-
Notifications
You must be signed in to change notification settings - Fork 30
14890 show or hide the sign up newsletter component #14929
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
14890 show or hide the sign up newsletter component #14929
Conversation
|
Hello 👋! When you're ready to run Chromatic, please apply the You will need to reapply the label each time you want to run Chromatic. |
…nto 14890-show-or-hide-the-sign-up-newsletter-component
…nto 14890-show-or-hide-the-sign-up-newsletter-component
…nto 14890-show-or-hide-the-sign-up-newsletter-component
| }: EmailSignUpWrapperProps) => { | ||
| const [idApiUrl] = useState(() => { | ||
| if (typeof window === 'undefined') return ''; | ||
| return window.guardian?.config?.page?.idApiUrl ?? ''; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might it be better to return undefined rather than an empty string here and then make the type string | undefined?
…nto 14890-show-or-hide-the-sign-up-newsletter-component
…ttps://github.com/guardian/dotcom-rendering into 14890-show-or-hide-the-sign-up-newsletter-component
…te the type comparision
| if (isSubscribed === true) { | ||
| return null; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this mean we initially render the the newsletter component and then remove it if we determine there is a subscription?
I assume we have considered this approach will cause the least layout shift vs not showing and then inserting.
There is also the possibility of showing a newsletter related placeholder and replacing with the aim of zero layout shift.
|
|
||
| setIsSubscribed(isUserSubscribed); | ||
| } catch (error) { | ||
| console.error('Error fetching newsletters:', error); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rather than console.error, we have a Sentry reportError function on the window which will allow you to report errors to Sentry. Here's an example e.g.:
dotcom-rendering/dotcom-rendering/src/components/StickyBottomBanner/ReaderRevenueBanner.tsx
Lines 98 to 101 in 9038dfd
| window.guardian.modules.sentry.reportError( | |
| new Error(errorMessage), | |
| 'rr-banner', | |
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I should have said earlier, any access of window should be inside a useEffect because:
a) that is the right place for side-effects h/t @JamieB-gu
b) so there is no risk of the component being used in a server render and causing an exception in the main render path
…nto 14890-show-or-hide-the-sign-up-newsletter-component
Good question! I tried mocking useAuthStatus directly, but Storybook doesn’t support jest.mock() since it runs in a real browser. The hook reads the actual auth state from the browser, so we can’t override it that way. Using Webpack’s resolve.alias is the recommended approach — it lets us cleanly swap the identity module and control the auth state per story. |
JamieB-gu
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! 👍 for the tests and JSDocs.
A few questions and comments, one related to @georgerichmond 's point above.
dotcom-rendering/src/components/EmailSignUpWrapper.importable.tsx
Outdated
Show resolved
Hide resolved
dotcom-rendering/src/components/EmailSignUpWrapper.importable.tsx
Outdated
Show resolved
Hide resolved
| } | ||
| } | ||
|
|
||
| const mockAccessToken = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Note, this is a reply to George's comment above, but the GH review UI might not show this clearly).
Doesn't the useAuthStatus hook also return this data via the SignedIn type though? I can also see that the SecureSignup component relies on a few different functions/hooks to retrieve information about the signed in status and email address, such as lazyFetchEmailWithTimeout and useIsSignedIn, which in turn rely on this?
An alternative might be to use storybook's built-in mocking1 for the modules in question? Given that you've already got tests for useNewsletterSubscription we probably don't need to re-test the underlying implementation in storybook, as we just want to test the resulting component behaviour. Therefore we could add the following to storybook's preview.ts to set up mocking for the relevant modules:
sb.mock(import('../src/lib/useNewsletterSubscription.ts'), { spy: true });
sb.mock(import('../src/lib/fetchEmail.ts'), { spy: true });
sb.mock(import('../src/lib/useAuthStatus.ts'), { spy: true });Then we can use beforeEach in storybook2 to mock the specific functionality we care about. So, for each story:
LoadingState:
async beforeEach() {
mocked(useNewsletterSubscription).mockReturnValue(undefined);
},DefaultStory/DefaultStoryWithPrivacy:
async beforeEach() {
mocked(useNewsletterSubscription).mockReturnValue(false);
},SignedInNotSubscribed:
async beforeEach() {
mocked(useNewsletterSubscription).mockReturnValue(false);
mocked(lazyFetchEmailWithTimeout).mockReturnValue(() => Promise.resolve("mock email"));
mocked(useIsSignedIn).mockReturnValue(true);
},SignedInAlreadySubscribed:
async beforeEach() {
mocked(useNewsletterSubscription).mockReturnValue(true);
},I think this would allow you to avoid writing custom mocks for the identity module, and the auth decorators too. However, I doubt we have other examples of this in the codebase, as I believe it's a relatively recent feature (Storybook 9), so I'd be happy to discuss if helpful.
Footnotes
…nto 14890-show-or-hide-the-sign-up-newsletter-component
…ttps://github.com/guardian/dotcom-rendering into 14890-show-or-hide-the-sign-up-newsletter-component
|
Looking much better, simpler just to mock the hook 👍 |
JamieB-gu
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, thanks for making those changes, one question.
| frequency: element.newsletter.frequency, | ||
| successDescription: element.newsletter.successDescription, | ||
| theme: element.newsletter.theme, | ||
| idApiUrl: idApiUrl ?? '', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How will the component handle this when it's an empty string?
…nto 14890-show-or-hide-the-sign-up-newsletter-component
…nto 14890-show-or-hide-the-sign-up-newsletter-component
…nto 14890-show-or-hide-the-sign-up-newsletter-component
…nto 14890-show-or-hide-the-sign-up-newsletter-component
…nto 14890-show-or-hide-the-sign-up-newsletter-component
|
Seen on PROD (merged by @Marianaguardian 7 minutes and 56 seconds ago) Please check your changes! |
What does this change?
Investigate hiding the sign up component
Why?
There is an ambition to hide the sign up component that appears in articles when a user has already signed up to the newsletter in question. This would be a nice "quality of life" update that should make the sign up embeds less intrusive.
Ticket link: #14889
Subtask ticket link : #14890
Screenshots