Skip to content
Snippets Groups Projects
Commit 57438beb authored by sixertoy's avatar sixertoy
Browse files

:key: ouverture de la popin de connexion depuis l'URL

- rename login-form to connexion
- fix de regles eslint
- ajout de tests unitaires/snapshots
- envoi de la requete au serveur pour la connexion
- gestion du retour des erreurs
- ajout d'une condition pour afficher le bouton de login uniquement de local/developement
parent f46c9f41
Branches
Tags
No related merge requests found
Showing
with 477 additions and 135 deletions
......@@ -3,6 +3,14 @@
semi: [2, "always"],
react/jsx-indent: [2, 2],
react/jsx-indent-props: [2, 2],
react/jsx-closing-bracket-location: [2, {
"nonEmpty": false,
"selfClosing": false
}],
"jsx-a11y/anchor-is-valid": [2, {
"components": ["Link"],
"specialLink": ["hrefLeft", "hrefRight"]
}],
import/order: [2, {
newlines-between: "always",
groups: ["builtin", "external", "parent", "sibling", "index"]
......@@ -12,12 +20,45 @@ import PropTypes from "prop-types";
import { flow, get } from "lodash";
import { Fragment, PureComponent } from "react";
import { withRouter } from "next/router";
import { Drawer } from "@material-ui/core";
import { withStyles } from "@material-ui/core/styles/";
import { Drawer, DialogContent, Dialog } from "@material-ui/core";
import LoginForm from "./connexion";
import EnSavoirPlus from "./en-savoir-plus";
import { closeCurrentOpenedRoutingPopin } from "./actions";
const styles = () => ({
dialog: {
width: "100%",
backgroundColor: "rgba(229, 220, 0, 0.5)",
},
dialogPaper: {
width: "800px",
maxWidth: "800px",
minWidth: "630px",
backgroundColor: "#FFFFFF",
},
dialogContent: {
padding: "45px 45px 0 45px",
},
});
class PopinManager extends PureComponent {
renderConnexion = (popinType) => {
const { classes } = this.props;
const showConnexion = popinType === "connection";
return (
<Dialog
open={showConnexion}
onClose={closeCurrentOpenedRoutingPopin}
classes={{ root: classes.dialog, paper: classes.dialogPaper }}>
<DialogContent classes={{ root: classes.dialogContent }}>
<LoginForm />
</DialogContent>
</Dialog>
);
}
renderEnSavoirPlus = (popinType) => {
const showEnSavoirPlus = popinType === "en-savoir-plus";
return (
......@@ -25,8 +66,7 @@ class PopinManager extends PureComponent {
anchor="bottom"
variant="temporary"
open={showEnSavoirPlus}
onClose={closeCurrentOpenedRoutingPopin}
>
onClose={closeCurrentOpenedRoutingPopin}>
<EnSavoirPlus />
</Drawer>
);
......@@ -36,12 +76,21 @@ class PopinManager extends PureComponent {
const { router } = this.props;
const pathString = "query.showPopin";
const popinType = get(router, pathString, false);
return <Fragment>{this.renderEnSavoirPlus(popinType)}</Fragment>;
return (
<Fragment>
{this.renderEnSavoirPlus(popinType)}
{this.renderConnexion(popinType)}
</Fragment>
);
}
}
PopinManager.propTypes = {
classes: PropTypes.shape().isRequired,
router: PropTypes.shape().isRequired,
};
export default flow(withRouter)(PopinManager);
export default flow(
withStyles(styles),
withRouter,
)(PopinManager);
......@@ -10,6 +10,10 @@
*/
import Router from "next/router";
export function showConnexionPopin() {
Router.push("/?showPopin=connection", "/connection");
}
export function showEnSavoirPlusPopin() {
Router.push("/?showPopin=en-savoir-plus", "/en-savoir-plus");
}
......
......@@ -11,15 +11,17 @@
*/
import Router from "next/router";
import { showEnSavoirPlusPopin } from "../routing";
import { showConnexionPopin, showEnSavoirPlusPopin } from "../routing";
const MockRouterPush = jest.fn();
jest.mock("next/router", () => ({ push: jest.fn() }));
describe("components | actions | routing", () => {
describe("teste les appels de methode du router avec les bons arguments", () => {
it("doit avoir appeler la methode push du Router", () => {
MockRouterPush.mockClear();
afterEach(() => {
Router.push.mockClear();
});
it("doit avoir appeler la methode push du Router a l'ouverture de la popin 'en savoir plus'", () => {
showEnSavoirPlusPopin();
expect(Router.push).toHaveBeenCalledTimes(1);
expect(Router.push).toHaveBeenCalledWith(
......@@ -27,5 +29,14 @@ describe("components | actions | routing", () => {
"/en-savoir-plus",
);
});
it("doit avoir appeler la methode push du Router a l'ouverture de la popin 'connection'", () => {
showConnexionPopin();
expect(Router.push).toHaveBeenCalledTimes(1);
expect(Router.push).toHaveBeenCalledWith(
"/?showPopin=connection",
"/connection",
);
});
});
});
......@@ -37,6 +37,7 @@ const styles = () => ({
class HeaderContainer extends PureComponent {
render() {
const { classes, isUserLogged } = this.props;
const showLoginButton = process.env.NODE_ENV === "development";
return (
<AppBar position="static">
<Toolbar classes={{ root: classes.toolbarRoot }}>
......@@ -55,7 +56,7 @@ class HeaderContainer extends PureComponent {
</span>
)}
</Typography>
<LoginButton />
{showLoginButton && <LoginButton />}
</Toolbar>
</AppBar>
);
......
......@@ -2,14 +2,28 @@
indent: [2, 2],
semi: [2, "always"],
react/jsx-indent: [2, 2],
react/jsx-indent-props: [2, 2]
react/jsx-indent-props: [2, 2],
max-nested-callbacks: [2, { "max": 4 }],
react/jsx-closing-bracket-location: [2, {
"nonEmpty": false,
"selfClosing": false
}],
"jsx-a11y/anchor-is-valid": [2, {
"components": ["Link"],
"specialLink": ["hrefLeft", "hrefRight"]
}],
import/order: [2, {
newlines-between: "always",
groups: ["builtin", "external", "parent", "sibling", "index"]
}]
*/
import Router from "next/router";
import PropTypes from "prop-types";
import Button from "@material-ui/core/Button";
import VPNKeyIcon from "@material-ui/icons/VpnKey";
import { withStyles } from "@material-ui/core/styles";
import { showConnexionPopin } from "../actions";
const styles = () => ({
avatarIcon: {
marginRight: "9px",
......@@ -25,13 +39,6 @@ const styles = () => ({
},
});
function handleButtonClick() {
Router.push({
pathname: "/",
query: { showLoginPopup: "1" },
});
}
function LoginButton({ classes }) {
return (
<Button
......@@ -39,8 +46,7 @@ function LoginButton({ classes }) {
color="primary"
variant="contained"
className={classes.button}
onClick={handleButtonClick}
>
onClick={showConnexionPopin}>
<VPNKeyIcon classes={{ root: classes.avatarIcon }} />
<span>leximpact&nbsp;</span>
<b>pop</b>
......
......@@ -33,7 +33,6 @@ exports[`components | app-header | index snapshot doit correspondre quand l'user
</span>
</span>
</WithStyles(Typography)>
<WithStyles(LoginButton) />
</WithStyles(Toolbar)>
</WithStyles(AppBar)>
`;
......@@ -71,7 +70,6 @@ exports[`components | app-header | index snapshot doit correspondre quand l'user
</span>
</span>
</WithStyles(Typography)>
<WithStyles(LoginButton) />
</WithStyles(Toolbar)>
</WithStyles(AppBar)>
`;
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`components | app-header | index snapshot doit correspondre au snapshot existant 1`] = `
<WithStyles(Button)
className="LoginButton-button-2"
color="primary"
onClick={[MockFunction]}
size="medium"
variant="contained"
>
<pure(VpnKeyIcon)
classes={
Object {
"root": "LoginButton-avatarIcon-1",
}
}
/>
<span>
leximpact
</span>
<b>
pop
</b>
</WithStyles(Button)>
`;
......@@ -9,13 +9,23 @@ import { createShallow } from "@material-ui/core/test-utils";
import HeaderContainer from "../index";
const CURRENT_NODE_ENV = process.env;
describe("components | app-header | index", () => {
let shallow;
beforeAll(() => {
jest.resetModules();
process.env = { ...CURRENT_NODE_ENV };
delete process.env.NODE_ENV;
const options = { dive: true };
shallow = createShallow(options);
});
afterAll(() => {
process.env = CURRENT_NODE_ENV;
});
describe("snapshot", () => {
it("doit correspondre quand l'user n'est pas connecté", () => {
const props = { isUserLogged: false };
......
/* eslint
indent: [2, 2],
semi: [2, "always"],
react/jsx-indent: [2, 2],
react/jsx-indent-props: [2, 2],
max-nested-callbacks: [2, { "max": 4 }],
react/jsx-closing-bracket-location: [2, {
"nonEmpty": false,
"selfClosing": false
}],
"jsx-a11y/anchor-is-valid": [2, {
"components": ["Link"],
"specialLink": ["hrefLeft", "hrefRight"]
}],
import/order: [2, {
newlines-between: "always",
groups: ["builtin", "external", "parent", "sibling", "index"]
}]
*/
import { createShallow } from "@material-ui/core/test-utils";
import LoginButton from "../login-button";
import { showConnexionPopin } from "../../actions/routing";
const MockButtonClickHandler = jest.fn();
jest.mock("next/router", () => ({ push: jest.fn() }));
jest.mock("../../actions/routing", () => ({
showConnexionPopin: jest.fn(),
}));
describe("components | app-header | index", () => {
let shallow = null;
beforeAll(() => {
MockButtonClickHandler.mockClear();
const options = { dive: true };
shallow = createShallow(options);
});
describe("snapshot", () => {
it("doit correspondre au snapshot existant", () => {
const props = {};
const wrapper = shallow(<LoginButton {...props} />);
expect(wrapper).toBeDefined();
expect(wrapper).toMatchSnapshot();
});
});
describe("render", () => {
it("au click sur le bouton on doit avoir appeler la methode showConnexionPopin", () => {
const props = {};
const wrapper = shallow(<LoginButton {...props} />);
wrapper.simulate("click");
expect(showConnexionPopin).toHaveBeenCalledTimes(1);
});
});
});
/* eslint
indent: [2, 2],
semi: [2, "always"],
react/jsx-indent: [2, 2],
react/jsx-indent-props: [2, 2],
react/jsx-closing-bracket-location: [2, {
"nonEmpty": false,
"selfClosing": false
}],
"jsx-a11y/anchor-is-valid": [2, {
"components": ["Link"],
"specialLink": ["hrefLeft", "hrefRight"]
}],
import/order: [2, {
newlines-between: "always",
groups: ["builtin", "external", "parent", "sibling", "index"]
}]
*/
import PropTypes from "prop-types";
import { PureComponent } from "react";
import { Typography } from "@material-ui/core";
class ConnexionFormSuccess extends PureComponent {
render() {
const { message } = this.props;
return (
<Typography>
<span>{message}</span>
</Typography>
);
}
}
ConnexionFormSuccess.propTypes = {
message: PropTypes.string.isRequired,
};
export default ConnexionFormSuccess;
......@@ -2,65 +2,39 @@
indent: [2, 2],
semi: [2, "always"],
react/jsx-indent: [2, 2],
react/jsx-indent-props: [2, 2]
react/jsx-indent-props: [2, 2],
react/jsx-closing-bracket-location: [2, {
"nonEmpty": false,
"selfClosing": false
}],
"jsx-a11y/anchor-is-valid": [2, {
"components": ["Link"],
"specialLink": ["hrefLeft", "hrefRight"]
}],
import/order: [2, {
newlines-between: "always",
groups: ["builtin", "external", "parent", "sibling", "index"]
}]
*/
import PropTypes from "prop-types";
import { PureComponent } from "react";
import { FORM_ERROR } from "final-form";
import { Form as FinalForm, Field } from "react-final-form";
import { withStyles } from "@material-ui/core/styles";
import { Avatar, Typography } from "@material-ui/core";
import VPNKeyIcon from "@material-ui/icons/VpnKey";
import { Fragment, PureComponent } from "react";
import createDecorator from "final-form-calculate";
import { withStyles } from "@material-ui/core/styles";
import { Form as FinalForm, Field } from "react-final-form";
import SubmitButton from "./submit-button";
import MentionsLegales from "./mentions-legales-text";
import EmailInput from "./email-input";
import RolesInput from "./roles-input";
import ErrorSnackbar from "./error-snackbar";
import request from "../utils/request";
import { roles } from "./config.json";
import {
getDefaultRoleFromConfig,
parseFormValuesUserEmail,
updateDomainsWhenRoleChange,
} from "./helpers";
import { roles } from "./config.json";
} from "./utils";
const DEFAULT_ROLES = { ...roles };
const DEFAULT_ROLE_OBJECT = getDefaultRoleFromConfig();
const styles = theme => ({
container: {
width: "100%",
display: "flex",
alignItems: "center",
flexDirection: "column",
},
avatar: {
width: "80px",
height: "80px",
margin: theme.spacing.unit,
backgroundColor: theme.palette.primary.main,
},
avatarIcon: {
width: "42px",
height: "auto",
},
form: {
width: "100%", // Fix IE 11 issue.
marginTop: theme.spacing.unit,
},
submit: {
marginTop: theme.spacing.unit * 3,
},
spanLighter: {
fontWeight: "lighter",
},
spanBolder: {
fontWeight: "bold",
},
});
const FORM_DECORATORS = createDecorator({
// NOTE les decorateurs permettent de changer
// la valeur d'un champ en fonction d'un autre champ
......@@ -70,46 +44,23 @@ const FORM_DECORATORS = createDecorator({
updates: { domains: updateDomainsWhenRoleChange },
});
class RequestTokenForm extends PureComponent {
constructor(props) {
super(props);
this.state = { isLoading: false };
}
handleFormSubmitFail = (error) => {
this.setState({ isLoading: false });
return { [FORM_ERROR]: error };
}
handleFormSubmitSuccess = form => () => {
this.setState({ isLoading: false });
form.reset();
}
handleFormSubmit = (formValues, form) => {
this.setState({ isLoading: true });
const email = parseFormValuesUserEmail(formValues);
return request
.post("/fake/path", { email })
.then(this.handleFormSubmitSuccess(form))
.catch(this.handleFormSubmitFail);
}
const styles = theme => ({
form: {
width: "100%", // Fix IE 11 issue.
marginTop: theme.spacing.unit,
},
});
class ConnexionForm extends PureComponent {
render() {
const { isLoading } = this.state;
const { classes, initialValues } = this.props;
const {
classes, handleFormSubmit, initialValues, isLoading,
} = this.props;
return (
<div className={classes.container}>
<Avatar className={classes.avatar}>
<VPNKeyIcon classes={{ root: classes.avatarIcon }} />
</Avatar>
<Typography component="h1" variant="h5">
<span className={classes.spanLighter}>LEXIMPACT&nbsp;</span>
<span className={classes.spanBolder}>POP</span>
</Typography>
<Fragment>
<FinalForm
onSubmit={handleFormSubmit}
initialValues={initialValues}
onSubmit={this.handleFormSubmit}
decorators={[FORM_DECORATORS]}
render={({
handleSubmit,
......@@ -134,13 +85,12 @@ class RequestTokenForm extends PureComponent {
);
}}
/>
<MentionsLegales />
</div>
</Fragment>
);
}
}
RequestTokenForm.defaultProps = {
ConnexionForm.defaultProps = {
initialValues: {
// valeurs par défaut du form
domains: DEFAULT_ROLE_OBJECT.domains,
......@@ -149,9 +99,11 @@ RequestTokenForm.defaultProps = {
},
};
RequestTokenForm.propTypes = {
ConnexionForm.propTypes = {
classes: PropTypes.shape().isRequired,
handleFormSubmit: PropTypes.func.isRequired,
initialValues: PropTypes.shape(),
isLoading: PropTypes.bool.isRequired,
};
export default withStyles(styles)(RequestTokenForm);
export default withStyles(styles)(ConnexionForm);
/* eslint
indent: [2, 2],
semi: [2, "always"],
react/jsx-indent: [2, 2,{indentLogicalExpressions: false}],
react/jsx-indent-props: [2, 2]
react/jsx-indent: [2, 2],
react/jsx-indent-props: [2, 2],
react/jsx-closing-bracket-location: [2, {
"nonEmpty": false,
"selfClosing": false
}],
"jsx-a11y/anchor-is-valid": [2, {
"components": ["Link"],
"specialLink": ["hrefLeft", "hrefRight"]
}],
import/order: [2, {
newlines-between: "always",
groups: ["builtin", "external", "parent", "sibling", "index"]
}]
*/
import { PureComponent } from "react";
import PropTypes from "prop-types";
......@@ -16,7 +28,7 @@ import {
Select,
} from "@material-ui/core";
import { validateEmailInputField } from "./helpers";
import { validateEmailInputField } from "./utils";
const styles = () => ({
formGroup: { marginTop: "28px" },
......@@ -66,8 +78,7 @@ class EmailTextInput extends PureComponent {
value={value}
inputProps={rest}
onChange={onChange}
classes={{ root: classes.selectRoot }}
>
classes={{ root: classes.selectRoot }}>
{domains.map(domainLabel => (
<MenuItem key={domainLabel} value={domainLabel}>
{domainLabel}
......@@ -100,8 +111,7 @@ class EmailTextInput extends PureComponent {
<FormLabel
focused={false}
component="legend"
classes={{ root: classes.formLabel }}
>
classes={{ root: classes.formLabel }}>
<b>Mon adresse e-mail officielle</b>
</FormLabel>
<div className={classes.fieldsContainer}>
......
/* eslint
indent: [2, 2],
semi: [2, "always"],
react/jsx-indent: [2, 2,{indentLogicalExpressions: false}],
react/jsx-indent-props: [2, 2]
react/jsx-indent: [2, 2],
react/jsx-indent-props: [2, 2],
react/jsx-closing-bracket-location: [2, {
"nonEmpty": false,
"selfClosing": false
}],
"jsx-a11y/anchor-is-valid": [2, {
"components": ["Link"],
"specialLink": ["hrefLeft", "hrefRight"]
}],
import/order: [2, {
newlines-between: "always",
groups: ["builtin", "external", "parent", "sibling", "index"]
}]
*/
import PropTypes from "prop-types";
import { IconButton, Snackbar } from "@material-ui/core";
......
/* eslint
indent: [2, 2],
semi: [2, "always"],
react/jsx-indent: [2, 2],
react/jsx-indent-props: [2, 2],
react/jsx-closing-bracket-location: [2, {
"nonEmpty": false,
"selfClosing": false
}],
"jsx-a11y/anchor-is-valid": [2, {
"components": ["Link"],
"specialLink": ["hrefLeft", "hrefRight"]
}],
import/order: [2, {
newlines-between: "always",
groups: ["builtin", "external", "parent", "sibling", "index"]
}]
*/
import PropTypes from "prop-types";
import { PureComponent } from "react";
import { FORM_ERROR } from "final-form";
import { withStyles } from "@material-ui/core/styles";
import { Avatar, Typography } from "@material-ui/core";
import VPNKeyIcon from "@material-ui/icons/VpnKey";
import request from "../utils/request";
import ConnexionForm from "./connexion-form";
import MentionsLegales from "./mentions-legales-text";
import ConnexionSuccess from "./connexion-form-success";
import { parseFormValuesUserEmail } from "./utils";
const styles = theme => ({
container: {
width: "100%",
display: "flex",
alignItems: "center",
flexDirection: "column",
},
avatar: {
width: "80px",
height: "80px",
margin: theme.spacing.unit,
backgroundColor: theme.palette.primary.main,
},
avatarIcon: {
width: "42px",
height: "auto",
},
form: {
width: "100%", // Fix IE 11 issue.
marginTop: theme.spacing.unit,
},
submit: {
marginTop: theme.spacing.unit * 3,
},
spanLighter: {
fontWeight: "lighter",
},
spanBolder: {
fontWeight: "bold",
},
});
class Connexion extends PureComponent {
constructor(props) {
super(props);
this.state = { hasBeenSubmitWithSuccess: false, isLoading: false };
}
handleFormSubmitFail = (message) => {
this.setState({ isLoading: false });
return { [FORM_ERROR]: message };
}
handleFormSubmitSuccess = (payload) => {
this.setState({ hasBeenSubmitWithSuccess: payload, isLoading: false });
return {};
}
handleFormSubmit = (formValues) => {
this.setState({ isLoading: true });
const email = parseFormValuesUserEmail(formValues);
return request
.post("/auth/login", { email })
.then(this.handleFormSubmitSuccess)
.catch(this.handleFormSubmitFail);
}
renderConnexionSuccess = () => {
const { hasBeenSubmitWithSuccess } = this.state;
if (!hasBeenSubmitWithSuccess) return null;
return <ConnexionSuccess message={hasBeenSubmitWithSuccess} />;
}
renderConnexionForm = () => {
const { hasBeenSubmitWithSuccess, isLoading } = this.state;
if (hasBeenSubmitWithSuccess) return null;
return (
<ConnexionForm
isLoading={isLoading}
handleFormSubmit={this.handleFormSubmit}
/>
);
}
render() {
const { classes } = this.props;
return (
<div className={classes.container}>
<Avatar className={classes.avatar}>
<VPNKeyIcon classes={{ root: classes.avatarIcon }} />
</Avatar>
<Typography component="h1" variant="h5">
<span className={classes.spanLighter}>LEXIMPACT&nbsp;</span>
<span className={classes.spanBolder}>POP</span>
</Typography>
{this.renderConnexionForm()}
{this.renderConnexionSuccess()}
<MentionsLegales />
</div>
);
}
}
Connexion.propTypes = {
classes: PropTypes.shape().isRequired,
};
export default withStyles(styles)(Connexion);
......@@ -3,9 +3,17 @@
semi: [2, "always"],
react/jsx-indent: [2, 2],
react/jsx-indent-props: [2, 2],
react/jsx-closing-bracket-location: [2, {
"nonEmpty": false,
"selfClosing": false
}],
"jsx-a11y/anchor-is-valid": [2, {
"components": ["Link"],
"specialLink": ["hrefLeft", "hrefRight"]
}],
import/order: [2, {
newlines-between: "always",
groups: ["builtin", "external", "parent", "sibling", "index"]
}]
*/
import PropTypes from "prop-types";
......
/* eslint
indent: [2, 2],
semi: [2, "always"],
react/jsx-indent: [2, 2,{indentLogicalExpressions: false}],
react/jsx-indent-props: [2, 2]
react/jsx-indent: [2, 2],
react/jsx-indent-props: [2, 2],
react/jsx-closing-bracket-location: [2, {
"nonEmpty": false,
"selfClosing": false
}],
"jsx-a11y/anchor-is-valid": [2, {
"components": ["Link"],
"specialLink": ["hrefLeft", "hrefRight"]
}],
import/order: [2, {
newlines-between: "always",
groups: ["builtin", "external", "parent", "sibling", "index"]
}]
*/
import { Field } from "react-final-form";
import { PureComponent } from "react";
......@@ -14,8 +26,6 @@ import RadioGroup from "@material-ui/core/RadioGroup";
import FormControlLabel from "@material-ui/core/FormControlLabel";
import { withStyles } from "@material-ui/core/styles";
import { roles as AVAILABLE_ROLES } from "./config.json";
const styles = () => ({
formLegend: {
flex: "0",
......@@ -74,8 +84,7 @@ class RolesInput extends PureComponent {
<FormControl
required
component="div"
classes={{ root: classes.formControl }}
>
classes={{ root: classes.formControl }}>
<FormLabel
required
focused={false}
......@@ -83,8 +92,7 @@ class RolesInput extends PureComponent {
classes={{
root: classes.formLegend,
asterisk: classes.formLegendAsterisk,
}}
>
}}>
<b>Je suis</b>
</FormLabel>
<Field
......@@ -98,8 +106,7 @@ class RolesInput extends PureComponent {
aria-label={input.name}
onChange={input.onChange}
defaultValue={defaultValue}
classes={{ root: classes.radioGroup }}
>
classes={{ root: classes.radioGroup }}>
{Object.keys(roles).map(this.renderRadioItem)}
</RadioGroup>
)}
......
......@@ -6,6 +6,14 @@
react/jsx-closing-bracket-location: [2, {
"nonEmpty": false,
"selfClosing": false
}],
"jsx-a11y/anchor-is-valid": [2, {
"components": ["Link"],
"specialLink": ["hrefLeft", "hrefRight"]
}],
import/order: [2, {
newlines-between: "always",
groups: ["builtin", "external", "parent", "sibling", "index"]
}]
*/
import { PureComponent } from "react";
......
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`components | login-form | email-input snapshot doit correspondre avec les props requises 1`] = `
exports[`components | connexion | email-input snapshot doit correspondre avec les props requises 1`] = `
<EmailTextInput
classes={
Object {
......
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`components | connexion | index snapshot doit correspondre avec les props requises 1`] = `
<Connexion
classes={
Object {
"avatar": "Connexion-avatar-2",
"avatarIcon": "Connexion-avatarIcon-3",
"container": "Connexion-container-1",
"form": "Connexion-form-4",
"spanBolder": "Connexion-spanBolder-7",
"spanLighter": "Connexion-spanLighter-6",
"submit": "Connexion-submit-5",
}
}
/>
`;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment