Skip to content

Commit cf186a1

Browse files
arbrandesclaude
andcommitted
test: restore missing test coverage for items 6, 8, 9
Adds tests that were removed or simplified during the Redux-to-React-Query migration, as identified in PR #1641 review. Logistration: CSRF token on mount, institution login page events for both login and register pages, institution login track+page event assertions. LoginPage: reset password banner dismissal on form submit, SSO redirect to finishAuthUrl, and redirectUrl precedence over finishAuthUrl. ProgressiveProfiling: sendPageEvent('login_and_registration', 'welcome') assertion on component mount. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent e9137d5 commit cf186a1

3 files changed

Lines changed: 174 additions & 0 deletions

File tree

src/login/tests/LoginPage.test.jsx

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -689,4 +689,105 @@ describe('LoginPage', () => {
689689
expect(container.querySelector('.alert-danger, .alert, [role="alert"]')).toBeTruthy();
690690
});
691691
});
692+
693+
// ******** test reset password banner ********
694+
695+
it('should dismiss reset password banner on form submission', () => {
696+
const wrapper = (children) => (
697+
<QueryClientProvider client={queryClient}>
698+
<IntlProvider locale="en">
699+
<MemoryRouter initialEntries={[{ pathname: '/login', state: { showResetPasswordSuccessBanner: true } }]}>
700+
<CurrentAppProvider appId={appId}>
701+
<RegisterProvider>
702+
<LoginProvider>
703+
{children}
704+
</LoginProvider>
705+
</RegisterProvider>
706+
</CurrentAppProvider>
707+
</MemoryRouter>
708+
</IntlProvider>
709+
</QueryClientProvider>
710+
);
711+
712+
const { container } = render(wrapper(<LoginPage {...props} />));
713+
// Banner should be visible initially
714+
expect(container.querySelector('#reset-password-success')).toBeTruthy();
715+
716+
// Submit the form
717+
fireEvent.click(screen.getByRole('button', { name: /sign in/i }));
718+
719+
// Banner should be dismissed
720+
expect(container.querySelector('#reset-password-success')).toBeFalsy();
721+
});
722+
723+
// ******** test SSO redirect ********
724+
725+
it('should redirect to finish auth URL on SSO login success', () => {
726+
const finishAuthUrl = '/auth/complete/google-oauth2/';
727+
mockThirdPartyAuthContext.thirdPartyAuthContext = {
728+
...mockThirdPartyAuthContext.thirdPartyAuthContext,
729+
finishAuthUrl,
730+
};
731+
useThirdPartyAuthContext.mockReturnValue(mockThirdPartyAuthContext);
732+
733+
useLogin.mockImplementation((options) => ({
734+
mutate: jest.fn().mockImplementation((data) => {
735+
mockLoginMutate(data);
736+
if (options?.onSuccess) {
737+
options.onSuccess({ redirectUrl: '' });
738+
}
739+
}),
740+
isPending: false,
741+
}));
742+
743+
delete window.location;
744+
window.location = { href: getSiteConfig().baseUrl };
745+
746+
render(queryWrapper(<LoginPage {...props} />));
747+
748+
fireEvent.change(screen.getByLabelText(/username or email/i), {
749+
target: { value: 'test@example.com', name: 'emailOrUsername' },
750+
});
751+
fireEvent.change(screen.getByLabelText('Password'), {
752+
target: { value: 'password123', name: 'password' },
753+
});
754+
fireEvent.click(screen.getByRole('button', { name: /sign in/i }));
755+
756+
expect(window.location.href).toBe(getSiteConfig().lmsBaseUrl + finishAuthUrl);
757+
});
758+
759+
it('should use redirectUrl when it includes finishAuthUrl', () => {
760+
const finishAuthUrl = '/auth/complete/google-oauth2/';
761+
const redirectUrl = 'https://test.com/auth/complete/google-oauth2/?next=/dashboard';
762+
mockThirdPartyAuthContext.thirdPartyAuthContext = {
763+
...mockThirdPartyAuthContext.thirdPartyAuthContext,
764+
finishAuthUrl,
765+
};
766+
useThirdPartyAuthContext.mockReturnValue(mockThirdPartyAuthContext);
767+
768+
useLogin.mockImplementation((options) => ({
769+
mutate: jest.fn().mockImplementation((data) => {
770+
mockLoginMutate(data);
771+
if (options?.onSuccess) {
772+
options.onSuccess({ redirectUrl });
773+
}
774+
}),
775+
isPending: false,
776+
}));
777+
778+
delete window.location;
779+
window.location = { href: getSiteConfig().baseUrl };
780+
781+
render(queryWrapper(<LoginPage {...props} />));
782+
783+
fireEvent.change(screen.getByLabelText(/username or email/i), {
784+
target: { value: 'test@example.com', name: 'emailOrUsername' },
785+
});
786+
fireEvent.change(screen.getByLabelText('Password'), {
787+
target: { value: 'password123', name: 'password' },
788+
});
789+
fireEvent.click(screen.getByRole('button', { name: /sign in/i }));
790+
791+
expect(window.location.href).toBe(redirectUrl);
792+
});
692793
});

