diff --git a/src/login/data/sagas.js b/src/login/data/sagas.js index 35e943a3..a0b10e82 100644 --- a/src/login/data/sagas.js +++ b/src/login/data/sagas.js @@ -2,7 +2,7 @@ import { call, put, takeEvery } from 'redux-saga/effects'; import { camelCaseObject } from '@edx/frontend-platform'; import { logError } from '@edx/frontend-platform/logging'; -import { INTERNAL_SERVER_ERROR } from './constants'; +import { FORBIDDEN_REQUEST, INTERNAL_SERVER_ERROR } from './constants'; // Actions import { @@ -30,10 +30,13 @@ export function* handleLoginRequest(action) { } catch (e) { const statusCodes = [400]; if (e.response) { - if (statusCodes.includes(e.response.status)) { + const { status } = e.response; + if (statusCodes.includes(status)) { yield put(loginRequestFailure(camelCaseObject(e.response.data))); + } else if (status === 403) { + yield put(loginRequestFailure({ errorCode: FORBIDDEN_REQUEST })); } else { - yield put(loginRequestFailure(camelCaseObject({ errorCode: INTERNAL_SERVER_ERROR }))); + yield put(loginRequestFailure({ errorCode: INTERNAL_SERVER_ERROR })); } } logError(e); diff --git a/src/login/data/tests/sagas.test.js b/src/login/data/tests/sagas.test.js index 5b4a1726..4fed8be1 100644 --- a/src/login/data/tests/sagas.test.js +++ b/src/login/data/tests/sagas.test.js @@ -2,6 +2,7 @@ import { runSaga } from 'redux-saga'; import { camelCaseObject } from '@edx/frontend-platform'; +import { FORBIDDEN_REQUEST, INTERNAL_SERVER_ERROR } from '../constants'; import * as actions from '../actions'; import { handleLoginRequest } from '../sagas'; import * as api from '../service'; @@ -19,6 +20,22 @@ describe('handleLoginRequest', () => { }, }; + const testErrorResponse = async (loginErrorResponse, expectedDispatchers) => { + const loginRequest = jest.spyOn(api, 'loginRequest').mockImplementation(() => Promise.reject(loginErrorResponse)); + + const dispatched = []; + await runSaga( + { dispatch: (action) => dispatched.push(action) }, + handleLoginRequest, + params, + ); + + expect(loginRequest).toHaveBeenCalledTimes(1); + expect(loggingService.logError).toHaveBeenCalled(); + expect(dispatched).toEqual(expectedDispatchers); + loginRequest.mockClear(); + }; + beforeEach(() => { loggingService.logError.mockReset(); }); @@ -52,23 +69,27 @@ describe('handleLoginRequest', () => { }, }, }; - const loginRequest = jest.spyOn(api, 'loginRequest') - .mockImplementation(() => Promise.reject(loginErrorResponse)); - const dispatched = []; - await runSaga( - { dispatch: (action) => dispatched.push(action) }, - handleLoginRequest, - params, - ); - - expect(loginRequest).toHaveBeenCalledTimes(1); - expect(loggingService.logError).toHaveBeenCalled(); - expect(dispatched).toEqual([ + await testErrorResponse(loginErrorResponse, [ actions.loginRequestBegin(), actions.loginRequestFailure(camelCaseObject(loginErrorResponse.response.data)), ]); - loginRequest.mockClear(); + }); + + it('should handle rate limit error code', async () => { + const loginErrorResponse = { + response: { + status: 403, + data: { + errorCode: FORBIDDEN_REQUEST, + }, + }, + }; + + await testErrorResponse(loginErrorResponse, [ + actions.loginRequestBegin(), + actions.loginRequestFailure(loginErrorResponse.response.data), + ]); }); it('should handle 500 error code', async () => { @@ -76,24 +97,14 @@ describe('handleLoginRequest', () => { response: { status: 500, data: { - errorCode: 'internal-server-error', + errorCode: INTERNAL_SERVER_ERROR, }, }, }; - const loginRequest = jest.spyOn(api, 'loginRequest').mockImplementation(() => Promise.reject(loginErrorResponse)); - - const dispatched = []; - await runSaga( - { dispatch: (action) => dispatched.push(action) }, - handleLoginRequest, - params, - ); - - expect(dispatched).toEqual([ + await testErrorResponse(loginErrorResponse, [ actions.loginRequestBegin(), - actions.loginRequestFailure(camelCaseObject(loginErrorResponse.response.data)), + actions.loginRequestFailure(loginErrorResponse.response.data), ]); - loginRequest.mockClear(); }); }); diff --git a/src/login/tests/LoginPage.test.jsx b/src/login/tests/LoginPage.test.jsx index e8e36192..d4b0ca32 100644 --- a/src/login/tests/LoginPage.test.jsx +++ b/src/login/tests/LoginPage.test.jsx @@ -17,9 +17,7 @@ describe('LoginPage', () => { const initialState = { forgotPassword: { status: null }, login: { - forgotPassword: { status: null }, loginResult: { success: false, redirectUrl: '' }, - response_error: null, }, commonComponents: { thirdPartyAuthApiStatus: null, diff --git a/src/reset-password/ResetPasswordPage.jsx b/src/reset-password/ResetPasswordPage.jsx index 6a851cd0..ca5bea6e 100644 --- a/src/reset-password/ResetPasswordPage.jsx +++ b/src/reset-password/ResetPasswordPage.jsx @@ -79,7 +79,7 @@ const ResetPasswordPage = (props) => {