From 59852728cb31326c6c5f720c124078d514a5fe23 Mon Sep 17 00:00:00 2001 From: "D. Ror" Date: Wed, 5 Aug 2020 13:34:37 -0400 Subject: [PATCH] Disambiguate user and username. (#552) --- src/components/Login/LoginActions.tsx | 79 ++++++----- .../Login/LoginPage/LoginComponent.tsx | 55 ++++---- src/components/Login/LoginPage/index.tsx | 12 +- .../LoginPage/tests/LoginComponent.test.tsx | 14 +- src/components/Login/LoginReducer.tsx | 65 ++++----- .../Login/RegisterPage/RegisterComponent.tsx | 64 ++++----- src/components/Login/RegisterPage/index.tsx | 17 ++- .../tests/RegisterComponent.test.tsx | 32 ++--- .../Login/tests/LoginActions.test.tsx | 116 +++++++++------- .../Login/tests/LoginReducer.test.tsx | 131 +++++++++--------- 10 files changed, 305 insertions(+), 280 deletions(-) diff --git a/src/components/Login/LoginActions.tsx b/src/components/Login/LoginActions.tsx index 7f243bad07..302e3cc950 100644 --- a/src/components/Login/LoginActions.tsx +++ b/src/components/Login/LoginActions.tsx @@ -1,11 +1,12 @@ import { Dispatch } from "react"; -import history from "../../history"; import { ThunkAction } from "redux-thunk"; import { AnyAction } from "redux"; + import * as backend from "../../backend"; import { getCurrentUser, setAvatar } from "../../backend/localStorage"; -import { User } from "../../types/user"; +import history from "../../history"; import { StoreAction, reset } from "../../rootActions"; +import { User } from "../../types/user"; export const LOGIN_ATTEMPT = "LOGIN_ATTEMPT"; export type LOGIN_ATTEMPT = typeof LOGIN_ATTEMPT; @@ -35,7 +36,7 @@ export const REGISTER_RESET = "REGISTER_RESET"; export type REGISTER_RESET = typeof REGISTER_RESET; export interface LoginData { - user: string; + username: string; password?: string; } @@ -44,11 +45,11 @@ export type LoginType = | LOGIN_FAILURE | LOGIN_SUCCESS | LOGIN_RESET - | LOGOUT | REGISTER_ATTEMPT - | REGISTER_SUCCESS | REGISTER_FAILURE - | REGISTER_RESET; + | REGISTER_SUCCESS + | REGISTER_RESET + | LOGOUT; //action types @@ -58,14 +59,15 @@ export interface UserAction { } //thunk action creator -export function asyncLogin(user: string, password: string) { +export function asyncLogin(username: string, password: string) { return async (dispatch: Dispatch, getState: any) => { + dispatch(loginAttempt(username)); await backend - .authenticateUser(user, password) - .then(async (res: string) => { - await localStorage.setItem("user", res); //Store tokens' - dispatch(loginSuccess(user)); - var currentUser = getCurrentUser(); + .authenticateUser(username, password) + .then(async (userString: string) => { + await localStorage.setItem("user", userString); //Store tokens' + dispatch(loginSuccess(username)); + const currentUser = getCurrentUser(); if (currentUser) { try { var avatar = await backend.avatarSrc(currentUser!); @@ -77,44 +79,45 @@ export function asyncLogin(user: string, password: string) { history.push("/"); }) .catch((err) => { - dispatch(loginFailure(user)); + dispatch(loginFailure(username)); }); }; } -export function loginAttempt(user: string): UserAction { +export function loginAttempt(username: string): UserAction { return { type: LOGIN_ATTEMPT, - payload: { user }, + payload: { username }, }; } -export function loginFailure(user: string): UserAction { +export function loginFailure(username: string): UserAction { return { type: LOGIN_FAILURE, - payload: { user }, + payload: { username }, }; } -export function loginSuccess(user: string): UserAction { +export function loginSuccess(username: string): UserAction { return { type: LOGIN_SUCCESS, - payload: { user }, + payload: { username }, }; } export function loginReset(): UserAction { return { type: LOGIN_RESET, - payload: { user: "" }, + payload: { username: "" }, }; } export function logoutAndResetStore() { return (dispatch: Dispatch) => { - const user = localStorage.getItem("user"); - if (user) { - dispatch(logout(user)); + const userString: string | null = localStorage.getItem("user"); + if (userString) { + const user: User = JSON.parse(userString); + dispatch(logout(user.username)); } dispatch(reset()); localStorage.removeItem("user"); @@ -123,21 +126,21 @@ export function logoutAndResetStore() { export function asyncRegister( name: string, - user: string, + username: string, email: string, password: string ) { return async ( dispatch: Dispatch> ) => { - dispatch(registerAttempt(user)); + dispatch(registerAttempt(username)); // Create new user - let newUser = new User(name, user, password); + let newUser: User = new User(name, username, password); newUser.email = email; await backend .addUser(newUser) .then((res) => { - dispatch(registerSuccess(user)); + dispatch(registerSuccess(username)); setTimeout(() => { dispatch(registerReset()); history.push("/login"); @@ -150,37 +153,37 @@ export function asyncRegister( }); }; } -export function registerAttempt(user: string): UserAction { +export function registerAttempt(username: string): UserAction { return { type: REGISTER_ATTEMPT, - payload: { user }, + payload: { username }, }; } -export function registerSuccess(user: string): UserAction { +export function registerFailure(errorMessage: string): UserAction { return { - type: REGISTER_SUCCESS, - payload: { user }, + type: REGISTER_FAILURE, + payload: { username: errorMessage }, }; } -export function registerFailure(errorMessage: string): UserAction { +export function registerSuccess(username: string): UserAction { return { - type: REGISTER_FAILURE, - payload: { user: errorMessage }, + type: REGISTER_SUCCESS, + payload: { username }, }; } export function registerReset(): UserAction { return { type: REGISTER_RESET, - payload: { user: "" }, + payload: { username: "" }, }; } -function logout(user: string): UserAction { +function logout(username: string): UserAction { return { type: LOGOUT, - payload: { user: user }, + payload: { username }, }; } diff --git a/src/components/Login/LoginPage/LoginComponent.tsx b/src/components/Login/LoginPage/LoginComponent.tsx index f7ce58c762..1cac0b634b 100644 --- a/src/components/Login/LoginPage/LoginComponent.tsx +++ b/src/components/Login/LoginPage/LoginComponent.tsx @@ -1,26 +1,26 @@ -//external modules -import * as React from "react"; -import { - Translate, - LocalizeContextProps, - withLocalize, -} from "react-localize-redux"; -import Button from "@material-ui/core/Button"; -import TextField from "@material-ui/core/TextField"; import { - Grid, + Button, Card, CardContent, CircularProgress, - Typography, + Grid, Link, + TextField, + Typography, } from "@material-ui/core"; -import history from "../../../history"; import ReCaptcha from "@matt-block/react-recaptcha-v2"; +import * as React from "react"; +import { + LocalizeContextProps, + Translate, + withLocalize, +} from "react-localize-redux"; + +import history from "../../../history"; import { RuntimeConfig } from "../../../types/runtimeConfig"; export interface LoginDispatchProps { - login?: (user: string, password: string) => void; + login?: (username: string, password: string) => void; logout: () => void; reset: () => void; } @@ -31,10 +31,15 @@ export interface LoginStateProps { } export interface LoginState { - user: string; + username: string; password: string; isVerified: boolean; - error: { password: boolean; username: boolean }; + error: LoginError; +} + +interface LoginError { + username: boolean; + password: boolean; } export class Login extends React.Component< @@ -48,10 +53,10 @@ export class Login extends React.Component< this.props.logout(); //Hitting the login page will log a user out (doubles as a logout page, essentially) this.state = { - user: "", + username: "", password: "", isVerified: !RuntimeConfig.getInstance().captchaRequired(), - error: { password: false, username: false }, + error: { username: false, password: false }, }; } @@ -80,15 +85,15 @@ export class Login extends React.Component< login(e: React.FormEvent) { e.preventDefault(); - let user = this.state.user.trim(); - let pass = this.state.password.trim(); + const username: string = this.state.username.trim(); + const password: string = this.state.password.trim(); let error = { ...this.state.error }; - error.password = pass === ""; - error.username = user === ""; - if (error.password || error.username) { + error.username = username === ""; + error.password = password === ""; + if (error.username || error.password) { this.setState({ error }); } else if (this.props.login) { - this.props.login(user, pass); + this.props.login(username, password); } } @@ -108,8 +113,8 @@ export class Login extends React.Component< required autoComplete="username" label={} - value={this.state.user} - onChange={(e) => this.updateField(e, "user")} + value={this.state.username} + onChange={(e) => this.updateField(e, "username")} error={this.state.error["username"]} helperText={ this.state.error["username"] ? ( diff --git a/src/components/Login/LoginPage/index.tsx b/src/components/Login/LoginPage/index.tsx index 5b298f0c28..a0ca8fce3f 100644 --- a/src/components/Login/LoginPage/index.tsx +++ b/src/components/Login/LoginPage/index.tsx @@ -1,14 +1,14 @@ -import Login, { LoginStateProps, LoginDispatchProps } from "./LoginComponent"; -import { StoreState } from "../../../types"; - import { connect } from "react-redux"; import { ThunkDispatch } from "redux-thunk"; + +import { StoreState } from "../../../types"; import { asyncLogin, - UserAction, loginReset, logoutAndResetStore, + UserAction, } from "../LoginActions"; +import Login, { LoginDispatchProps, LoginStateProps } from "./LoginComponent"; function mapStateToProps(state: StoreState): LoginStateProps { return { @@ -21,8 +21,8 @@ export function mapDispatchToProps( dispatch: ThunkDispatch ): LoginDispatchProps { return { - login: (user: string, password: string) => { - dispatch(asyncLogin(user, password)); + login: (username: string, password: string) => { + dispatch(asyncLogin(username, password)); }, logout: () => { dispatch(logoutAndResetStore()); diff --git a/src/components/Login/LoginPage/tests/LoginComponent.test.tsx b/src/components/Login/LoginPage/tests/LoginComponent.test.tsx index 0957067dd4..707f72cb08 100644 --- a/src/components/Login/LoginPage/tests/LoginComponent.test.tsx +++ b/src/components/Login/LoginPage/tests/LoginComponent.test.tsx @@ -59,28 +59,28 @@ describe("Testing login component", () => { }); test("Login: no password", () => { - testLogin("User", "", false, true); + testLogin("Username", "", false, true); }); - test("Login: no user", () => { + test("Login: no username", () => { testLogin("", "Password", true, false); }); test("Login: all fields good", () => { - testLogin("User", "Password", false, false); + testLogin("Username", "Password", false, false); }); }); function testLogin( - user: string, + username: string, password: string, - goodUser: boolean, + goodUsername: boolean, goodPassword: boolean ) { - loginHandle.instance.setState({ user: user, password: password }); + loginHandle.instance.setState({ username, password }); loginHandle.instance.login(MOCK_EVENT); expect(loginHandle.instance.state.error).toEqual({ - username: goodUser, + username: goodUsername, password: goodPassword, }); } diff --git a/src/components/Login/LoginReducer.tsx b/src/components/Login/LoginReducer.tsx index 1adbde787c..fd85ea44dd 100644 --- a/src/components/Login/LoginReducer.tsx +++ b/src/components/Login/LoginReducer.tsx @@ -1,90 +1,79 @@ -import { - UserAction, - LOGIN_ATTEMPT, - LOGIN_FAILURE, - LOGIN_SUCCESS, - LOGIN_RESET, - REGISTER_FAILURE, - REGISTER_ATTEMPT, - REGISTER_SUCCESS, - REGISTER_RESET, - LOGOUT, -} from "./LoginActions"; import { StoreAction, StoreActions } from "../../rootActions"; +import * as LoginAction from "./LoginActions"; export interface LoginState { - user: string; - success: boolean; + username: string; loginAttempt: boolean; loginFailure: boolean; + loginSuccess: boolean; registerAttempt: boolean; - registerSuccess: boolean; registerFailure: string; + registerSuccess: boolean; } export const defaultState: LoginState = { - user: "", - success: false, + username: "", loginAttempt: false, loginFailure: false, + loginSuccess: false, registerAttempt: false, - registerSuccess: false, registerFailure: "", + registerSuccess: false, }; export const loginReducer = ( state: LoginState = defaultState, //createStore() calls each reducer with undefined state - action: StoreAction | UserAction + action: StoreAction | LoginAction.UserAction ): LoginState => { switch (action.type) { - case LOGIN_ATTEMPT: + case LoginAction.LOGIN_ATTEMPT: return { ...state, - user: action.payload.user, - success: false, + username: action.payload.username, loginAttempt: true, + loginSuccess: false, loginFailure: false, }; - case LOGIN_FAILURE: + case LoginAction.LOGIN_FAILURE: return { ...state, - user: action.payload.user, - success: false, + username: action.payload.username, loginAttempt: false, loginFailure: true, + loginSuccess: false, }; - case LOGIN_SUCCESS: + case LoginAction.LOGIN_SUCCESS: return { ...state, - user: action.payload.user, - success: true, + username: action.payload.username, + loginSuccess: true, }; - case REGISTER_ATTEMPT: + case LoginAction.REGISTER_ATTEMPT: return { ...state, - user: action.payload.user, + username: action.payload.username, registerAttempt: true, - registerSuccess: false, registerFailure: "", + registerSuccess: false, }; - case REGISTER_SUCCESS: + case LoginAction.REGISTER_SUCCESS: return { ...state, - user: action.payload.user, + username: action.payload.username, registerAttempt: false, registerSuccess: true, }; - case REGISTER_FAILURE: + case LoginAction.REGISTER_FAILURE: return { ...state, registerAttempt: false, + registerFailure: action.payload.username, registerSuccess: false, - registerFailure: action.payload.user, }; - case LOGIN_RESET: - case LOGOUT: + case LoginAction.LOGIN_RESET: + case LoginAction.LOGOUT: case StoreActions.RESET: - case REGISTER_RESET: + case LoginAction.REGISTER_RESET: return defaultState; default: return state; diff --git a/src/components/Login/RegisterPage/RegisterComponent.tsx b/src/components/Login/RegisterPage/RegisterComponent.tsx index 5866f96837..261141f3a6 100644 --- a/src/components/Login/RegisterPage/RegisterComponent.tsx +++ b/src/components/Login/RegisterPage/RegisterComponent.tsx @@ -23,7 +23,7 @@ import { passwordRequirements, usernameRequirements } from "../../../utilities"; export interface RegisterDispatchProps { register?: ( name: string, - user: string, + username: string, email: string, password: string ) => void; @@ -38,16 +38,16 @@ export interface RegisterStateProps { interface RegisterState { name: string; - user: string; + username: string; + email: string; password: string; confirmPassword: string; - email: string; error: { - password: boolean; - user: boolean; - confirmPassword: boolean; name: boolean; + username: boolean; email: boolean; + password: boolean; + confirmPassword: boolean; }; } @@ -61,16 +61,16 @@ export class Register extends React.Component< super(props); this.state = { name: "", - user: "", + username: "", + email: "", password: "", confirmPassword: "", - email: "", error: { - password: false, - user: false, - confirmPassword: false, name: false, + username: false, email: false, + password: false, + confirmPassword: false, }, }; } @@ -86,7 +86,7 @@ export class Register extends React.Component< >, field: K ) { - const value = e.target.value; + const value: string = e.target.value; this.setState({ [field]: value, @@ -95,14 +95,14 @@ export class Register extends React.Component< } async checkUsername(username: string) { - let usernameTaken = await isUsernameTaken(username); + const usernameTaken: boolean = await isUsernameTaken(username); if (usernameTaken) { - this.setState({ error: { ...this.state.error, user: true } }); + this.setState({ error: { ...this.state.error, username: true } }); } } async checkEmail(username: string) { - let emailTaken = await isEmailTaken(username); + const emailTaken: boolean = await isEmailTaken(username); if (emailTaken) { this.setState({ error: { ...this.state.error, email: true } }); } @@ -110,30 +110,30 @@ export class Register extends React.Component< register(e: React.FormEvent) { e.preventDefault(); - let name = this.state.name.trim(); - let user = this.state.user.trim(); - let email = this.state.email.trim(); - let pass = this.state.password.trim(); - let confPass = this.state.confirmPassword.trim(); + const name: string = this.state.name.trim(); + const username: string = this.state.username.trim(); + const email: string = this.state.email.trim(); + const password: string = this.state.password.trim(); + const confirmPassword: string = this.state.confirmPassword.trim(); // error checking let error = { ...this.state.error }; error.name = name === ""; - error.password = !passwordRequirements(pass); - error.user = !usernameRequirements(user); - error.confirmPassword = pass !== confPass; + error.username = !usernameRequirements(username); error.email = email === ""; + error.password = !passwordRequirements(password); + error.confirmPassword = password !== confirmPassword; if ( error.name || + error.username || + error.email || error.password || - error.user || - error.confirmPassword || - error.email + error.confirmPassword ) { this.setState({ error }); } else if (this.props.register) { - this.props.register(name, user, email, pass); + this.props.register(name, username, email, password); } } @@ -182,12 +182,12 @@ export class Register extends React.Component< required autoComplete="username" label={} - value={this.state.user} - onChange={(e) => this.updateField(e, "user")} - onBlur={() => this.checkUsername(this.state.user)} - error={this.state.error["user"]} + value={this.state.username} + onChange={(e) => this.updateField(e, "username")} + onBlur={() => this.checkUsername(this.state.username)} + error={this.state.error["username"]} helperText={ - this.state.error["user"] ? ( + this.state.error["username"] ? ( ) : ( diff --git a/src/components/Login/RegisterPage/index.tsx b/src/components/Login/RegisterPage/index.tsx index da0df2755f..7b49949680 100644 --- a/src/components/Login/RegisterPage/index.tsx +++ b/src/components/Login/RegisterPage/index.tsx @@ -1,9 +1,9 @@ -import Register, { RegisterStateProps } from "./RegisterComponent"; -import { StoreState } from "../../../types"; - import { connect } from "react-redux"; import { ThunkDispatch } from "redux-thunk"; -import { UserAction, asyncRegister, registerReset } from "../LoginActions"; + +import { StoreState } from "../../../types"; +import { asyncRegister, registerReset, UserAction } from "../LoginActions"; +import Register, { RegisterStateProps } from "./RegisterComponent"; function mapStateToProps(state: StoreState): RegisterStateProps { return { @@ -17,8 +17,13 @@ export function mapDispatchToProps( dispatch: ThunkDispatch ) { return { - register: (name: string, user: string, email: string, password: string) => { - dispatch(asyncRegister(name, user, email, password)); + register: ( + name: string, + username: string, + email: string, + password: string + ) => { + dispatch(asyncRegister(name, username, email, password)); }, reset: () => { dispatch(registerReset()); diff --git a/src/components/Login/RegisterPage/tests/RegisterComponent.test.tsx b/src/components/Login/RegisterPage/tests/RegisterComponent.test.tsx index 770293f0d5..210798adec 100644 --- a/src/components/Login/RegisterPage/tests/RegisterComponent.test.tsx +++ b/src/components/Login/RegisterPage/tests/RegisterComponent.test.tsx @@ -55,29 +55,29 @@ describe("Testing register component", () => { // These test whether various combinations of registration data should result in errors test("Register: no data", () => { - testRegister("", "", "", "", "", true, true, true, false, true); + testRegister("", "", "", "", "", true, true, true, true, false); }); test("Register: confirm password doesn't match password", () => { testRegister( "Frodo Baggins", "underhill", + "a@b.c", "1234567890", "1234567899", - "a@b.c", false, false, false, - true, - false + false, + true ); }); test("Register: username too short", () => { testRegister( "Samwise Gamgee", "sg", + "a@b.c", "12345678", "12345678", - "a@b.c", false, true, false, @@ -89,13 +89,13 @@ describe("Testing register component", () => { testRegister( "Bilbo Baggins", "bbb", + "a@b.c", "sting", "sting", - "a@b.c", false, false, - true, false, + true, false ); }); @@ -103,29 +103,29 @@ describe("Testing register component", () => { function testRegister( name: string, - user: string, + username: string, + email: string, password: string, confirmPassword: string, - email: string, error_name: boolean, - error_user: boolean, + error_username: boolean, + error_email: boolean, error_password: boolean, - error_confirmPassword: boolean, - error_email: boolean + error_confirmPassword: boolean ) { registerHandle.instance.setState({ name, - user, + username, + email, password, confirmPassword, - email, }); registerHandle.instance.register(MOCK_EVENT); expect(registerHandle.instance.state.error).toEqual({ name: error_name, - user: error_user, + username: error_username, + email: error_email, password: error_password, confirmPassword: error_confirmPassword, - email: error_email, }); } diff --git a/src/components/Login/tests/LoginActions.test.tsx b/src/components/Login/tests/LoginActions.test.tsx index 8a089bd40c..6ad2e31d68 100644 --- a/src/components/Login/tests/LoginActions.test.tsx +++ b/src/components/Login/tests/LoginActions.test.tsx @@ -1,53 +1,54 @@ -import * as action from "../LoginActions"; -import * as reducer from "../LoginReducer"; -import * as rootAction from "../../../rootActions"; import configureMockStore from "redux-mock-store"; import thunk from "redux-thunk"; +import * as RootAction from "../../../rootActions"; +import * as LoginAction from "../LoginActions"; +import * as LoginReducer from "../LoginReducer"; + const createMockStore = configureMockStore([thunk]); -const user = { user: "testUser", password: "testPass" }; +const user = { username: "testUsername", password: "testPassword" }; describe("LoginAction Tests", () => { - let mockState: reducer.LoginState = reducer.defaultState; + let mockState: LoginReducer.LoginState = LoginReducer.defaultState; - let loginAttempt: action.UserAction = { - type: action.LOGIN_ATTEMPT, - payload: { user: user.user }, + let loginAttempt: LoginAction.UserAction = { + type: LoginAction.LOGIN_ATTEMPT, + payload: { username: user.username }, }; - let loginSuccess: action.UserAction = { - type: action.LOGIN_SUCCESS, - payload: { user: user.user }, + let loginSuccess: LoginAction.UserAction = { + type: LoginAction.LOGIN_SUCCESS, + payload: { username: user.username }, }; - let logout: action.UserAction = { - type: action.LOGOUT, - payload: { user: user.user }, + let logout: LoginAction.UserAction = { + type: LoginAction.LOGOUT, + payload: { username: user.username }, }; - let reset: rootAction.StoreAction = { - type: rootAction.StoreActions.RESET, + let reset: RootAction.StoreAction = { + type: RootAction.StoreActions.RESET, }; - let registerAttempt: action.UserAction = { - type: action.REGISTER_ATTEMPT, - payload: { user: user.user }, + let registerAttempt: LoginAction.UserAction = { + type: LoginAction.REGISTER_ATTEMPT, + payload: { username: user.username }, }; - let registerFailure: action.UserAction = { - type: action.REGISTER_FAILURE, - payload: { user: user.user }, + let registerFailure: LoginAction.UserAction = { + type: LoginAction.REGISTER_FAILURE, + payload: { username: user.username }, }; test("register returns correct value", () => { - expect(action.registerAttempt(user.user)).toEqual(registerAttempt); + expect(LoginAction.registerAttempt(user.username)).toEqual(registerAttempt); }); test("asyncLogin correctly affects state", () => { const mockStore = createMockStore(mockState); const mockDispatch = mockStore.dispatch( - action.asyncLogin(user.user, user.password) + LoginAction.asyncLogin(user.username, user.password) ); mockDispatch @@ -63,7 +64,7 @@ describe("LoginAction Tests", () => { test("asyncRegister correctly affects state", () => { const mockStore = createMockStore(mockState); const mockDispatch = mockStore.dispatch( - action.asyncRegister("name", user.user, "", user.password) + LoginAction.asyncRegister("name", user.username, "", user.password) ); mockDispatch @@ -80,62 +81,83 @@ describe("LoginAction Tests", () => { }); test("loginAttempt returns correct value", () => { - testActionCreatorAgainst(action.loginAttempt, action.LOGIN_ATTEMPT); + testActionCreatorAgainst( + LoginAction.loginAttempt, + LoginAction.LOGIN_ATTEMPT + ); }); test("loginFailure returns correct value", () => { - testActionCreatorAgainst(action.loginFailure, action.LOGIN_FAILURE); + testActionCreatorAgainst( + LoginAction.loginFailure, + LoginAction.LOGIN_FAILURE + ); }); test("loginSuccess returns correct value", () => { - testActionCreatorAgainst(action.loginSuccess, action.LOGIN_SUCCESS); + testActionCreatorAgainst( + LoginAction.loginSuccess, + LoginAction.LOGIN_SUCCESS + ); }); test("registerAttempt returns correct value", () => { - testActionCreatorAgainst(action.registerAttempt, action.REGISTER_ATTEMPT); + testActionCreatorAgainst( + LoginAction.registerAttempt, + LoginAction.REGISTER_ATTEMPT + ); }); - test("registerSuccess returns correct value", () => { - testActionCreatorAgainst(action.registerSuccess, action.REGISTER_SUCCESS); + test("registerFailure returns correct value", () => { + testActionCreatorAgainst( + LoginAction.registerFailure, + LoginAction.REGISTER_FAILURE + ); }); - test("registerFailure returns correct value", () => { - testActionCreatorAgainst(action.registerFailure, action.REGISTER_FAILURE); + test("registerSuccess returns correct value", () => { + testActionCreatorAgainst( + LoginAction.registerSuccess, + LoginAction.REGISTER_SUCCESS + ); }); test("loginReset returns correct value", () => { - expect(action.loginReset()).toEqual({ - type: action.LOGIN_RESET, - payload: { user: "" }, + expect(LoginAction.loginReset()).toEqual({ + type: LoginAction.LOGIN_RESET, + payload: { username: "" }, }); }); test("registerReset returns correct value", () => { - expect(action.registerReset()).toEqual({ - type: action.REGISTER_RESET, - payload: { user: "" }, + expect(LoginAction.registerReset()).toEqual({ + type: LoginAction.REGISTER_RESET, + payload: { username: "" }, }); }); test("loginAttempt returns correct value", () => { - testActionCreatorAgainst(action.loginAttempt, action.LOGIN_ATTEMPT); + testActionCreatorAgainst( + LoginAction.loginAttempt, + LoginAction.LOGIN_ATTEMPT + ); }); - test("logout creates a proper action", () => { - localStorage.setItem("user", user.user); + test("logout creates a proper LoginAction", () => { + localStorage.setItem("user", JSON.stringify(user)); const mockStore = createMockStore(mockState); - mockStore.dispatch(action.logoutAndResetStore()); + mockStore.dispatch(LoginAction.logoutAndResetStore()); expect(mockStore.getActions()).toEqual([logout, reset]); expect(localStorage.getItem("user")).toBe(null); }); }); function testActionCreatorAgainst( - action: (name: string) => action.UserAction, - type: action.LoginType + LoginAction: (name: string) => LoginAction.UserAction, + type: LoginAction.LoginType ) { - expect(action(user.user)).toEqual({ + expect(LoginAction(user.username)).toEqual({ type: type, - payload: { user: user.user }, + payload: { username: user.username }, }); } diff --git a/src/components/Login/tests/LoginReducer.test.tsx b/src/components/Login/tests/LoginReducer.test.tsx index 6db3b3a89e..44138a0a18 100644 --- a/src/components/Login/tests/LoginReducer.test.tsx +++ b/src/components/Login/tests/LoginReducer.test.tsx @@ -1,139 +1,140 @@ -import * as reducer from "../LoginReducer"; -import { - UserAction, - LOGIN_ATTEMPT, - LOGIN_FAILURE, - REGISTER_ATTEMPT, - LOGIN_SUCCESS, - REGISTER_SUCCESS, - REGISTER_FAILURE, - LOGIN_RESET, - REGISTER_RESET, -} from "../LoginActions"; -import { StoreActions, StoreAction } from "../../../rootActions"; - -const user = { user: "testUser", password: "testPass" }; +import * as RootAction from "../../../rootActions"; +import * as LoginAction from "../LoginActions"; +import * as LoginReducer from "../LoginReducer"; + +const user: LoginAction.LoginData = { + username: "testUsername", + password: "testPassword", +}; describe("LoginReducer Tests", () => { - let dummyState: reducer.LoginState = { - ...reducer.defaultState, - user: user.user, - success: false, + let dummyState: LoginReducer.LoginState = { + ...LoginReducer.defaultState, + username: user.username, + loginSuccess: false, }; //The state while attempting to log in - let loginAttemptState: reducer.LoginState = { + let loginAttemptState: LoginReducer.LoginState = { + username: "testUsername", loginAttempt: true, loginFailure: false, + loginSuccess: false, registerAttempt: false, registerFailure: "", registerSuccess: false, - success: false, - user: "testUser", }; - let action: UserAction = { - type: LOGIN_ATTEMPT, + let action: LoginAction.UserAction = { + type: LoginAction.LOGIN_ATTEMPT, payload: user, }; // Test with no state test("no state, expecting login attempt", () => { - action.type = LOGIN_ATTEMPT; - expect(reducer.loginReducer(undefined, action)).toEqual(loginAttemptState); + action.type = LoginAction.LOGIN_ATTEMPT; + expect(LoginReducer.loginReducer(undefined, action)).toEqual( + loginAttemptState + ); }); test("default state, expecting login attempt", () => { - action.type = LOGIN_ATTEMPT; - expect(reducer.loginReducer(dummyState, action)).toEqual(loginAttemptState); + action.type = LoginAction.LOGIN_ATTEMPT; + expect(LoginReducer.loginReducer(dummyState, action)).toEqual( + loginAttemptState + ); }); test("failed login, expecting no success", () => { - let loginFailureState: reducer.LoginState = { - ...reducer.defaultState, + let loginFailureState: LoginReducer.LoginState = { + ...LoginReducer.defaultState, + username: user.username, loginAttempt: false, loginFailure: true, - user: user.user, - success: false, + loginSuccess: false, }; - action.type = LOGIN_FAILURE; - expect(reducer.loginReducer(dummyState, action)).toEqual(loginFailureState); + action.type = LoginAction.LOGIN_FAILURE; + expect(LoginReducer.loginReducer(dummyState, action)).toEqual( + loginFailureState + ); }); test("default state, expecting register", () => { - let resultState: reducer.LoginState = { + let resultState: LoginReducer.LoginState = { + username: "testUsername", loginAttempt: false, loginFailure: false, + loginSuccess: false, registerAttempt: true, registerFailure: "", registerSuccess: false, - success: false, - user: "testUser", }; - action.type = REGISTER_ATTEMPT; + action.type = LoginAction.REGISTER_ATTEMPT; - expect(reducer.loginReducer(dummyState, action)).toEqual(resultState); + expect(LoginReducer.loginReducer(dummyState, action)).toEqual(resultState); }); test("default state, expecting login success", () => { - let loginSuccessState: reducer.LoginState = { + let loginSuccessState: LoginReducer.LoginState = { ...dummyState, - user: user.user, - success: true, + username: user.username, + loginSuccess: true, }; - action.type = LOGIN_SUCCESS; + action.type = LoginAction.LOGIN_SUCCESS; - expect(reducer.loginReducer(dummyState, action)).toEqual(loginSuccessState); + expect(LoginReducer.loginReducer(dummyState, action)).toEqual( + loginSuccessState + ); }); test("default state, expecting register success", () => { - let registerSuccessState: reducer.LoginState = { + let registerSuccessState: LoginReducer.LoginState = { ...dummyState, - user: user.user, + username: user.username, registerAttempt: false, registerSuccess: true, }; - action.type = REGISTER_SUCCESS; - expect(reducer.loginReducer(dummyState, action)).toEqual( + action.type = LoginAction.REGISTER_SUCCESS; + expect(LoginReducer.loginReducer(dummyState, action)).toEqual( registerSuccessState ); }); test("default state, expecting register failure", () => { - let registerFailureState: reducer.LoginState = { + let registerFailureState: LoginReducer.LoginState = { ...dummyState, registerAttempt: false, + registerFailure: "testUsername", registerSuccess: false, - registerFailure: "testUser", }; - action.type = REGISTER_FAILURE; - expect(reducer.loginReducer(dummyState, action)).toEqual( + action.type = LoginAction.REGISTER_FAILURE; + expect(LoginReducer.loginReducer(dummyState, action)).toEqual( registerFailureState ); }); test("non-default state, expecting login reset", () => { - action.type = LOGIN_RESET; - expect(reducer.loginReducer({} as reducer.LoginState, action)).toEqual( - reducer.defaultState - ); + action.type = LoginAction.LOGIN_RESET; + expect( + LoginReducer.loginReducer({} as LoginReducer.LoginState, action) + ).toEqual(LoginReducer.defaultState); }); test("non-default state, expecting register reset", () => { - action.type = REGISTER_RESET; - expect(reducer.loginReducer({} as reducer.LoginState, action)).toEqual( - reducer.defaultState - ); + action.type = LoginAction.REGISTER_RESET; + expect( + LoginReducer.loginReducer({} as LoginReducer.LoginState, action) + ).toEqual(LoginReducer.defaultState); }); test("non-default state, expecting reset", () => { - const resetAction: StoreAction = { - type: StoreActions.RESET, + const resetAction: RootAction.StoreAction = { + type: RootAction.StoreActions.RESET, }; - expect(reducer.loginReducer({} as reducer.LoginState, resetAction)).toEqual( - reducer.defaultState - ); + expect( + LoginReducer.loginReducer({} as LoginReducer.LoginState, resetAction) + ).toEqual(LoginReducer.defaultState); }); });