src/logistration/Logistration.test.jsx

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,4 +292,75 @@ describe('Logistration', () => {
292292
fireEvent.click(container.querySelector('a[data-rb-event-key="/login"]'));
293293
expect(mockClearThirdPartyAuthErrorMessage).toHaveBeenCalled();
294294
});
295+
296+
it('should call authService getCsrfTokenService on component mount', () => {
297+
render(renderWrapper(<Logistration selectedPage={LOGIN_PAGE} />));
298+
expect(mockGetCsrfToken).toHaveBeenCalledWith(getSiteConfig().lmsBaseUrl);
299+
});
300+
301+
it('should send correct page events for login and register when handling institution login', () => {
302+
mergeAppConfig(appId, {
303+
DISABLE_ENTERPRISE_LOGIN: 'true',
304+
ALLOW_PUBLIC_ACCOUNT_CREATION: 'true',
305+
});
306+
307+
const { useThirdPartyAuthContext } = require('../common-components/components/ThirdPartyAuthContext.tsx');
308+
useThirdPartyAuthContext.mockReturnValue({
309+
...mockDefaultThirdPartyAuthContextValue,
310+
thirdPartyAuthContext: {
311+
...mockDefaultThirdPartyAuthContextValue.thirdPartyAuthContext,
312+
secondaryProviders: [{
313+
id: 'saml-test',
314+
name: 'Test University',
315+
loginUrl: '/dummy-auth',
316+
registerUrl: '/dummy_auth',
317+
}],
318+
},
319+
});
320+
321+
// Login page
322+
render(renderWrapper(<Logistration selectedPage={LOGIN_PAGE} />));
323+
fireEvent.click(screen.getByText('Institution/campus credentials'));
324+
expect(sendPageEvent).toHaveBeenCalledWith('login_and_registration', 'institution_login');
325+
326+
// Register page
327+
sendPageEvent.mockClear();
328+
render(renderWrapper(<Logistration selectedPage={REGISTER_PAGE} />));
329+
fireEvent.click(screen.getByText('Institution/campus credentials'));
330+
expect(sendPageEvent).toHaveBeenCalledWith('login_and_registration', 'institution_login');
331+
332+
mergeAppConfig(appId, {
333+
DISABLE_ENTERPRISE_LOGIN: '',
334+
});
335+
});
336+
337+
it('should handle institution login with string parameters correctly', () => {
338+
mergeAppConfig(appId, {
339+
DISABLE_ENTERPRISE_LOGIN: 'true',
340+
});
341+
342+
const { useThirdPartyAuthContext } = require('../common-components/components/ThirdPartyAuthContext.tsx');
343+
useThirdPartyAuthContext.mockReturnValue({
344+
...mockDefaultThirdPartyAuthContextValue,
345+
thirdPartyAuthContext: {
346+
...mockDefaultThirdPartyAuthContextValue.thirdPartyAuthContext,
347+
secondaryProviders: [{
348+
id: 'saml-test',
349+
name: 'Test University',
350+
loginUrl: '/dummy-auth',
351+
registerUrl: '/dummy_auth',
352+
}],
353+
},
354+
});
355+
356+
render(renderWrapper(<Logistration selectedPage={LOGIN_PAGE} />));
357+
sendPageEvent.mockClear();
358+
fireEvent.click(screen.getByText('Institution/campus credentials'));
359+
expect(sendTrackEvent).toHaveBeenCalledWith('edx.bi.institution_login_form.toggled', { category: 'user-engagement' });
360+
expect(sendPageEvent).toHaveBeenCalledWith('login_and_registration', 'institution_login');
361+
362+
mergeAppConfig(appId, {
363+
DISABLE_ENTERPRISE_LOGIN: '',
364+
});
365+
});
295366
});

src/progressive-profiling/tests/ProgressiveProfiling.test.jsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
identifyAuthenticatedUser,
66
IntlProvider,
77
mergeAppConfig,
8+
sendPageEvent,
89
sendTrackEvent,
910
} from '@openedx/frontend-base';
1011
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
@@ -515,6 +516,7 @@ describe('ProgressiveProfilingTests', () => {
515516
it('should call analytics functions on component mount', () => {
516517
renderWithProviders(<ProgressiveProfiling />);
517518
expect(identifyAuthenticatedUser).toHaveBeenCalledWith(3);
519+
expect(sendPageEvent).toHaveBeenCalledWith('login_and_registration', 'welcome');
518520
});
519521
});
520522

0 commit comments

Comments
 (0)