Skip to content
This repository has been archived by the owner on Nov 21, 2024. It is now read-only.

Commit

Permalink
feat: show different success message for password on success, refactor (
Browse files Browse the repository at this point in the history
#413)

* feat: show differnt success message for password on success, refactor

* refactor: apply new design

* fix(test): use correct magic link email input

* feat: improve code from code review

* refactor: update backgrounds

* refactor: fix tests

* refactor: remove container

---------

Co-authored-by: Thibault Reidy <[email protected]>
  • Loading branch information
pyphilia and ReidyT authored Sep 11, 2024
1 parent fed4476 commit 606cc7a
Show file tree
Hide file tree
Showing 29 changed files with 822 additions and 524 deletions.
6 changes: 3 additions & 3 deletions cypress/e2e/SignIn.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ describe('Name and Email Validation', () => {
const { GRAASP, WRONG_EMAIL } = MEMBERS;
cy.visit(SIGN_IN_PATH);
// Signing in with a wrong email format
cy.signInAndCheck(WRONG_EMAIL);
// Siging in with a valid email
cy.signInAndCheck(GRAASP);
cy.signInByMailAndCheck(WRONG_EMAIL);
// Signing in with a valid email
cy.signInByMailAndCheck(GRAASP);
});
});
43 changes: 40 additions & 3 deletions cypress/e2e/SignInPassword.cy.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { API_ROUTES } from '@graasp/query-client';

import { SIGN_IN_PATH } from '../../src/config/paths';
import { PASSWORD_SUCCESS_ALERT } from '../../src/config/selectors';
import { MEMBERS } from '../fixtures/members';

describe('Email and Password Validation', () => {
Expand All @@ -15,17 +16,53 @@ describe('Email and Password Validation', () => {
},
).as('signInWithPassword');

const { WRONG_EMAIL, GRAASP } = MEMBERS;
cy.visit(SIGN_IN_PATH);
// Signing in with wrong email
cy.signInPasswordAndCheck(WRONG_EMAIL);

// Signing in with a valid email and password
cy.signInPasswordAndCheck(GRAASP);

cy.url().should('contain', redirectionLink);
});

it('Sign In With Wrong Password', () => {
cy.intercept(
{
pathname: API_ROUTES.SIGN_IN_WITH_PASSWORD_ROUTE,
},
(req) => {
req.reply({ statusCode: 500 });
},
).as('signInWithPassword');

const { WRONG_PASSWORD } = MEMBERS;
cy.visit(SIGN_IN_PATH);

// Signing in with a valid email but empty password
cy.signInPasswordAndCheck(WRONG_PASSWORD);
});

