Add some mocha/chai tests

This commit is contained in:
2020-11-14 20:02:00 -06:00
parent 313ef146dd
commit ddf1a833d6
9 changed files with 21 additions and 365 deletions

View File

@@ -3,7 +3,8 @@
"env": {
"node": true,
"browser": false,
"es6": true
"es6": true,
"mocha": true
},
"parserOptions": {
"ecmaVersion": 2018

View File

@@ -52,7 +52,6 @@ const login = async (req, res, next) => {
try {
user = await users.getByEmail(req.body.email);
} catch (error) {
console.log(error);
return next(error, null);
}

View File

@@ -4,6 +4,7 @@
"description": "",
"main": "app.js",
"dependencies": {
"aws-sdk": "^2.792.0",
"bcryptjs": "^2.4.3",
"express": "^4.17.1",
"jsonwebtoken": "^8.5.1",
@@ -12,13 +13,17 @@
"shortid": "^2.2.15"
},
"devDependencies": {
"chai": "^4.2.0",
"chai-http": "^4.3.0",
"eslint": "^7.12.1",
"eslint-config-prettier": "^6.15.0",
"faker": "^5.1.0",
"mocha": "^8.2.1",
"prettier": "^2.1.2"
},
"scripts": {
"pretest": "eslint --ignore-path ../.gitignore .",
"test": "echo \"Error: no test specified\" && exit 1",
"test": "mocha",
"format": "prettier --write \"**/*.{js,json,md,yml}\""
},
"author": "",

View File

@@ -15,11 +15,12 @@
},
"dependencies": {
"gatsby": "^2.25.3",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-router-dom": "^5.1.2",
"js-cookie": "^2.2.1",
"moment": "^2.24.0"
"moment": "^2.24.0",
"react": "^16.12.0",
"react-bootstrap": "^1.4.0",
"react-dom": "^16.12.0",
"react-router-dom": "^5.1.2"
},
"devDependencies": {
"eslint": "^7.12.1",

View File

@@ -1,284 +0,0 @@
import React, { Component } from "react";
import { Link } from "gatsby";
import styles from "./Auth.module.css";
import { userRegister, userLogin, userGet, saveSession } from "../../utils";
class Auth extends Component {
constructor(props) {
super(props);
const pathName = window.location.pathname.replace("/", "");
this.state = {};
this.state.state = pathName;
this.state.loading = true;
this.state.error = null;
this.state.formEmail = "";
this.state.formPassword = "";
// Bindings
this.handleFormInput = this.handleFormInput.bind(this);
this.handleFormSubmit = this.handleFormSubmit.bind(this);
this.handleFormTypeChange = this.handleFormTypeChange.bind(this);
}
/**
* Component did mount
*/
componentDidMount() {
this.setState({
loading: false,
});
// Clear query params
const url = document.location.href;
window.history.pushState({}, "", url.split("?")[0]);
}
/**
* Handles a form change
*/
handleFormTypeChange(type) {
this.setState({ state: type }, () => {
this.props.history.push(`/${type}`);
});
}
/**
* Handle text changes within form fields
*/
handleFormInput(field, value) {
value = value.trim();
const nextState = {};
nextState[field] = value;
this.setState(Object.assign(this.state, nextState));
}
/**
* Handles form submission
* @param {object} evt
*/
async handleFormSubmit(evt) {
evt.preventDefault();
this.setState({ loading: true });
// Validate email
if (!this.state.formEmail) {
return this.setState({
loading: false,
formError: "email is required",
});
}
// Validate password
if (!this.state.formPassword) {
return this.setState({
loading: false,
formError: "password is required",
});
}
let token;
try {
if (this.state.state === "register") {
token = await userRegister(
this.state.formEmail,
this.state.formPassword
);
} else {
token = await userLogin(
this.state.formEmail,
this.state.formPassword
);
}
} catch (error) {
console.log(error);
if (error.message) {
this.setState({
formError: error.message,
loading: false,
});
} else {
this.setState({
formError:
"Sorry, something unknown went wrong. Please try again.",
loading: false,
});
}
return;
}
// Fetch user record and set session in cookie
let user = await userGet(token.token);
user = user.user;
saveSession(user.id, user.email, token.token);
window.location.replace("/");
}
render() {
return (
<div className={`${styles.container} animateFadeIn`}>
<div className={styles.containerInner}>
{/* Logo */}
<Link to="/" className={`${styles.logo}`}>
<img
draggable="false"
src={"./fullstack-app-title.png"}
alt="serverless-fullstack-application"
/>
</Link>
{/* Loading */}
{this.state.loading && <div>loading, man!</div>}
{/* Registration Form */}
{!this.state.loading && (
<div className={styles.formType}>
<div
className={`${styles.formTypeRegister}
${
this.state.state === "register" ? styles.formTypeActive : ""
}`}
onClick={(e) => {
this.handleFormTypeChange("register");
}}
>
Register
</div>
<div
className={`${styles.formTypeSignIn}
${this.state.state === "login" ? styles.formTypeActive : ""}`}
onClick={(e) => {
this.handleFormTypeChange("login");
}}
>
Sign-In
</div>
</div>
)}
{this.state.state === "register" && !this.state.loading && (
<div className={styles.containerRegister}>
<form
className={styles.form}
onSubmit={this.handleFormSubmit}
>
<div className={styles.formField}>
<label className={styles.formLabel}>
email
</label>
<input
type="text"
placeholder="yours@example.com"
className={styles.formInput}
value={this.state.formEmail}
onChange={(e) => {
this.handleFormInput(
"formEmail",
e.target.value
);
}}
/>
</div>
<div className={styles.formField}>
<label className={styles.formLabel}>
password
</label>
<input
type="password"
placeholder="your password"
className={styles.formInput}
value={this.state.formPassword}
onChange={(e) => {
this.handleFormInput(
"formPassword",
e.target.value
);
}}
/>
</div>
{this.state.formError && (
<div className={styles.formError}>
{this.state.formError}
</div>
)}
<input
className={`buttonPrimaryLarge ${styles.formButton}`}
type="submit"
value="Register"
/>
</form>
</div>
)}
{this.state.state === "login" && !this.state.loading && (
<div className={styles.containerSignIn}>
<form
className={styles.form}
onSubmit={this.handleFormSubmit}
>
<div className={styles.formField}>
<label className={styles.formLabel}>
email
</label>
<input
type="text"
placeholder="yours@example.com"
className={styles.formInput}
value={this.state.formEmail}
onChange={(e) => {
this.handleFormInput(
"formEmail",
e.target.value
);
}}
/>
</div>
<div className={styles.formField}>
<label className={styles.formLabel}>
password
</label>
<input
type="password"
placeholder="your password"
className={styles.formInput}
value={this.state.formPassword}
onChange={(e) => {
this.handleFormInput(
"formPassword",
e.target.value
);
}}
/>
</div>
{this.state.formError && (
<div className={styles.formError}>
{this.state.formError}
</div>
)}
<input
className={`buttonPrimaryLarge ${styles.formButton}`}
type="submit"
value="Sign In"
/>
</form>
</div>
)}
</div>
</div>
);
}
}
export default Auth;

View File

@@ -1,69 +0,0 @@
import React, { Component } from "react";
import { withRouter } from "react-router-dom";
import styles from "./Dashboard.module.css";
import { getSession, deleteSession } from "../../utils";
class Dashboard extends Component {
constructor(props) {
super(props);
this.state = {};
// Bindings
this.logout = this.logout.bind(this);
}
async componentDidMount() {
const userSession = getSession();
this.setState({
session: userSession,
});
}
/**
* Log user out by clearing cookie and redirecting
*/
logout() {
deleteSession();
this.props.history.push(`/`);
}
render() {
return (
<div className={`${styles.container} animateFadeIn`}>
<div className={styles.containerInner}>
{/* Navigation */}
<div className={styles.navigationContainer}>
<div className={`link`}>
{this.state.session
? this.state.session.userEmail
: ""}
</div>
<div className={`link`} onClick={this.logout}>
logout
</div>
</div>
{/* Content */}
<div className={`${styles.contentContainer}`}>
<div className={`${styles.artwork} animateFlicker`}>
<img
draggable="false"
src={"./fullstack-app-artwork.png"}
alt="serverless-fullstack-application"
/>
</div>
<div className={`${styles.welcomeMessage}`}>
Welcome to your serverless fullstack dashboard...
</div>
</div>
</div>
</div>
);
}
}
export default withRouter(Dashboard);

View File

@@ -1,11 +1,14 @@
import React from "react";
import Auth from "../components/Auth/Auth";
import { Container, Row, Col } from "react-bootstrap";
export default function Home() {
return (
<div>
<Container>
<Row>
<Col>
<p>Hello world!</p>
<Auth />
</div>
</Col>
</Row>
</Container>
);
}