Skip to content

Commit

Permalink
fix: add unit tests to improve coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
attiyaIshaque committed Aug 27, 2024
1 parent 4a28019 commit 6fae198
Show file tree
Hide file tree
Showing 12 changed files with 447 additions and 50 deletions.
27 changes: 27 additions & 0 deletions src/common-ui/SocialAuthButtons/index.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { fireEvent, render } from '@testing-library/react';
import configureStore from 'redux-mock-store';

import { COMPLETE_STATE, PENDING_STATE } from '../../data/constants';
import { setCookie } from '../../data/cookies';
import { OnboardingComponentContext } from '../../data/storeHooks';

import SocialAuthProviders, { SocialAuthButton } from './index';
Expand All @@ -18,6 +19,9 @@ jest.mock('@edx/frontend-platform', () => ({
}));

const mockStore = configureStore();
jest.mock('../../data/cookies', () => ({
setCookie: jest.fn(),
}));

describe('SocialAuthButton', () => {
let store = {};
Expand Down Expand Up @@ -84,6 +88,29 @@ describe('SocialAuthButton', () => {

expect(window.location.href).toEqual('http://example.com/login/google');
});

it('sets marketingEmailsOptIn cookie when isLoginForm is false', () => {
store = mockStore({
register: {
registrationFields: {
marketingEmailsOptIn: true,
},
},
});

const { getByText } = render(reduxWrapper(
<IntlSocialAuthButton provider={provider} isLoginForm={false} />,
));

delete window.location;
window.location = { href: 'http://base-url.com' };

const button = getByText('Sign up with Google');
fireEvent.click(button);

expect(setCookie).toHaveBeenCalledWith('marketingEmailsOptIn', true);
expect(window.location.href).toEqual('http://example.com/register/google');
});
});

