Skip to content

Commit

Permalink
Increase code coverage 6 (#2659)
Browse files Browse the repository at this point in the history
* Layouts

* Flex-page

* Details page, part 1

* details/links-to-translations

* details/resource-box

* details/common (get-this-title)

* details/get-this-title (give-before-*)

* models

* explore-by-subject

* Code review items
  • Loading branch information
RoyEJohnson authored Aug 13, 2024
1 parent 681bfd4 commit edcb242
Show file tree
Hide file tree
Showing 30 changed files with 1,407 additions and 273 deletions.
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,7 @@ To build the site for development and load it in your default web browser with [
script/dev
```

That will create a new `dev` directory from which the site is served. Changes should be made to files in the `src` directory. Gulp will automatically watch for changes in `src`, perform any compilation and transpilation necessary, and update the result in `dev`.

You can also run individual tasks. Enter `$(npm bin)/gulp --tasks` to see the full list.
That will create a new `dev` directory from which the site is served. Changes should be made to files in the `src` directory. Webpack will automatically watch for changes in `src`, perform any compilation and transpilation necessary, and update the result in `dev`.

## Testing

Expand All @@ -56,7 +54,11 @@ script/build
script/test
```

You can also just run the linters (`$(npm bin)/gulp lint`) individually without rebuilding.
You can also just run the linters (`yarn lint`) individually without rebuilding.
You can run individual tests by name (`yarn jest layout.test`).

Check code coverage by loading into your browser `/coverage/index.html` from the
root of the git repository.

**Note:** The unit tests require the dev build to be built (in the `dev` directory).

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default function ContentWarning({
link: string;
track: string | undefined;
close: () => void;
onDownload: (event: React.MouseEvent) => void;
onDownload?: (event: React.MouseEvent) => void;
variant?: string;
warning: string;
id: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default function GiveBeforePdf({
track?: string;
close: () => void;
data: DonationPopupData;
onDownload: () => void;
onDownload?: () => void;
id?: string;
}) {
const [doneDownloading, setDoneDownloading] = React.useState(false);
Expand Down Expand Up @@ -65,7 +65,7 @@ function GiveBeforePdfAfterConditionals({
track: string | undefined;
data: DonationPopupData;
close: () => void;
onDownload: (event: React.MouseEvent) => void;
onDownload?: (event: React.MouseEvent) => void;
}) {
const [controlLink, alternateLink] = useGiveLinks();
const variants = [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
import React from 'react';
import {useDataFromSlug} from '~/helpers/page-data-utils';

export type DonationPopupData = {
download_image: string;
download_ready?: string;
header_image: string;
header_title: string;
header_subtitle: string;
give_link_text: string;
give_link: string;
thank_you_link_text: string;
thank_you_link: string;
giving_optional: string;
go_to_pdf_link_text: string;
hide_donation_popup: boolean;
};

export default function useDonationPopupData() {
// When useDataFromSlug moves to TS, we can make it type-generic
const data1 = useDataFromSlug('donations/donation-popup');
const data = React.useMemo(
() => (data1?.length > 0 ? data1[0] : {}),
[data1]
);

return data;
return data as DonationPopupData;
}

export type DonationPopupData = ReturnType<typeof useDonationPopupData>;
51 changes: 0 additions & 51 deletions src/app/pages/details/common/get-this-title.js

This file was deleted.

71 changes: 71 additions & 0 deletions src/app/pages/details/common/get-this-title.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import React from 'react';
import {useToggle} from '~/helpers/data';
import {
TocOption,
WebviewOption,
PdfOption,
BookshareOption,
IbooksOption,
KindleOption,
CheggOption,
OptionExpander
} from './get-this-title-files/options';
import OrderPrintCopy from './get-this-title-files/order-print-copy/order-print-copy';
import './get-this-title-files/get-this-title.scss';
import trackLink from './track-link';

type Model = {
id: string;
slug: string;
bookshareLink: string;
ibookLink: string;
kindleLink: string;
};
type ModelKey = 'bookshareLink' | 'ibookLink' | 'kindleLink';
type TrackedMouseEvent = Parameters<typeof trackLink>[0];

function AdditionalOptions({model}: {model: Model}) {
return (
<React.Fragment>
<BookshareOption model={model} />
<IbooksOption model={model} />
<KindleOption model={model} />
</React.Fragment>
);
}

export default function GetThisTitle({model}: {model: Model}) {
const additionalOptions = (
['bookshareLink', 'ibookLink', 'kindleLink'] as ModelKey[]
).filter((key) => model[key]).length;
const [expanded, toggleExpanded] = useToggle(additionalOptions < 1);
const interceptLinkClicks = React.useCallback<React.MouseEventHandler>(
(event: TrackedMouseEvent) => {
trackLink(event, model.id);
},
[model.id]
);

return (
<div className="get-the-book">
<div className="get-this-title">
<div
className="options"
onClick={interceptLinkClicks}
data-analytics-nav="Get the book"
>
<TocOption model={model} />
<WebviewOption model={model} />
<PdfOption model={model} />
<CheggOption model={model} />
{expanded && <AdditionalOptions model={model} />}
<OptionExpander
{...{expanded, additionalOptions}}
toggle={toggleExpanded}
/>
</div>
</div>
<OrderPrintCopy slug={model.slug} />
</div>
);
}
6 changes: 1 addition & 5 deletions src/app/pages/details/common/links-to-translations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,10 @@ function AnotherLanguage({
[translations, locale]
);

if (!translation) {
return null;
}

// translation is guaranteed to have a valid value, because the locale
// is pulled from translations
return (
<a href={`/details/books/${translation.slug}`}>
<a href={`/details/books/${translation?.slug}`}>
<LanguageText locale={locale} />
</a>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,11 @@ function CommonsHubBox() {
);
}

export default function ResourceBoxes({ models, includeCommonsHub = false }) {
export default function ResourceBoxes({ models, includeCommonsHub = false }: {
models: {heading: string;
}[]; // Will be a real type when other stuff becomes TS
includeCommonsHub?: boolean;
}) {
return (
<React.Fragment>
{includeCommonsHub && <CommonsHubBox />}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ type BoxModel = { heading: string };

type VideoResourceBoxesArgs = {
models: VideoResourceBoxModelType[];
blogLinkModels: BoxModel[];
referenceModels: BoxModel[];
blogLinkModels?: BoxModel[];
referenceModels?: BoxModel[];
};

export default function VideoResourceBoxes({
Expand All @@ -37,7 +37,7 @@ export default function VideoResourceBoxes({
{blogLinkModels?.map((model) => (
<ResourceBox model={model} key={model.heading} />
))}
{referenceModels.map((model) => (
{referenceModels?.map((model) => (
<ResourceBox model={model} key={model.heading} />
))}
</React.Fragment>
Expand Down
2 changes: 1 addition & 1 deletion src/app/pages/details/dual-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export default function DualView() {
}

function useViewsUsed() {
const {innerWidth} = useWindowContext() as typeof window;
const {innerWidth} = useWindowContext();
const [phone, setPhone] = React.useState<boolean>(false);
const [desktop, setDesktop] = React.useState<boolean>(false);

Expand Down
10 changes: 6 additions & 4 deletions src/app/pages/details/title-image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import cn from 'classnames';

export default function TitleImage() {
const {reverseGradient, title, titleImageUrl} = useDetailsContext();
const titleLogo = ''; // For future use
// const titleLogo = ''; // For future use

if (!title || !titleImageUrl) {
return null;
Expand All @@ -21,9 +21,11 @@ export default function TitleImage() {
height='130'
width='392'
/>
{titleLogo && (
<img className='title-logo' src={titleLogo} alt='' />
)}
{/*
titleLogo && (
<img className='title-logo' src={titleLogo} alt='' />
)
*/}
</h1>
</div>
</div>
Expand Down
7 changes: 5 additions & 2 deletions src/app/pages/flex-page/flex-page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import React from 'react';
import { LoadedPage } from '~/components/jsx-helpers/loader-page';
import { Data } from '~/helpers/use-page-data';
import { ContentBlocks, ContentBlockConfig } from './blocks/ContentBlock';

type Data = {
body: ContentBlockConfig[];
}

function FlexPageBody({data}: {data: Data}) {
return <ContentBlocks data={data.body as ContentBlockConfig[]} />;
return <ContentBlocks data={data.body} />;
}

export default function FlexPage({data}: {data: Data}) {
Expand Down
3 changes: 2 additions & 1 deletion test/src/data/subject-categories.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ export default [
"id": 1,
"name": "Math",
"seo_title": "Math SEO Title",
"search_description": "This is math search meta"
"search_description": "This is math search meta",
"subject_icon": "/images/subject-icon"
},
{
"id": 2,
Expand Down
47 changes: 47 additions & 0 deletions test/src/layouts.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from 'react';
import {render, screen} from '@testing-library/preact';
import {describe, it} from '@jest/globals';
import { MemoryRouter } from 'react-router-dom';
import LandingLayout from '~/layouts/landing/landing';

describe('layouts/landing', () => {
const data: Parameters<typeof LandingLayout>[0]['data'] = {
title: 'the-title',
layout: []
};

it('renders without layout values', () => {
render(
<MemoryRouter initialEntries={['']}>
<LandingLayout data={data}>
<div>child contents</div>
</LandingLayout>
</MemoryRouter>
);
expect(screen.getAllByRole('img')).toHaveLength(2);
expect(screen.getAllByRole('link')).toHaveLength(3);
});
it('renders with layout values', () => {
data.layout.push({
value: {
navLinks: [
{
text: 'link-name',
target: {
type: 'link-type',
value: 'link-value'
}
}
]
}
});
render(
<MemoryRouter initialEntries={['']}>
<LandingLayout data={data}>
<div>child contents</div>
</LandingLayout>
</MemoryRouter>
);
expect(screen.getAllByRole('link')).toHaveLength(4);
});
});
Loading

0 comments on commit edcb242

Please sign in to comment.