it('Sign In With Password shows success message if no redirect', () => {
cy.intercept(
{
pathname: API_ROUTES.SIGN_IN_WITH_PASSWORD_ROUTE,
},
(req) => {
req.reply({ statusCode: 303 });
},
).as('signInWithPassword');

const { WRONG_EMAIL, WRONG_PASSWORD, GRAASP } = MEMBERS;
cy.visit(SIGN_IN_PATH);
// Select sign in method
cy.signInPasswordMethodAndCheck();
// Signing in with wrong email
cy.signInPasswordAndCheck(WRONG_EMAIL);
// Signing in with a valid email but empty password
cy.signInPasswordAndCheck(WRONG_PASSWORD);
// Signing in with a valid email and password
cy.signInPasswordAndCheck(GRAASP);

cy.url().should('contain', redirectionLink);
cy.get(`#${PASSWORD_SUCCESS_ALERT}`).should('be.visible');
});
});
16 changes: 4 additions & 12 deletions cypress/e2e/SuccessContent.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { SIGN_IN_PATH, SIGN_UP_PATH } from '../../src/config/paths';
import {
BACK_BUTTON_ID,
EMAIL_SIGN_IN_FIELD_ID,
EMAIL_SIGN_UP_FIELD_ID,
RESEND_EMAIL_BUTTON_ID,
SIGN_IN_HEADER_ID,
SIGN_UP_HEADER_ID,
Expand All @@ -29,7 +28,7 @@ describe('Success Content', () => {
cy.get(`#${SUCCESS_CONTENT_ID}`).should('not.exist');

// Signing in with a valid email
cy.signInAndCheck(GRAASP);
cy.signInByMailAndCheck(GRAASP);

cy.get(`#${SUCCESS_CONTENT_ID}`).should('be.visible');

Expand All @@ -42,7 +41,7 @@ describe('Success Content', () => {
cy.get(`#${EMAIL_SIGN_IN_FIELD_ID}`).should('be.empty');

// check if it's possible to sign in and use back button again
cy.signInAndCheck(GRAASP_OTHER);
cy.signInByMailAndCheck(GRAASP_OTHER);

cy.get(`#${SUCCESS_CONTENT_ID}`).should('be.visible');

Expand All @@ -66,10 +65,10 @@ describe('Success Content', () => {
});

// Signing in with a valid email
cy.signInAndCheck(GRAASP_OTHER);
cy.signInByMailAndCheck(GRAASP_OTHER);
cy.get(`#${BACK_BUTTON_ID}`).click();

cy.signInAndCheck(GRAASP);
cy.signInByMailAndCheck(GRAASP);

// checks so request body contains correct email
cy.intercept(API_ROUTES.SIGN_IN_ROUTE, ({ body }) => {
Expand Down Expand Up @@ -105,8 +104,6 @@ describe('Success Content', () => {
cy.get(`#${SUCCESS_CONTENT_ID}`).should('not.exist');
cy.url().should('include', SIGN_UP_PATH);
cy.get(`#${SIGN_UP_HEADER_ID}`).should('be.visible');
// checks so email is still filled
cy.get(`#${EMAIL_SIGN_UP_FIELD_ID}`).should('have.value', GRAASP.email);

// check if it's possible to sign up and use back button again
cy.signUpAndCheck(GRAASP_OTHER, true);
Expand All @@ -118,11 +115,6 @@ describe('Success Content', () => {
cy.get(`#${SUCCESS_CONTENT_ID}`).should('not.exist');
cy.url().should('include', SIGN_UP_PATH);
cy.get(`#${SIGN_UP_HEADER_ID}`).should('be.visible');
// checks so email is still filled
cy.get(`#${EMAIL_SIGN_UP_FIELD_ID}`).should(
'have.value',
GRAASP_OTHER.email,
);
});

it('Resend email', () => {
Expand Down
10 changes: 3 additions & 7 deletions cypress/e2e/util.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import {
EMAIL_SIGN_IN_FIELD_ID,
EMAIL_SIGN_IN_MAGIC_LINK_FIELD_ID,
EMAIL_SIGN_UP_FIELD_ID,
NAME_SIGN_UP_FIELD_ID,
PASSWORD_SIGN_IN_BUTTON_ID,
PASSWORD_SIGN_IN_FIELD_ID,
PASSWORD_SIGN_IN_METHOD_BUTTON_ID,
SIGN_IN_BUTTON_ID,
SIGN_UP_BUTTON_ID,
} from '../../src/config/selectors';
Expand Down Expand Up @@ -37,8 +37,8 @@ export const checkInvitationFields = ({
.should('be.disabled');
};

export const fillSignInLayout = ({ email }: { email?: string }) => {
cy.get(`#${EMAIL_SIGN_IN_FIELD_ID}`).clear().type(email);
export const fillSignInByMailLayout = ({ email }: { email?: string }) => {
cy.get(`#${EMAIL_SIGN_IN_MAGIC_LINK_FIELD_ID}`).clear().type(email);
};

export const submitSignIn = () => {
Expand All @@ -49,10 +49,6 @@ export const submitSignUp = () => {
cy.get(`#${SIGN_UP_BUTTON_ID}`).click();
};

export const passwordSignInMethod = () => {
cy.get(`#${PASSWORD_SIGN_IN_METHOD_BUTTON_ID}`).click();
};

export const fillPasswordSignInLayout = ({
email,
password,
Expand Down
25 changes: 10 additions & 15 deletions cypress/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,16 @@ import { Member } from '@graasp/sdk';

import {
EMAIL_SIGN_IN_FIELD_ID,
EMAIL_SIGN_IN_MAGIC_LINK_FIELD_ID,
EMAIL_SIGN_UP_FIELD_ID,
NAME_SIGN_UP_FIELD_ID,
PASSWORD_SIGN_IN_FIELD_ID,
PASSWORD_SIGN_IN_METHOD_BUTTON_ID,
SIGN_UP_AGREEMENTS_CHECKBOX_ID,
} from '../../src/config/selectors';
import {
fillPasswordSignInLayout,
fillSignInLayout,
fillSignInByMailLayout,
fillSignUpLayout,
passwordSignInMethod,
submitPasswordSignIn,
submitSignIn,
submitSignUp,
Expand Down Expand Up @@ -54,21 +53,20 @@ declare global {
acceptAllTerms?: boolean,
): Chainable<JQuery<HTMLElement>>;

signInAndCheck(
signInByMailAndCheck(
value: Partial<Member> & {
nameValid?: boolean;
emailValid?: boolean;
passwordValid?: boolean;
},
): Chainable<JQuery<HTMLElement>>;

signInPasswordMethodAndCheck(): Chainable<JQuery<HTMLElement>>;

signInPasswordAndCheck(
member: Member & {
nameValid?: boolean;
emailValid?: boolean;
passwordValid?: boolean;
password?: string;
},
): Chainable<JQuery<HTMLElement>>;

Expand Down Expand Up @@ -112,23 +110,20 @@ Cypress.Commands.add('signUpAndCheck', (user, acceptAllTerms) => {
cy.checkErrorTextField(EMAIL_SIGN_UP_FIELD_ID, user.emailValid);
});

Cypress.Commands.add('signInAndCheck', (user) => {
fillSignInLayout(user);
Cypress.Commands.add('signInByMailAndCheck', (user) => {
fillSignInByMailLayout(user);
submitSignIn();
cy.checkErrorTextField(EMAIL_SIGN_IN_FIELD_ID, user.emailValid);
});

Cypress.Commands.add('signInPasswordMethodAndCheck', () => {
passwordSignInMethod();
cy.get(`#${PASSWORD_SIGN_IN_METHOD_BUTTON_ID}`).should('be.disabled');
cy.checkErrorTextField(EMAIL_SIGN_IN_MAGIC_LINK_FIELD_ID, user.emailValid);
});

Cypress.Commands.add('signInPasswordAndCheck', (user) => {
fillPasswordSignInLayout(user);
if (user.password) {
submitPasswordSignIn();
}
if (!user.passwordValid) {
cy.get(`#${PASSWORD_SIGN_IN_FIELD_ID}`).clear();
}
submitPasswordSignIn();
cy.checkErrorTextField(EMAIL_SIGN_IN_FIELD_ID, user.emailValid);
cy.checkErrorTextField(PASSWORD_SIGN_IN_FIELD_ID, user.passwordValid);
});
6 changes: 6 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ import * as Sentry from '@sentry/react';
import { Route, BrowserRouter as Router, Routes } from 'react-router-dom';

import ErrorFallback from './components/ErrorFallback';
import MagicLinkSuccessContent from './components/MagicLinkSuccessContent';
import MobileAuth from './components/MobileAuth';
import Redirection from './components/Redirection';
import SignIn from './components/SignIn';
import SignUp from './components/SignUp';
import {
HOME_PATH,
MOBILE_AUTH_PATH,
SIGN_IN_MAGIC_LINK_SUCCESS_PATH,
SIGN_IN_PATH,
SIGN_UP_PATH,
} from './config/paths';
Expand All @@ -19,6 +21,10 @@ const App = () => (
<Redirection>
<Routes>
<Route path={SIGN_IN_PATH} element={<SignIn />} />
<Route
path={SIGN_IN_MAGIC_LINK_SUCCESS_PATH}
element={<MagicLinkSuccessContent />}
/>
<Route path={SIGN_UP_PATH} element={<SignUp />} />
<Route path={HOME_PATH} element={<SignIn />} />
<Route path={MOBILE_AUTH_PATH} element={<MobileAuth />} />
Expand Down
2 changes: 1 addition & 1 deletion src/components/APIChecker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const APIChecker = (): JSX.Element | false => {
if (isError) {
return (
<Box maxWidth="48ch">
<Alert severity="error">
<Alert variant="outlined" sx={{ background: 'white' }} severity="error">
<AlertTitle>{t(AUTH.API_UNAVAILABLE_TITLE)}</AlertTitle>
<Stack direction="column" alignItems="center" spacing={1}>
<Typography>{t(AUTH.API_UNAVAILABLE_EXPLANATION)}</Typography>
Expand Down
3 changes: 1 addition & 2 deletions src/components/AgreementForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
Typography,
} from '@mui/material';

import { MAX_CHECKBOX_LABEL_WITH_PX_SIGN_UP } from '../config/constants';
import { useAuthTranslation } from '../config/i18n';
import { SIGN_UP_AGREEMENTS_CHECKBOX_ID } from '../config/selectors';
import { UseAgreementForm } from '../hooks/useAgreementForm';
Expand All @@ -30,7 +29,7 @@ export const AgreementForm = ({ useAgreementForm }: Props) => {
const errorColor = 'error';

return (
<FormGroup sx={{ maxWidth: `${MAX_CHECKBOX_LABEL_WITH_PX_SIGN_UP}px` }}>
<FormGroup>
<FormControlLabel
checked={userHasAcceptedAllTerms}
onChange={(_, checked) => updateUserAgreements(checked)}
Expand Down
22 changes: 19 additions & 3 deletions src/components/EmailInput.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import { Mail } from 'lucide-react';
import React, { FC, useEffect, useState } from 'react';

import { InputAdornment } from '@mui/material';

import { useAuthTranslation } from '../config/i18n';
import { AUTH } from '../langs/constants';
import { emailValidator } from '../utils/validation';
import StyledTextField from './StyledTextField';

const { EMAIL_INPUT_PLACEHOLDER } = AUTH;

type Props = {
required?: boolean;
value: string;
Expand All @@ -13,16 +18,18 @@ type Props = {
setValue: (str: string) => void;
onKeyPress?: React.KeyboardEventHandler<unknown>;
shouldValidate: boolean;
autoFocus?: boolean;
};

const EmailInput: FC<Props> = ({
required = true,
required = false,
value = '',
id,
disabled = false,
setValue,
onKeyPress,
shouldValidate = true,
autoFocus = false,
}) => {
const { t } = useAuthTranslation();
const [error, setError] = useState<string | null>(null);
Expand All @@ -44,12 +51,21 @@ const EmailInput: FC<Props> = ({

return (
<StyledTextField
InputProps={{
startAdornment: (
<InputAdornment position="start">
<Mail />
</InputAdornment>
),
}}
variant="outlined"
label={t(AUTH.EMAIL_FIELD_TEXT)}
required={required}
value={value}
error={Boolean(error)}
helperText={t(error)}
placeholder={t(
`${EMAIL_INPUT_PLACEHOLDER}${required ? '_REQUIRED' : ''}`,
)}
autoFocus={autoFocus}
onChange={handleEmailOnChange}
id={id}
type="email"
Expand Down
3 changes: 1 addition & 2 deletions src/components/EnableAnalyticsForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
Typography,
} from '@mui/material';

import { MAX_CHECKBOX_LABEL_WITH_PX_SIGN_UP } from '../config/constants';
import { useAuthTranslation } from '../config/i18n';
import { SIGN_UP_SAVE_ACTIONS_ID } from '../config/selectors';
import { AUTH } from '../langs/constants';
Expand All @@ -25,7 +24,7 @@ export const EnableAnalyticsForm = ({

return (
<Tooltip title={t(SIGN_UP_SAVE_ACTIONS_TOOLTIP)} placement="right">
<FormGroup sx={{ maxWidth: `${MAX_CHECKBOX_LABEL_WITH_PX_SIGN_UP}px` }}>
<FormGroup>
<FormControlLabel
control={
<Checkbox
Expand Down
Loading

0 comments on commit 606cc7a

Please sign in to comment.