Skip to content

Commit d5cd1f1

Browse files
authored
Merge branch 'main' into use-user-benefits-abtest
2 parents 31f9b65 + 0764a1b commit d5cd1f1

9 files changed

+522
-262
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import type { SerializedStyles } from '@emotion/react';
2+
import { css } from '@emotion/react';
3+
import { remSpace, textSans14 } from '@guardian/source/foundations';
4+
import type { Meta, StoryObj } from '@storybook/react';
5+
import { within } from '@storybook/test';
6+
import { createRoot } from 'react-dom/client';
7+
import {
8+
centreColumnDecorator,
9+
rightColumnDecorator,
10+
} from '../../.storybook/decorators/gridDecorators';
11+
import { ArticleDisplay } from '../lib/articleFormat';
12+
import { AdSlot } from './AdSlot.web';
13+
14+
const meta = {
15+
component: AdSlot,
16+
title: 'Components/Ad Slot (web)',
17+
} satisfies Meta<typeof AdSlot>;
18+
19+
export default meta;
20+
21+
type Story = StoryObj<typeof meta>;
22+
23+
const adLabelsStyles = css`
24+
${textSans14}
25+
padding: ${remSpace[3]};
26+
display: flex;
27+
justify-content: center;
28+
width: 100%;
29+
p {
30+
margin: 0;
31+
font-size: 16px;
32+
font-weight: 400;
33+
}
34+
`;
35+
36+
const squareAdStyles = css`
37+
padding-bottom: 250px;
38+
width: 300px;
39+
`;
40+
41+
const bannerAdStyles = css`
42+
padding-bottom: 250px;
43+
width: 100%;
44+
`;
45+
46+
function renderTestAd(
47+
adStyles: SerializedStyles,
48+
slotId = 'slot',
49+
): Story['play'] {
50+
return async ({ canvasElement }) => {
51+
const canvas = within(canvasElement);
52+
const slot = await canvas.findByTestId(slotId);
53+
const root = createRoot(slot);
54+
55+
root.render(
56+
<aside>
57+
<div css={adLabelsStyles}>
58+
<p>Advertisement</p>
59+
</div>
60+
<div css={adStyles}></div>
61+
</aside>,
62+
);
63+
};
64+
}
65+
66+
export const Right = {
67+
args: {
68+
position: 'right',
69+
display: ArticleDisplay.Standard,
70+
},
71+
decorators: [rightColumnDecorator],
72+
play: renderTestAd(squareAdStyles),
73+
} satisfies Story;
74+
75+
export const TopAboveNav = {
76+
args: {
77+
position: 'top-above-nav',
78+
},
79+
play: renderTestAd(bannerAdStyles),
80+
} satisfies Story;
81+
82+
export const FrontsBanner = {
83+
args: {
84+
position: 'fronts-banner',
85+
index: 1,
86+
},
87+
play: renderTestAd(bannerAdStyles),
88+
} satisfies Story;
89+
90+
export const LiveblogInline = {
91+
args: {
92+
position: 'liveblog-inline',
93+
index: 0,
94+
},
95+
decorators: [centreColumnDecorator],
96+
play: renderTestAd(bannerAdStyles, 'liveblog-inline--inline1'),
97+
} satisfies Story;
98+
99+
export const Merchandising = {
100+
args: {
101+
position: 'merchandising',
102+
},
103+
decorators: [centreColumnDecorator],
104+
play: renderTestAd(bannerAdStyles),
105+
} satisfies Story;

dotcom-rendering/src/components/AdSlot.web.tsx