describe('SocialAuthProviders', () => {
Expand Down
14 changes: 13 additions & 1 deletion src/data/tests/cookies.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { getConfig } from '@edx/frontend-platform';
import Cookies from 'universal-cookie';

import { setCookie } from '../cookies';
import { getCookie, setCookie } from '../cookies';

// Mock getConfig function
jest.mock('@edx/frontend-platform', () => ({
Expand Down Expand Up @@ -50,3 +50,15 @@ describe('setCookie function', () => {
expect(Cookies).not.toHaveBeenCalled();
});
});

describe('getCookie function', () => {
beforeEach(() => {
jest.clearAllMocks();
});

it('should return null if cookieName is undefined', () => {
const result = getCookie(undefined);
expect(result).toBeNull();
expect(Cookies).not.toHaveBeenCalled();
});
});
24 changes: 23 additions & 1 deletion src/data/tests/utils.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { getConfig, mergeConfig } from '@edx/frontend-platform';
import Cookies from 'universal-cookie';

import { getCountryCookieValue } from '../cookies';
import getAllPossibleQueryParams from '../utils';
import getAllPossibleQueryParams, { moveScrollToTop } from '../utils';

describe('getAllPossibleQueryParams', () => {
beforeEach(() => {
Expand Down Expand Up @@ -50,3 +50,25 @@ describe('getCountryCookieValue', () => {
expect(countryCode).toEqual(undefined);
});
});
describe('moveScrollToTop', () => {
it('should call scrollIntoView on the provided ref', () => {
const scrollIntoViewMock = jest.fn();
const ref = {
current: {
scrollIntoView: scrollIntoViewMock,
},
};

moveScrollToTop(ref, 'end');

expect(scrollIntoViewMock).toHaveBeenCalledWith({ behavior: 'smooth', block: 'end' });
});

it('should not throw an error if ref.current is undefined', () => {
const ref = {
current: null,
};

expect(() => moveScrollToTop(ref, 'end')).not.toThrow();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { MemoryRouter } from 'react-router-dom';
import configureStore from 'redux-mock-store';

import { PROGRESSIVE_PROFILING_FORM } from '../../../data/constants';
import { LINK_TIMEOUT } from '../../../data/segment/utils';
import { OnboardingComponentContext } from '../../../data/storeHooks';
import { setCurrentOpenedForm } from '../../../onboarding-component/data/reducers';
import AuthenticatedRedirection from '../AuthenticatedRedirection';
Expand Down Expand Up @@ -48,10 +49,12 @@ describe('AuthenticatedRedirection', () => {
store = mockStore(initialState);
delete window.location;
window.location = { href: '' };
jest.useFakeTimers();
});

afterEach(() => {
jest.clearAllMocks();
jest.useRealTimers();
});

it('should not redirect if success is false', () => {
Expand Down Expand Up @@ -103,4 +106,21 @@ describe('AuthenticatedRedirection', () => {

expect(store.dispatch).toHaveBeenCalledWith(setCurrentOpenedForm(PROGRESSIVE_PROFILING_FORM));
});

it('should redirect after a delay if isLinkTracked is true', () => {
render(reduxWrapper(
<IntlAuthenticatedRedirection
finishAuthUrl={null}
redirectUrl={mockRedirectUrl}
success={mockSuccess}
isLinkTracked
/>,
));

expect(window.location.href).toBe(''); // Shouldn't redirect immediately

jest.advanceTimersByTime(LINK_TIMEOUT); // Fast-forward time by LINK_TIMEOUT

expect(window.location.href).toBe(mockRedirectUrl); // Should have redirected after timeout
});
});
69 changes: 69 additions & 0 deletions src/forms/enterprise-sso-popup/data/utils.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import QueryString from 'query-string';

import { getTpaHint, getTpaProvider } from './utils';

// Mocking the query-string library
jest.mock('query-string');

describe('Utility Functions', () => {
describe('getTpaProvider', () => {
it('should return the provider from primaryProviders', () => {
const tpaHintProvider = 'google-oauth2';
const primaryProviders = [{ id: 'google-oauth2' }, { id: 'facebook' }];
const secondaryProviders = [{ id: 'twitter' }];

const result = getTpaProvider(tpaHintProvider, primaryProviders, secondaryProviders);
expect(result.provider).toEqual({ id: 'google-oauth2' });
});

it('should return the provider from secondaryProviders', () => {
const tpaHintProvider = 'twitter';
const primaryProviders = [{ id: 'google-oauth2' }, { id: 'facebook' }];
const secondaryProviders = [{ id: 'twitter' }];

const result = getTpaProvider(tpaHintProvider, primaryProviders, secondaryProviders);
expect(result.provider).toEqual({ id: 'twitter' });
});

it('should return null if provider is not found', () => {
const tpaHintProvider = 'linkedin';
const primaryProviders = [{ id: 'google-oauth2' }, { id: 'facebook' }];
const secondaryProviders = [{ id: 'twitter' }];

const result = getTpaProvider(tpaHintProvider, primaryProviders, secondaryProviders);
expect(result.provider).toBeNull();
});

it('should return null if tpaHintProvider is not provided', () => {
const tpaHintProvider = null;
const primaryProviders = [{ id: 'google-oauth2' }, { id: 'facebook' }];
const secondaryProviders = [{ id: 'twitter' }];

const result = getTpaProvider(tpaHintProvider, primaryProviders, secondaryProviders);
expect(result.provider).toBeNull();
});
});

describe('getTpaHint', () => {
it('should return tpa_hint from the query string', () => {
QueryString.parse.mockReturnValue({ tpa_hint: 'google-oauth2' });

const result = getTpaHint();
expect(result).toBe('google-oauth2');
});

it('should return tpa_hint from the "next" parameter in the query string', () => {
QueryString.parse.mockReturnValue({ next: 'some-path?tpa_hint=facebook' });

const result = getTpaHint();
expect(result).toBe('facebook');
});

it('should return undefined if tpa_hint is not found', () => {
QueryString.parse.mockReturnValue({ next: 'some-path' });

const result = getTpaHint();
expect(result).toBeUndefined();
});
});
});
11 changes: 11 additions & 0 deletions src/forms/enterprise-sso-popup/index.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,15 @@ describe('EnterpriseSSO', () => {

expect(store.dispatch).toHaveBeenCalledWith(setCurrentOpenedForm(LOGIN_FORM));
});

it('should prevent default behavior on mouse down for "Show me other ways to sign in or register" button', () => {
const { container } = render(reduxWrapper(<IntlEnterpriseSSO provider={provider} isLoginForm />));

const button = container.querySelector('#other-ways-to-sign-in');

const preventDefaultMock = jest.fn();
button.onmousedown = preventDefaultMock;
fireEvent.mouseDown(button);
expect(preventDefaultMock).toHaveBeenCalledTimes(1);
});
});
16 changes: 12 additions & 4 deletions src/forms/login-popup/components/AccountActivationMessage.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,14 @@ import React from 'react';

import { mergeConfig } from '@edx/frontend-platform';
import { injectIntl, IntlProvider } from '@edx/frontend-platform/i18n';
import {
render, screen,
} from '@testing-library/react';
import { render, screen } from '@testing-library/react';

import AccountActivationMessage from './AccountActivationMessage';
import { ACCOUNT_ACTIVATION_MESSAGE } from '../data/constants';

const IntlAccountActivationMessage = injectIntl(AccountActivationMessage);

describe('EmailConfirmationMessage', () => {
describe('AccountActivationMessage', () => {
beforeEach(() => {
mergeConfig({
MARKETING_EMAILS_OPT_IN: 'true',
Expand Down Expand Up @@ -64,4 +62,14 @@ describe('EmailConfirmationMessage', () => {
{ selector: '#account-activation-message' },
).textContent).toBe(expectedMessage);
});

it('should render nothing for unknown messageType', () => {
render(
<IntlProvider locale="en">
<IntlAccountActivationMessage messageType="UNKNOWN_TYPE" />
</IntlProvider>,
);
// Expect nothing to be rendered
expect(screen.queryByText('', { selector: '#account-activation-message' })).toBeNull();
});
});
56 changes: 54 additions & 2 deletions src/forms/login-popup/data/tests/reducer.test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
import {
COMPLETE_STATE, FAILURE_STATE, PENDING_STATE,
COMPLETE_STATE,
DEFAULT_STATE,
FAILURE_STATE,
PENDING_STATE,
} from '../../../../data/constants';
import loginReducer, {
loginInitialState, loginUser, loginUserFailed, loginUserSuccess,
backupLoginForm,
loginErrorClear,
loginInitialState,
loginUser,
loginUserFailed,
loginUserSuccess,
setLoginSSOIntent,
setShowPasswordResetBanner,
} from '../reducers';

describe('loginSlice reducer', () => {
Expand Down Expand Up @@ -47,4 +57,46 @@ describe('loginSlice reducer', () => {
});
expect(nextState.loginResult).toEqual({});
});

it('should handle setShowPasswordResetBanner action', () => {
const nextState = loginReducer(loginInitialState, setShowPasswordResetBanner());

expect(nextState.showResetPasswordSuccessBanner).toEqual(true);
});

it('should handle loginErrorClear action', () => {
const stateWithErrors = {
...loginInitialState,
loginError: { errorCode: 'SOME_ERROR_CODE', errorContext: {} },
submitState: FAILURE_STATE,
};

const nextState = loginReducer(stateWithErrors, loginErrorClear());

expect(nextState.loginError).toEqual({});
expect(nextState.submitState).toEqual(DEFAULT_STATE);
});

it('should handle setLoginSSOIntent action', () => {
const nextState = loginReducer(loginInitialState, setLoginSSOIntent());

expect(nextState.isLoginSSOIntent).toEqual(true);
});

it('should handle backupLoginForm action', () => {
const mockPayload = {
formFields: {
emailOrUsername: '[email protected]',
password: 'password123',
},
errors: {
emailOrUsername: '',
password: '',
},
};

const nextState = loginReducer(loginInitialState, backupLoginForm(mockPayload));

expect(nextState.loginFormData).toEqual(mockPayload);
});
});
Loading

0 comments on commit 6fae198

Please sign in to comment.