+14
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,7 @@ export const AdSlot = ({
397397
].join(' ')}
398398
data-link-name="ad slot right"
399399
data-name="right"
400+
data-testid="slot"
400401
aria-hidden="true"
401402
/>
402403
</div>
@@ -422,6 +423,7 @@ export const AdSlot = ({
422423
].join(' ')}
423424
data-link-name="ad slot right"
424425
data-name="right"
426+
data-testid="slot"
425427
aria-hidden="true"
426428
/>
427429
</div>
@@ -480,6 +482,7 @@ export const AdSlot = ({
480482
]}
481483
data-link-name="ad slot right"
482484
data-name="right"
485+
data-testid="slot"
483486
aria-hidden="true"
484487
/>
485488
</div>
@@ -504,6 +507,7 @@ export const AdSlot = ({
504507
].join(' ')}
505508
data-link-name="ad slot comments"
506509
data-name="comments"
510+
data-testid="slot"
507511
aria-hidden="true"
508512
/>
509513
</div>
@@ -526,6 +530,7 @@ export const AdSlot = ({
526530
].join(' ')}
527531
data-link-name="ad slot top-above-nav"
528532
data-name="top-above-nav"
533+
data-testid="slot"
529534
aria-hidden="true"
530535
></div>
531536
</div>
@@ -550,6 +555,7 @@ export const AdSlot = ({
550555
css={[mostPopAdStyles]}
551556
data-link-name="ad slot mostpop"
552557
data-name="mostpop"
558+
data-testid="slot"
553559
aria-hidden="true"
554560
/>
555561
</div>
@@ -573,6 +579,7 @@ export const AdSlot = ({
573579
data-link-name="ad slot merchandising-high"
574580
data-name="merchandising-high"
575581
data-refresh="false"
582+
data-testid="slot"
576583
aria-hidden="true"
577584
/>
578585
</div>
@@ -594,6 +601,7 @@ export const AdSlot = ({
594601
css={[merchandisingAdStyles]}
595602
data-link-name="ad slot merchandising"
596603
data-name="merchandising"
604+
data-testid="slot"
597605
aria-hidden="true"
598606
/>
599607
</div>
@@ -625,6 +633,7 @@ export const AdSlot = ({
625633
css={[frontsBannerAdStyles]}
626634
data-link-name={`ad slot ${advertId}`}
627635
data-name={`${advertId}`}
636+
data-testid="slot"
628637
aria-hidden="true"
629638
/>
630639
</div>
@@ -646,6 +655,7 @@ export const AdSlot = ({
646655
data-label="false"
647656
data-refresh="false"
648657
data-out-of-page="true"
658+
data-testid="slot"
649659
aria-hidden="true"
650660
/>
651661
);
@@ -717,6 +727,7 @@ export const AdSlot = ({
717727
css={[liveBlogTopAdStyles]}
718728
data-link-name="ad slot liveblog-top"
719729
data-name="liveblog-top"
730+
data-testid="slot"
720731
aria-hidden="true"
721732
/>
722733
</div>
@@ -740,6 +751,7 @@ export const AdSlot = ({
740751
css={[mobileFrontAdStyles]}
741752
data-link-name={`ad slot ${advertId}`}
742753
data-name={advertId}
754+
data-testid="slot"
743755
aria-hidden="true"
744756
/>
745757
</div>
@@ -763,6 +775,7 @@ export const AdSlot = ({
763775
data-refresh="false"
764776
data-out-of-page="true"
765777
data-wide="1,1"
778+
data-testid="slot"
766779
aria-hidden="true"
767780
/>
768781
</div>
@@ -782,6 +795,7 @@ export const AdSlot = ({
782795
css={[articleEndAdStyles]}
783796
data-link-name="ad slot article-end"
784797
data-name="article-end"
798+
data-testid="slot"
785799
aria-hidden="true"
786800
/>
787801
</div>

dotcom-rendering/src/components/FlexibleGeneral.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,7 @@ export const FlexibleGeneral = ({
449449
aspectRatio,
450450
}: Props) => {
451451
const splash = [...groupedTrails.splash].slice(0, 1);
452-
const cards = [...groupedTrails.standard].slice(0, 8);
452+
const cards = [...groupedTrails.standard].slice(0, 19);
453453
const groupedCards = decideCardPositions(cards);
454454

455455
return (
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,78 @@
11
import { render } from '@testing-library/react';
2-
import { FrontsBannerAdSlot, MerchHighOrMobileAdSlot } from './FrontsAdSlots';
2+
import {
3+
FrontsBannerAdSlot,
4+
MerchHighAdSlot,
5+
MobileAdSlot,
6+
} from './FrontsAdSlots';
37

4-
describe('MerchHighOrMobileAdSlot', () => {
8+
describe('MobileAdSlot', () => {
59
it("should return null if we shouldn't render ads", () => {
610
const { container } = render(
7-
<MerchHighOrMobileAdSlot
11+
<MobileAdSlot renderAds={false} adSlotIndex={4} />,
12+
);
13+
14+
expect(container.innerHTML).toBe('');
15+
});
16+
17+
it('should render ad slot if renderAds is true', () => {
18+
const { container } = render(
19+
<MobileAdSlot renderAds={true} adSlotIndex={4} />,
20+
);
21+
22+
expect(container.innerHTML).not.toBe('');
23+
expect(container.innerHTML).toMatch('ad slot inline');
24+
});
25+
});
26+
27+
describe('MerchHighAdSlot', () => {
28+
it("should return null if we shouldn't render ads", () => {
29+
const { container } = render(
30+
<MerchHighAdSlot
831
renderAds={false}
9-
index={4}
10-
collectionCount={10}
1132
isPaidContent={false}
12-
mobileAdPositions={[]}
13-
hasPageSkin={false}
33+
collectionCount={4}
34+
/>,
35+
);
36+
37+
expect(container.innerHTML).toBe('');
38+
});
39+
40+
it('should return null if front has 2 or fewer containers', () => {
41+
const { container } = render(
42+
<MerchHighAdSlot
43+
renderAds={true}
44+
isPaidContent={false}
45+
collectionCount={2}
1446
/>,
1547
);
1648

1749
expect(container.innerHTML).toBe('');
1850
});
51+
52+
it('should return null if it is paid content and front has 1 or fewer containers', () => {
53+
const { container } = render(
54+
<MerchHighAdSlot
55+
renderAds={true}
56+
isPaidContent={true}
57+
collectionCount={1}
58+
/>,
59+
);
60+
61+
expect(container.innerHTML).toBe('');
62+
});
63+
64+
it('should render the merch high slot if more than 2 containers', () => {
65+
const { container } = render(
66+
<MerchHighAdSlot
67+
renderAds={true}
68+
isPaidContent={false}
69+
collectionCount={4}
70+
/>,
71+
);
72+
73+
expect(container.innerHTML).not.toBe('');
74+
expect(container.innerHTML).toMatch('ad slot merchandising-high');
75+
});
1976
});
2077

2178
describe('FrontsBannerAdSlot', () => {
@@ -24,8 +81,7 @@ describe('FrontsBannerAdSlot', () => {
2481
<FrontsBannerAdSlot
2582
renderAds={false}
2683
hasPageSkin={false}
27-
index={2}
28-
desktopAdPositions={[2, 5]}
84+
adSlotIndex={2}
2985
/>,
3086
);
3187

@@ -37,52 +93,23 @@ describe('FrontsBannerAdSlot', () => {
3793
<FrontsBannerAdSlot
3894
renderAds={true}
3995
hasPageSkin={true}
40-
index={2}
41-
desktopAdPositions={[2, 5]}
96+
adSlotIndex={2}
4297
/>,
4398
);
4499

45100
expect(container.innerHTML).toBe('');
46101
});
47102

48-
test.each([
49-
[[2, 5], 3],
50-
[[2, 5], 0],
51-
[[], 1],
52-
])(
53-
'should return null if desktopAdPositions %p does NOT contain index %i',
54-
(adPositions, i) => {
55-
const { container } = render(
56-
<FrontsBannerAdSlot
57-
renderAds={true}
58-
hasPageSkin={false}
59-
index={i}
60-
desktopAdPositions={adPositions}
61-
/>,
62-
);
63-
64-
expect(container.innerHTML).toBe('');
65-
},
66-
);
67-
68-
test.each([
69-
[[2, 5], 2],
70-
[[2, 5], 5],
71-
[[1], 1],
72-
])(
73-
'should NOT return null if desktopAdPositions %p contains index %i',
74-
(adPositions, i) => {
75-
const { container } = render(
76-
<FrontsBannerAdSlot
77-
renderAds={true}
78-
hasPageSkin={false}
79-
index={i}
80-
desktopAdPositions={adPositions}
81-
/>,
82-
);
83-
84-
expect(container.innerHTML).not.toBe('');
85-
expect(container.innerHTML).toMatch('ad-slot-container');
86-
},
87-
);
103+
it('should render ad slot if there is no page skin and renderAds is true', () => {
104+
const { container } = render(
105+
<FrontsBannerAdSlot
106+
renderAds={true}
107+
hasPageSkin={false}
108+
adSlotIndex={2}
109+
/>,
110+
);
111+
112+
expect(container.innerHTML).not.toBe('');
113+
expect(container.innerHTML).toMatch('ad slot fronts-banner');
114+
});
88115
});

0 commit comments

Comments
 (0)