From 822e2af8fdb6d5ee7fea6b5367836e36249a686d Mon Sep 17 00:00:00 2001 From: Jason Hang Date: Wed, 28 Sep 2016 17:04:01 -0400 Subject: [PATCH 01/14] Conversion from Angular to React. TODO: Removed Traces of Angular, Fix Redux Auth Tests. --- generated/.babelrc | 9 +- generated/.eslintrc.json | 6 +- generated/client/src/api/auth/index.js | 31 +++++ generated/client/src/api/index.js | 1 + generated/client/src/app.js | 23 ++++ .../client/src/common/AuthForm/AuthForm.js | 81 ++++++++++++ generated/client/src/common/AuthForm/index.js | 1 + generated/client/src/common/Logo/Logo.js | 14 +++ generated/client/src/common/Logo/_Logo.scss | 8 ++ generated/client/src/common/Logo/index.js | 1 + .../client/src/common/NotFound/NotFound.js | 14 +++ generated/client/src/common/NotFound/index.js | 1 + generated/client/src/common/index.js | 3 + .../client/src/components/About/About.js | 30 +++++ .../client/src/components/About/_About.scss | 35 ++++++ .../client/src/components/About/index.js | 1 + generated/client/src/components/Docs/Docs.js | 14 +++ .../client/src/components/Docs/_Docs.scss | 5 + generated/client/src/components/Docs/index.js | 1 + generated/client/src/components/Home/Home.js | 17 +++ .../client/src/components/Home/_Home.scss | 9 ++ generated/client/src/components/Home/index.js | 1 + .../src/components/MembersOnly/MembersOnly.js | 14 +++ .../components/MembersOnly/_MembersOnly.scss | 3 + .../src/components/MembersOnly/index.js | 1 + .../client/src/components/Navbar/Navbar.js | 94 ++++++++++++++ .../client/src/components/Navbar/_Navbar.scss | 33 +++++ .../client/src/components/Navbar/index.js | 1 + generated/client/src/components/index.js | 5 + .../client/src/containers/Layout/Layout.js | 32 +++++ .../client/src/containers/Layout/_Layout.scss | 9 ++ .../client/src/containers/Layout/index.js | 1 + .../client/src/containers/Login/Login.js | 30 +++++ .../client/src/containers/Login/index.js | 1 + .../client/src/containers/Signup/Signup.js | 29 +++++ .../client/src/containers/Signup/index.js | 1 + generated/client/src/containers/index.js | 3 + generated/client/src/redux/configureStore.js | 28 +++++ .../client/src/redux/middleware/promise.js | 29 +++++ .../client/src/redux/modules/auth/index.js | 118 ++++++++++++++++++ .../client/src/redux/modules/auth/spec.js | 60 +++++++++ .../src/redux/modules/auth/tests/index.js | 9 ++ .../src/redux/modules/auth/tests/isLoaded.js | 21 ++++ .../src/redux/modules/auth/tests/load.js | 64 ++++++++++ .../redux/modules/auth/tests/loadActions.js | 71 +++++++++++ .../src/redux/modules/auth/tests/login.js | 66 ++++++++++ .../redux/modules/auth/tests/loginActions.js | 71 +++++++++++ .../src/redux/modules/auth/tests/logout.js | 60 +++++++++ .../redux/modules/auth/tests/logoutActions.js | 72 +++++++++++ .../src/redux/modules/auth/tests/signup.js | 64 ++++++++++ .../redux/modules/auth/tests/signupActions.js | 71 +++++++++++ .../client/src/resources/FullstackPics.js | 32 +++++ .../client/src/resources/RandomGreetings.js | 22 ++++ generated/client/src/routes.js | 83 ++++++++++++ generated/client/src/utils/index.js | 8 ++ generated/package.json | 42 ++++++- generated/server/app/configure/index.js | 1 + .../app/configure/webpack-middleware.js | 19 +++ generated/server/app/views/index.html | 14 +-- generated/webpack.dev.config.js | 57 +++++++++ generated/webpack.prod.config.js | 86 +++++++++++++ 61 files changed, 1715 insertions(+), 16 deletions(-) create mode 100644 generated/client/src/api/auth/index.js create mode 100644 generated/client/src/api/index.js create mode 100644 generated/client/src/app.js create mode 100644 generated/client/src/common/AuthForm/AuthForm.js create mode 100644 generated/client/src/common/AuthForm/index.js create mode 100644 generated/client/src/common/Logo/Logo.js create mode 100644 generated/client/src/common/Logo/_Logo.scss create mode 100644 generated/client/src/common/Logo/index.js create mode 100644 generated/client/src/common/NotFound/NotFound.js create mode 100644 generated/client/src/common/NotFound/index.js create mode 100644 generated/client/src/common/index.js create mode 100644 generated/client/src/components/About/About.js create mode 100644 generated/client/src/components/About/_About.scss create mode 100644 generated/client/src/components/About/index.js create mode 100644 generated/client/src/components/Docs/Docs.js create mode 100644 generated/client/src/components/Docs/_Docs.scss create mode 100644 generated/client/src/components/Docs/index.js create mode 100644 generated/client/src/components/Home/Home.js create mode 100644 generated/client/src/components/Home/_Home.scss create mode 100644 generated/client/src/components/Home/index.js create mode 100644 generated/client/src/components/MembersOnly/MembersOnly.js create mode 100644 generated/client/src/components/MembersOnly/_MembersOnly.scss create mode 100644 generated/client/src/components/MembersOnly/index.js create mode 100644 generated/client/src/components/Navbar/Navbar.js create mode 100644 generated/client/src/components/Navbar/_Navbar.scss create mode 100644 generated/client/src/components/Navbar/index.js create mode 100644 generated/client/src/components/index.js create mode 100644 generated/client/src/containers/Layout/Layout.js create mode 100644 generated/client/src/containers/Layout/_Layout.scss create mode 100644 generated/client/src/containers/Layout/index.js create mode 100644 generated/client/src/containers/Login/Login.js create mode 100644 generated/client/src/containers/Login/index.js create mode 100644 generated/client/src/containers/Signup/Signup.js create mode 100644 generated/client/src/containers/Signup/index.js create mode 100644 generated/client/src/containers/index.js create mode 100644 generated/client/src/redux/configureStore.js create mode 100644 generated/client/src/redux/middleware/promise.js create mode 100644 generated/client/src/redux/modules/auth/index.js create mode 100644 generated/client/src/redux/modules/auth/spec.js create mode 100644 generated/client/src/redux/modules/auth/tests/index.js create mode 100644 generated/client/src/redux/modules/auth/tests/isLoaded.js create mode 100644 generated/client/src/redux/modules/auth/tests/load.js create mode 100644 generated/client/src/redux/modules/auth/tests/loadActions.js create mode 100644 generated/client/src/redux/modules/auth/tests/login.js create mode 100644 generated/client/src/redux/modules/auth/tests/loginActions.js create mode 100644 generated/client/src/redux/modules/auth/tests/logout.js create mode 100644 generated/client/src/redux/modules/auth/tests/logoutActions.js create mode 100644 generated/client/src/redux/modules/auth/tests/signup.js create mode 100644 generated/client/src/redux/modules/auth/tests/signupActions.js create mode 100644 generated/client/src/resources/FullstackPics.js create mode 100644 generated/client/src/resources/RandomGreetings.js create mode 100644 generated/client/src/routes.js create mode 100644 generated/client/src/utils/index.js create mode 100644 generated/server/app/configure/webpack-middleware.js create mode 100644 generated/webpack.dev.config.js create mode 100644 generated/webpack.prod.config.js diff --git a/generated/.babelrc b/generated/.babelrc index c13c5f6..1e4e461 100644 --- a/generated/.babelrc +++ b/generated/.babelrc @@ -1,3 +1,10 @@ { - "presets": ["es2015"] + "presets": ["es2015", "react", "stage-1", "stage-2"], + "env": { + "development": { + "presets": [ + "react-hmre" + ] + } + } } diff --git a/generated/.eslintrc.json b/generated/.eslintrc.json index 2158099..9086937 100644 --- a/generated/.eslintrc.json +++ b/generated/.eslintrc.json @@ -2,6 +2,9 @@ { "root": true, "extends": "fullstack", // from the `eslint-config-fullstack` npm module, + "parserOptions": { + "sourceType": "module" + }, "env": { "es6": true, "node": false, @@ -13,7 +16,8 @@ "rules": { "global-require": 0, // 0 = off, 1 = warn (yellow), 2 = error (red) "camelcase": 0, - "no-debugger": 1 + "no-debugger": 1, + "no-unused-expressions": 1, // add more rules here to override the fullstack config } } diff --git a/generated/client/src/api/auth/index.js b/generated/client/src/api/auth/index.js new file mode 100644 index 0000000..019e2ef --- /dev/null +++ b/generated/client/src/api/auth/index.js @@ -0,0 +1,31 @@ +'use strict'; + +import axios from 'axios'; +import { parseJSON, parseData } from '../../utils'; + +const BASE_URL = process.env.URL || 'http://localhost:8080'; + +export const fetchSession = () => { + return axios.get(`${BASE_URL}/session`).then(parseData); +} + +export const trySignup = (credentials) => { + return axios.post(`${BASE_URL}/signup`, credentials); +} + +export const tryLogin = (credentials) => { + return axios.post(`${BASE_URL}/login`, credentials); +} + +export const tryLogout = () => { + return axios.get(`${BASE_URL}/logout`); +} + +const auth = { + fetchSession, + trySignup, + tryLogin, + tryLogout +} + +export default auth; diff --git a/generated/client/src/api/index.js b/generated/client/src/api/index.js new file mode 100644 index 0000000..c6e4055 --- /dev/null +++ b/generated/client/src/api/index.js @@ -0,0 +1 @@ +export auth from './auth'; diff --git a/generated/client/src/app.js b/generated/client/src/app.js new file mode 100644 index 0000000..fdf5796 --- /dev/null +++ b/generated/client/src/app.js @@ -0,0 +1,23 @@ +'use strict'; + +import React from 'react'; +import { render } from 'react-dom'; +import { Provider } from 'react-redux'; +import { Router, browserHistory } from 'react-router'; +import { syncHistoryWithStore } from 'react-router-redux'; +import getRoutes from './routes'; +import configureStore from './redux/configureStore'; + +const store = configureStore(browserHistory); +const history = syncHistoryWithStore(browserHistory, store); + +const component = ( + +); + +render( + + {component} + , + document.getElementById('app') +); diff --git a/generated/client/src/common/AuthForm/AuthForm.js b/generated/client/src/common/AuthForm/AuthForm.js new file mode 100644 index 0000000..4f5b6c7 --- /dev/null +++ b/generated/client/src/common/AuthForm/AuthForm.js @@ -0,0 +1,81 @@ +'use strict'; + +import React, { Component, PropTypes } from 'react' +import { + FormGroup, + FormControl, + ControlLabel, + HelpBlock, + Button, + Row, + Col +} from 'react-bootstrap' + +export default class AuthForm extends Component { + + static propTypes = { + buttonLabel: PropTypes.string, + buttonStyle: PropTypes.string, + onSubmit: PropTypes.func + } + + static defaultProps = { + buttonStyle: 'default', + buttonLabel: 'Submit' + } + + constructor (props) { + super(props) + this.state = { + form: { + email: '', + password: '' + } + } + } + + handleSubmit = (e) => { + e.preventDefault() + this.props.onSubmit(this.state.form) + const newState = {...this.state} + newState.form = { email: '', password: '' } + this.setState(newState) + } + + handleChange = (e, field) => { + const newState = {...this.state} + newState.form[field] = e.target.value + this.setState(newState) + } + + render () { + const { form } = this.state + const { buttonLabel, buttonStyle } = this.props + + return ( + +
+ + Email Address + this.handleChange(e, 'email')} + /> + + + Password + this.handleChange(e, 'password')} + /> + + +
+ + ) + } +} diff --git a/generated/client/src/common/AuthForm/index.js b/generated/client/src/common/AuthForm/index.js new file mode 100644 index 0000000..78e48ec --- /dev/null +++ b/generated/client/src/common/AuthForm/index.js @@ -0,0 +1 @@ +export default from './AuthForm'; diff --git a/generated/client/src/common/Logo/Logo.js b/generated/client/src/common/Logo/Logo.js new file mode 100644 index 0000000..a264216 --- /dev/null +++ b/generated/client/src/common/Logo/Logo.js @@ -0,0 +1,14 @@ +'use strict'; + +import React, { PropTypes } from 'react'; +import './_Logo'; + +const Logo = (props) => { + return ( +
+ +
+ ) +} + +export default Logo diff --git a/generated/client/src/common/Logo/_Logo.scss b/generated/client/src/common/Logo/_Logo.scss new file mode 100644 index 0000000..a34beaa --- /dev/null +++ b/generated/client/src/common/Logo/_Logo.scss @@ -0,0 +1,8 @@ +.logo { + + img { + display: block; + width: 100%; + } + +} diff --git a/generated/client/src/common/Logo/index.js b/generated/client/src/common/Logo/index.js new file mode 100644 index 0000000..0a77052 --- /dev/null +++ b/generated/client/src/common/Logo/index.js @@ -0,0 +1 @@ +export default from './Logo'; diff --git a/generated/client/src/common/NotFound/NotFound.js b/generated/client/src/common/NotFound/NotFound.js new file mode 100644 index 0000000..5c10092 --- /dev/null +++ b/generated/client/src/common/NotFound/NotFound.js @@ -0,0 +1,14 @@ +'use strict'; + +import React from 'react' + +const NotFound = (props) => { + return ( +
+

404

+

Page Not Found

+
+ ) +} + +export default NotFound diff --git a/generated/client/src/common/NotFound/index.js b/generated/client/src/common/NotFound/index.js new file mode 100644 index 0000000..50068c5 --- /dev/null +++ b/generated/client/src/common/NotFound/index.js @@ -0,0 +1 @@ +export default from './NotFound'; diff --git a/generated/client/src/common/index.js b/generated/client/src/common/index.js new file mode 100644 index 0000000..26e8d39 --- /dev/null +++ b/generated/client/src/common/index.js @@ -0,0 +1,3 @@ +export AuthForm from './AuthForm'; +export Logo from './Logo'; +export NotFound from './NotFound'; diff --git a/generated/client/src/components/About/About.js b/generated/client/src/components/About/About.js new file mode 100644 index 0000000..bad8362 --- /dev/null +++ b/generated/client/src/components/About/About.js @@ -0,0 +1,30 @@ +'use strict'; + +import React from 'react'; +import { Row, Col, Carousel } from 'react-bootstrap'; +import FullstackPics from '../../resources/FullstackPics'; +import './_About'; + +const About = (props) => { + return ( +
+

+ This website--the very one at which you currently gaze--was created by a basic scaffolding + concocted at Fullstack Academy. Here are some of the people who make it all very real: +

+ + { + FullstackPics.map((pic, i) => { + return ( + + + + ) + }) + } + +
+ ) +} + +export default About; diff --git a/generated/client/src/components/About/_About.scss b/generated/client/src/components/About/_About.scss new file mode 100644 index 0000000..f3741c7 --- /dev/null +++ b/generated/client/src/components/About/_About.scss @@ -0,0 +1,35 @@ +#about { + + text-align: center; + + p { + width: 40%; + margin: 0 auto; + text-align: justify; + font-size: 22px; + font-weight: 300; + float: left; + } + + .carousel { + float: right; + width: 55%; + overflow: hidden; + margin: 0 auto; + + .carousel-inner { + height: 500px !important; + + img { + max-width: 100%; + max-height: 500px; + display: block; + margin: 0 auto; + } + } + } + + .carousel-control.left, .carousel-control.right { + background-image: none; + } +} diff --git a/generated/client/src/components/About/index.js b/generated/client/src/components/About/index.js new file mode 100644 index 0000000..a1afdc8 --- /dev/null +++ b/generated/client/src/components/About/index.js @@ -0,0 +1 @@ +export default from './About'; diff --git a/generated/client/src/components/Docs/Docs.js b/generated/client/src/components/Docs/Docs.js new file mode 100644 index 0000000..cc1116b --- /dev/null +++ b/generated/client/src/components/Docs/Docs.js @@ -0,0 +1,14 @@ +'use strict'; + +import React from 'react'; +import './_Docs'; + +const Docs = (props) => { + return ( +
+

Documentation can be found in the project's Github wiki.

+
+ ) +} + +export default Docs; diff --git a/generated/client/src/components/Docs/_Docs.scss b/generated/client/src/components/Docs/_Docs.scss new file mode 100644 index 0000000..d6a2307 --- /dev/null +++ b/generated/client/src/components/Docs/_Docs.scss @@ -0,0 +1,5 @@ +#docs { + + text-align: center; + +} diff --git a/generated/client/src/components/Docs/index.js b/generated/client/src/components/Docs/index.js new file mode 100644 index 0000000..1b243fa --- /dev/null +++ b/generated/client/src/components/Docs/index.js @@ -0,0 +1 @@ +export default from './Docs'; diff --git a/generated/client/src/components/Home/Home.js b/generated/client/src/components/Home/Home.js new file mode 100644 index 0000000..217f0db --- /dev/null +++ b/generated/client/src/components/Home/Home.js @@ -0,0 +1,17 @@ +'use strict'; + +import React from 'react'; +import Logo from '../../common/Logo'; +import getRandomGreeting from '../../resources/RandomGreetings'; +import './_Home'; + +const Home = (props) => { + return ( +
+ +

{getRandomGreeting()}

+
+ ) +} + +export default Home; diff --git a/generated/client/src/components/Home/_Home.scss b/generated/client/src/components/Home/_Home.scss new file mode 100644 index 0000000..067de55 --- /dev/null +++ b/generated/client/src/components/Home/_Home.scss @@ -0,0 +1,9 @@ +#home { + + text-align: center; + + .logo { + width: 150px; + margin: 0 auto; + } +} diff --git a/generated/client/src/components/Home/index.js b/generated/client/src/components/Home/index.js new file mode 100644 index 0000000..f6e9bae --- /dev/null +++ b/generated/client/src/components/Home/index.js @@ -0,0 +1 @@ +export default from './Home'; diff --git a/generated/client/src/components/MembersOnly/MembersOnly.js b/generated/client/src/components/MembersOnly/MembersOnly.js new file mode 100644 index 0000000..a8a059a --- /dev/null +++ b/generated/client/src/components/MembersOnly/MembersOnly.js @@ -0,0 +1,14 @@ +'use strict'; + +import React from 'react'; +import './_MembersOnly'; + +const MembersOnly = (props) => { + return ( +
+

Members Only Area

+
+ ) +} + +export default MembersOnly; diff --git a/generated/client/src/components/MembersOnly/_MembersOnly.scss b/generated/client/src/components/MembersOnly/_MembersOnly.scss new file mode 100644 index 0000000..0472d54 --- /dev/null +++ b/generated/client/src/components/MembersOnly/_MembersOnly.scss @@ -0,0 +1,3 @@ +#members-only { + text-align: center; +} diff --git a/generated/client/src/components/MembersOnly/index.js b/generated/client/src/components/MembersOnly/index.js new file mode 100644 index 0000000..1cf7700 --- /dev/null +++ b/generated/client/src/components/MembersOnly/index.js @@ -0,0 +1 @@ +export default from './MembersOnly'; diff --git a/generated/client/src/components/Navbar/Navbar.js b/generated/client/src/components/Navbar/Navbar.js new file mode 100644 index 0000000..fa5bf0b --- /dev/null +++ b/generated/client/src/components/Navbar/Navbar.js @@ -0,0 +1,94 @@ +'use strict'; + +import React, { PropTypes } from 'react'; +import { IndexLink, Link } from 'react-router'; +import { push } from 'react-router-redux'; +import { Navbar, Nav, NavItem, Button } from 'react-bootstrap'; +import { LinkContainer, IndexLinkContainer } from 'react-router-bootstrap'; +import { logout } from '../../redux/modules/auth'; +import Logo from '../../common/Logo'; +import './_Navbar'; + +const NAV_ITEMS = [ + { label: 'Home', path: '/' }, + { label: 'About', path: 'about' }, + { label: 'Documentation', path: 'docs' }, + { label: 'Members Only', path: 'membersOnly', auth: true } +] + +const renderNavItems = (user) => { + return ( + + ) +} + +const renderAuthNavItems = (user, dispatch) => { + + function handleLogout () { + dispatch(logout()).then(() => dispatch(push('/login'))) + } + + if (user) { + return ( + + ) + } else { + return ( + + ) + } +} + +const NavBar = ({ user, dispatch }) => { + return ( + + + + + + + {renderNavItems(user)} + {renderAuthNavItems(user, dispatch)} + + ) +} + +NavBar.propTypes = { + user: PropTypes.object, + dispatch: PropTypes.func +} + +export default NavBar; diff --git a/generated/client/src/components/Navbar/_Navbar.scss b/generated/client/src/components/Navbar/_Navbar.scss new file mode 100644 index 0000000..1cad442 --- /dev/null +++ b/generated/client/src/components/Navbar/_Navbar.scss @@ -0,0 +1,33 @@ +$red: #ed1b24; +$inverse: #222; +$default: #efefef; + +.navbar { + background-color: white; + + .logo { + margin-top: 12px; + margin-right: 20px; + width: 30px; + } + + .navbar-nav>.active>a, + .navbar-nav>li>a { + padding: 0; + margin: 15px; + } + + .navbar-nav>.active>a, + .navbar-nav>.active>a:focus, + .navbar-nav>.active>a:hover, + .navbar-nav>li>a:focus, + .navbar-nav>li>a:hover { + color: $red; + background-color: transparent; + } + + .navbar-nav>.active>a { + background-color: transparent; + } + +} diff --git a/generated/client/src/components/Navbar/index.js b/generated/client/src/components/Navbar/index.js new file mode 100644 index 0000000..802fb9f --- /dev/null +++ b/generated/client/src/components/Navbar/index.js @@ -0,0 +1 @@ +export default from './Navbar'; diff --git a/generated/client/src/components/index.js b/generated/client/src/components/index.js new file mode 100644 index 0000000..fb53ec1 --- /dev/null +++ b/generated/client/src/components/index.js @@ -0,0 +1,5 @@ +export About from './About'; +export Docs from './Docs'; +export Home from './Home'; +export MembersOnly from './MembersOnly'; + diff --git a/generated/client/src/containers/Layout/Layout.js b/generated/client/src/containers/Layout/Layout.js new file mode 100644 index 0000000..2614c19 --- /dev/null +++ b/generated/client/src/containers/Layout/Layout.js @@ -0,0 +1,32 @@ +'use strict'; + +import React, { Component, PropTypes } from 'react'; +import { connect } from 'react-redux'; +import Navbar from '../../components/Navbar'; +import './_Layout'; + +class Layout extends Component { + + static propTypes = { + children: PropTypes.object, + user: PropTypes.object, + dispatch: PropTypes.func + } + + render () { + const { children, user, dispatch } = this.props + + return ( +
+ +
+ {children} +
+
+ ) + } +} + +const mapStateToProps = (state) => ({ user: state.auth.user }); + +export default connect(mapStateToProps)(Layout); diff --git a/generated/client/src/containers/Layout/_Layout.scss b/generated/client/src/containers/Layout/_Layout.scss new file mode 100644 index 0000000..b939552 --- /dev/null +++ b/generated/client/src/containers/Layout/_Layout.scss @@ -0,0 +1,9 @@ +body { + font-family: 'Roboto', 'Helvetica Neue', Helvetica, Arial, sans-serif; +} + +#main { + padding-top: 60px; +} + +@import url(https://fonts.googleapis.com/css?family=Roboto:400,100,300,500,700); diff --git a/generated/client/src/containers/Layout/index.js b/generated/client/src/containers/Layout/index.js new file mode 100644 index 0000000..0720a9d --- /dev/null +++ b/generated/client/src/containers/Layout/index.js @@ -0,0 +1 @@ +export default from './Layout'; diff --git a/generated/client/src/containers/Login/Login.js b/generated/client/src/containers/Login/Login.js new file mode 100644 index 0000000..79be8be --- /dev/null +++ b/generated/client/src/containers/Login/Login.js @@ -0,0 +1,30 @@ +'use strict'; + +import React, { Component, PropTypes } from 'react'; +import { connect } from 'react-redux'; +import { push } from 'react-router-redux'; +import { AuthForm } from '../../common'; +import { login } from '../../redux/modules/auth'; + +class Login extends Component { + + static propTypes = { + dispatch: PropTypes.func + } + + handleLogin = (credentials) => { + const { dispatch } = this.props + dispatch(login(credentials)).then(() => dispatch(push('/membersOnly'))) + } + + render () { + return ( + + ) + } +} + +export default connect()(Login); diff --git a/generated/client/src/containers/Login/index.js b/generated/client/src/containers/Login/index.js new file mode 100644 index 0000000..5fa85e6 --- /dev/null +++ b/generated/client/src/containers/Login/index.js @@ -0,0 +1 @@ +export default from './Login'; diff --git a/generated/client/src/containers/Signup/Signup.js b/generated/client/src/containers/Signup/Signup.js new file mode 100644 index 0000000..9793ee3 --- /dev/null +++ b/generated/client/src/containers/Signup/Signup.js @@ -0,0 +1,29 @@ +'use strict'; + +import React, { Component, PropTypes } from 'react'; +import { connect } from 'react-redux'; +import { AuthForm } from '../../common'; +import { signup } from '../../redux/modules/auth'; + +class Signup extends Component { + + static propTypes = { + dispatch: PropTypes.func + } + + handleSignup = (credentials) => { + this.props.dispatch(signup(credentials)) + } + + render () { + return ( + + ) + } +} + +export default connect()(Signup); diff --git a/generated/client/src/containers/Signup/index.js b/generated/client/src/containers/Signup/index.js new file mode 100644 index 0000000..d99c64a --- /dev/null +++ b/generated/client/src/containers/Signup/index.js @@ -0,0 +1 @@ +export default from './Signup'; diff --git a/generated/client/src/containers/index.js b/generated/client/src/containers/index.js new file mode 100644 index 0000000..4c100fe --- /dev/null +++ b/generated/client/src/containers/index.js @@ -0,0 +1,3 @@ +export Layout from './Layout'; +export Login from './Login'; +export Signup from './Signup'; diff --git a/generated/client/src/redux/configureStore.js b/generated/client/src/redux/configureStore.js new file mode 100644 index 0000000..85b2745 --- /dev/null +++ b/generated/client/src/redux/configureStore.js @@ -0,0 +1,28 @@ +'use strict'; + +import { createStore, combineReducers, applyMiddleware, compose } from 'redux' +import { routerMiddleware, routerReducer as routing } from 'react-router-redux' +import createLogger from 'redux-logger' +import thunk from 'redux-thunk' +import promise from './middleware/promise' +import auth from './modules/auth' + +export default function configureStore (history, initialState) { + + const reducer = combineReducers({ + auth, + routing + }) + + const middleware = [thunk, promise, routerMiddleware(history)] + if (process.env.NODE_ENV !== 'production') { + middleware.push(createLogger()) + } + + const enhancers = compose( + applyMiddleware(...middleware), + window.devToolsExtension ? window.devToolsExtension() : f => f + ) + + return createStore(reducer, initialState, enhancers) +} diff --git a/generated/client/src/redux/middleware/promise.js b/generated/client/src/redux/middleware/promise.js new file mode 100644 index 0000000..97b673e --- /dev/null +++ b/generated/client/src/redux/middleware/promise.js @@ -0,0 +1,29 @@ +'use strict'; + +import { parseJSON, parseData } from '../../utils' + +export default () => next => action => { + + const { promise, types, ...rest } = action + + if (!promise) { + return next(action) + } + + const [REQUEST, SUCCESS, FAILURE] = types + next({ ...rest, type: REQUEST }) + + return promise + .then(parseData) + .then( + result => next({ ...rest, result, type: SUCCESS }), + error => next({ ...rest, error, type: FAILURE}) + ) + .catch(error => { + next({ + ...rest, + error: `MIDDLEWARE ERROR: ${error.message}`, + type: FAILURE + }) + }) +} diff --git a/generated/client/src/redux/modules/auth/index.js b/generated/client/src/redux/modules/auth/index.js new file mode 100644 index 0000000..a12933d --- /dev/null +++ b/generated/client/src/redux/modules/auth/index.js @@ -0,0 +1,118 @@ +'use strict'; + +import { push } from 'react-router-redux'; +import { auth } from '../../../api'; + +export const LOAD = 'LOAD'; +export const LOAD_SUCCESS = 'LOAD_SUCCESS'; +export const LOAD_FAILURE = 'LOAD_FAILURE'; +export const LOGIN = 'LOGIN'; +export const LOGIN_SUCCESS = 'LOGIN_SUCCESS'; +export const LOGIN_FAILURE = 'LOGIN_FAILURE'; +export const LOGOUT = 'LOGOUT'; +export const LOGOUT_SUCCESS = 'LOGOUT_SUCCESS'; +export const LOGOUT_FAILURE = 'LOGOUT_FAILURE'; +export const SIGNUP = 'SIGNUP'; +export const SIGNUP_SUCCESS = 'SIGNUP_SUCCESS'; +export const SIGNUP_FAILURE = 'SIGNUP_FAILURE'; + +export function isLoaded (globalState) { + return globalState.auth && globalState.auth.loaded +} + +export const load = () => (dispatch, getState) => { + dispatch({ type: LOAD }); + const { auth: { user } } = getState(); + + if (user) { + dispatch({ type: LOAD_SUCCESS, user }); + } else { + return auth.fetchSession() + .then( + result => dispatch({ type: LOAD_SUCCESS, result }), + error => dispatch({ type: LOAD_FAILURE, error }) + ) + .catch(error => { + dispatch({ + type: LOAD_FAILURE, + error: error.message || `An error occured` + }) + }); + } +} + +export function signup (credentials) { + return { + types: [SIGNUP, SIGNUP_SUCCESS, SIGNUP_FAILURE], + promise: auth.trySignup(credentials) + } +} + +export function login (credentials) { + return { + types: [LOGIN, LOGIN_SUCCESS, LOGIN_FAILURE], + promise: auth.tryLogin(credentials) + } +} + +export function logout () { + return { + types: [LOGOUT, LOGOUT_SUCCESS, LOGOUT_FAILURE], + promise: auth.tryLogout() + } +} + +const initialState = { + loaded: false +} + +export default function reducer (state = initialState, action) { + switch (action.type) { + case LOAD: + return { + ...state, + loading: true, + loadError: null + } + case SIGNUP: + case LOGIN: + case LOGOUT: + return { + ...state, + loading: true, + error: null + } + case LOAD_SUCCESS: + case SIGNUP_SUCCESS: + case LOGIN_SUCCESS: + return { + ...state, + loading: false, + loaded: true, + user: action.result.user + } + case LOGOUT_SUCCESS: + return { + ...state, + loading: false, + loaded: false, + user: null + } + case LOAD_FAILURE: + return { + ...state, + loading: false, + loadError: action.error.response + } + case SIGNUP_FAILURE: + case LOGIN_FAILURE: + case LOGOUT_FAILURE: + return { + ...state, + loading: false, + error: action.error.response + } + default: + return state + } +} diff --git a/generated/client/src/redux/modules/auth/spec.js b/generated/client/src/redux/modules/auth/spec.js new file mode 100644 index 0000000..9d24a9c --- /dev/null +++ b/generated/client/src/redux/modules/auth/spec.js @@ -0,0 +1,60 @@ +'use strict'; + +import { expect } from 'chai'; +import configureMockStore from 'redux-mock-store'; +import thunk from 'redux-thunk'; +import promise from '../../middleware/promise'; +import reducer from '../auth'; +import * as test from './tests'; + +const middlewares = [ thunk, promise ]; +const mockStore = configureMockStore(middlewares); + +describe('MODULE - auth:', () => { + describe('ACTIONS', () => { + let store = mockStore({ session: {} }); + + // isLoaded action test + test.isLoaded(mockStore); + + // load action tests + test.load(mockStore); + + // login action tests + test.login(mockStore); + + // logout action tests + test.logout(mockStore); + + // signup action test + test.signup(mockStore); + + }); + + describe('REDUCER', () => { + + const initialState = { + loaded: false + }; + + it('returns the initial state', () => { + expect(reducer(undefined, {})).to.deep.equal(initialState) + }); + + describe('handles actions', () => { + // LOAD action tests + test.loadActions(); + + // SIGNUP action tests + test.signupActions(); + + // LOGIN action tests + test.loginActions(); + + // LOGOUT action tests + test.logoutActions(); + }); + + }); + +}); diff --git a/generated/client/src/redux/modules/auth/tests/index.js b/generated/client/src/redux/modules/auth/tests/index.js new file mode 100644 index 0000000..d7c70c1 --- /dev/null +++ b/generated/client/src/redux/modules/auth/tests/index.js @@ -0,0 +1,9 @@ +export isLoaded from './isLoaded' +export load from './load' +export loadActions from './loadActions' +export login from './login' +export loginActions from './loginActions' +export logout from './logout' +export logoutActions from './logoutActions' +export signup from './signup' +export signupActions from './signupActions' diff --git a/generated/client/src/redux/modules/auth/tests/isLoaded.js b/generated/client/src/redux/modules/auth/tests/isLoaded.js new file mode 100644 index 0000000..c265fc8 --- /dev/null +++ b/generated/client/src/redux/modules/auth/tests/isLoaded.js @@ -0,0 +1,21 @@ +'use strict'; + +import { expect } from 'chai'; +import { isLoaded } from '../../auth'; + +export default function (mockStore) { + describe('isLoaded', () => { + let store; + + it('returns true if session has been loaded', () => { + store = mockStore({ session: { loaded: true }}); + console.log('STORE:', store); + expect(isLoaded(store.getState())).to.be.true; + }); + + it('returns false if session has not been loaded', () => { + store = mockStore({ session: { loaded: false }}); + expect(isLoaded(store.getState())).to.be.false; + }); + }); +} diff --git a/generated/client/src/redux/modules/auth/tests/load.js b/generated/client/src/redux/modules/auth/tests/load.js new file mode 100644 index 0000000..1c9dd55 --- /dev/null +++ b/generated/client/src/redux/modules/auth/tests/load.js @@ -0,0 +1,64 @@ +'use strict'; + +import { expect } from 'chai'; +import nock from 'nock'; +import { + load, + LOAD, LOAD_SUCCESS, LOAD_FAILURE +} from '../../auth'; + +const credentials = { + email: 'test@test.com', + password: 'test1234' +}; + +export default function (mockStore) { + describe('load', () => { + let store; + + beforeEach(() => { + store = mockStore({ session: {} }); + }); + + afterEach(() => { + nock.cleanAll(); + }); + + const sessionAPICall = nock(`http://localhost:8080`) + .get('/session'); + + it('creates LOAD when initially dispatched', () => { + sessionAPICall.reply(200, credentials); + + return store.dispatch(load()) + .then(() => { + const actionTypes = store.getActions().map(action => action.type) + expect(actionTypes).to.include(LOAD) + }); + }); + + it('creates LOAD_SUCCESS with result when load was successfully done', () => { + sessionAPICall.reply(200, credentials); + + return store.dispatch(load()) + .then(() => { + const actions = store.getActions().filter(action => { + return action.result && action.type === LOAD_SUCCESS + }); + expect(actions).to.have.length(1); + expect(actions[0].type).to.equal(LOAD_SUCCESS); + expect(actions[0].result).to.deep.equal(credentials); + }); + }); + + it ('creates LOAD_FAILURE when load request fails', () => { + sessionAPICall.replyWithError({ message: 'Error occured' }); + + return store.dispatch(load()) + .then(() => { + const actionTypes = store.getActions().map(action => action.type); + expect(actionTypes).to.include(LOAD_FAILURE); + }); + }); + }); +} diff --git a/generated/client/src/redux/modules/auth/tests/loadActions.js b/generated/client/src/redux/modules/auth/tests/loadActions.js new file mode 100644 index 0000000..30e1bfd --- /dev/null +++ b/generated/client/src/redux/modules/auth/tests/loadActions.js @@ -0,0 +1,71 @@ +'use strict'; + +import { expect } from 'chai'; +import reducer, { LOAD, LOAD_SUCCESS, LOAD_FAILURE } from '../../auth'; + +const successRes = { + user: { email: 'test@test.com', password: 'test1234' } +}; + +const failureRes = { + response: { data: 'ERROR' } +}; + +export default function () { + describe('LOAD', () => { + const nextState = reducer( + { loading: false, loadError: failureRes }, + { type: LOAD } + ); + + it('by setting \'loading\' to true', () => { + expect(nextState.loading).to.be.true; + }); + + it('by setting \'loadError\' to null', () => { + expect(nextState.loadError).to.be.null; + }); + }); + + describe('LOAD_SUCCESS', () => { + const nextState = reducer( + { loading: true, loaded: false }, + { type: LOAD_SUCCESS, result: successRes } + ); + + it('by setting \'loading\' to false', () => { + expect(nextState.loading).to.be.false; + }); + + it('by setting \'loaded\' to true', () => { + expect(nextState.loaded).to.be.true; + }); + + it('by setting \'user\'', () => { + expect(nextState.user).to.exist; + }); + }); + + describe('LOAD_FAILURE', () => { + const nextState = reducer( + { loading: true, loaded: false }, + { type: LOAD_FAILURE, error: failureRes} + ); + + it('by setting \'loading\' to false', () => { + expect(nextState.loading).to.be.false; + }); + + it('by setting \'loadError\'', () => { + expect(nextState.loadError).to.exist; + }); + + it('by not setting \'loaded\' to true', () => { + expect(nextState.loaded).to.be.false; + }); + + it('by not setting \'user\'', () => { + expect(nextState.user).to.not.exist; + }); + }); +} diff --git a/generated/client/src/redux/modules/auth/tests/login.js b/generated/client/src/redux/modules/auth/tests/login.js new file mode 100644 index 0000000..8546d75 --- /dev/null +++ b/generated/client/src/redux/modules/auth/tests/login.js @@ -0,0 +1,66 @@ +'use strict'; + +import { expect } from 'chai'; +import nock from 'nock'; +import { + login, + LOGIN, LOGIN_SUCCESS, LOGIN_FAILURE +} from '../../auth'; + +const credentials = { + email: 'test@test.com', + password: 'test1234' +}; + +export default function (mockStore) { + describe('login', () => { + let store; + + beforeEach(() => { + store = mockStore({ session: {} }); + }) + + afterEach(() => { + nock.cleanAll(); + }) + + const loginAPICall = () => nock(`http://localhost:8080`) + .post('/login', credentials); + + it('creates LOGIN when initially dispatched', () => { + loginAPICall().reply(200, credentials); + + return store.dispatch(login(credentials)) + .then(() => { + const actionTypes = store.getActions().map(action => action.type) + expect(actionTypes).to.include(LOGIN) + }); + }) + + it('creates LOGIN_SUCCESS when login was successfully done', () => { + loginAPICall().reply(200, credentials); + + return store.dispatch(login(credentials)) + .then(() => { + const actions = store.getActions().filter(action => { + return action.result && action.type === LOGIN_SUCCESS + }); + expect(actions).to.have.length(1); + expect(actions[0].type).to.equal(LOGIN_SUCCESS); + expect(actions[0].result).to.deep.equal(credentials); + }); + }) + + it('creates LOGIN_FAILURE when login request fails', () => { + loginAPICall().replyWithError({ message: 'Invalid credentials' }); + + return store.dispatch(login(credentials)) + .then(() => { + const actionTypes = store.getActions().map(action => action.type); + expect(actionTypes).to.include(LOGIN_FAILURE); + }); + }); + }); +} + + diff --git a/generated/client/src/redux/modules/auth/tests/loginActions.js b/generated/client/src/redux/modules/auth/tests/loginActions.js new file mode 100644 index 0000000..86cb76e --- /dev/null +++ b/generated/client/src/redux/modules/auth/tests/loginActions.js @@ -0,0 +1,71 @@ +'use strict'; + +import { expect } from 'chai'; +import reducer, { LOGIN, LOGIN_SUCCESS, LOGIN_FAILURE } from '../../auth'; + +const successRes = { + user: { email: 'test@test.com', password: 'test1234' } +}; + +const failureRes = { + response: { data: 'ERROR' } +}; + +export default function () { + describe('LOGIN', () => { + const nextState = reducer( + { loading: false, error: failureRes }, + { type: LOGIN } + ); + + it('by setting \'loading\' to true', () => { + expect(nextState.loading).to.be.true; + }); + + it('by setting \'error\' to null', () => { + expect(nextState.error).to.be.null; + }); + }); + + describe('LOGIN_SUCCESS', () => { + const nextState = reducer( + { loading: true, loaded: false }, + { type: LOGIN_SUCCESS, result: successRes } + ); + + it('by setting \'loading\' to false', () => { + expect(nextState.loading).to.be.false; + }); + + it('by setting \'loaded\' to true', () => { + expect(nextState.loaded).to.be.true; + }); + + it('by setting \'user\'', () => { + expect(nextState.user).to.exist; + }); + }); + + describe('LOGIN_FAILURE', () => { + const nextState = reducer( + { loading: true, loaded: false }, + { type: LOGIN_FAILURE, error: failureRes} + ); + + it('by setting \'loading\' to false', () => { + expect(nextState.loading).to.be.false; + }); + + it('by setting \'error\'', () => { + expect(nextState.error).to.exist; + }); + + it('by not setting \'loaded\' to true', () => { + expect(nextState.loaded).to.be.false; + }); + + it('by not setting \'user\'', () => { + expect(nextState.user).to.not.exist; + }); + }); +} diff --git a/generated/client/src/redux/modules/auth/tests/logout.js b/generated/client/src/redux/modules/auth/tests/logout.js new file mode 100644 index 0000000..f03601d --- /dev/null +++ b/generated/client/src/redux/modules/auth/tests/logout.js @@ -0,0 +1,60 @@ +'use strict'; + +import { expect } from 'chai'; +import nock from 'nock'; +import { + logout, + LOGOUT, LOGOUT_SUCCESS, LOGOUT_FAILURE +} from '../../auth'; + +const credentials = { + email: 'test@test.com', + password: 'test1234' +}; + +export default function (mockStore) { + describe('logout', () => { + let store; + + beforeEach(() => { + store = mockStore({ session: {} }); + }); + + afterEach(() => { + nock.cleanAll(); + }); + + const logoutAPICall = nock(`http://localhost:8080`) + .get('/logout'); + + it('creates LOGOUT when initially dispatched', () => { + logoutAPICall.reply(200); + + return store.dispatch(logout()) + .then(() => { + const actionTypes = store.getActions().map(action => action.type); + expect(actionTypes).to.include(LOGOUT); + }); + }); + + it('creates LOGOUT_SUCCESS when login was successfully done', () => { + logoutAPICall.reply(200); + + return store.dispatch(logout()) + .then(() => { + const actionTypes = store.getActions().map(action => action.type); + expect(actionTypes).to.include(LOGOUT_SUCCESS); + }); + }); + + it('creates LOGOUT_FAILURE when login request fails', () => { + logoutAPICall.replyWithError({ message: 'Logout Failed' }); + + return store.dispatch(logout()) + .then(() => { + const actionTypes = store.getActions().map(action => action.type); + expect(actionTypes).to.include(LOGOUT_FAILURE); + }); + }); + }); +} diff --git a/generated/client/src/redux/modules/auth/tests/logoutActions.js b/generated/client/src/redux/modules/auth/tests/logoutActions.js new file mode 100644 index 0000000..0f8f4ba --- /dev/null +++ b/generated/client/src/redux/modules/auth/tests/logoutActions.js @@ -0,0 +1,72 @@ +'use strict'; + +import { expect } from 'chai'; +import reducer, { LOGOUT, LOGOUT_SUCCESS, LOGOUT_FAILURE } from '../../auth'; + +const credentials = { + email: 'test@test.com', + password: 'test1234' +}; + +const failureRes = { + response: { data: 'ERROR' } +}; + +export default function () { + describe('LOGOUT', () => { + const nextState = reducer( + { loading: false, error: failureRes, user: credentials }, + { type: LOGOUT } + ); + + it('by setting \'loading\' to true', () => { + expect(nextState.loading).to.be.true; + }); + + it('by setting \'error\' to null', () => { + expect(nextState.error).to.be.null; + }); + }); + + describe('LOGOUT_SUCCESS', () => { + const nextState = reducer( + { loading: true, loaded: true, user: credentials }, + { type: LOGOUT_SUCCESS } + ); + + it('by setting \'loading\' to false', () => { + expect(nextState.loading).to.be.false; + }); + + it('by setting \'loaded\' to false', () => { + expect(nextState.loaded).to.be.false; + }); + + it('by setting \'user\' to null', () => { + expect(nextState.user).to.be.null; + }); + }); + + describe('LOGOUT_FAILURE', () => { + const nextState = reducer( + { loading: true, loaded: true, user: credentials }, + { type: LOGOUT_FAILURE, error: failureRes } + ); + + it('by setting \'loading\' to false', () => { + expect(nextState.loading).to.be.false; + }); + + it('by setting \'error\'', () => { + expect(nextState.error).to.exist; + }); + + it('by not setting \'loaded\' to false', () => { + expect(nextState.loaded).to.be.true; + }); + + it('by not setting \'user\' to null', () => { + expect(nextState.user).to.exist; + }); + }); +} diff --git a/generated/client/src/redux/modules/auth/tests/signup.js b/generated/client/src/redux/modules/auth/tests/signup.js new file mode 100644 index 0000000..2fb8f6e --- /dev/null +++ b/generated/client/src/redux/modules/auth/tests/signup.js @@ -0,0 +1,64 @@ +'use strict'; + +import { expect } from 'chai'; +import nock from 'nock'; +import { + signup, + SIGNUP, SIGNUP_SUCCESS, SIGNUP_FAILURE +} from '../../auth'; + +const credentials = { + email: 'test@test.com', + password: 'test1234' +}; + +export default function (mockStore) { + describe('signup', () => { + let store; + + beforeEach(() => { + store = mockStore({ session: {} }); + }); + + afterEach(() => { + nock.cleanAll(); + }); + + const signupAPICall = nock(`http://localhost:8080`) + .post('/signup', credentials); + + it('creates SIGNUP when initially dispatched', () => { + signupAPICall.reply(200, credentials); + + return store.dispatch(signup(credentials)) + .then(() => { + const actionTypes = store.getActions().map(action => action.type); + expect(actionTypes).to.include(SIGNUP); + }); + }); + + it('creates SIGNUP_SUCCESS with result when signup was successfully done', () => { + signupAPICall.reply(200, credentials); + + return store.dispatch(signup(credentials)) + .then(() => { + const actions = store.getActions().filter(action => { + return action.result && action.type === SIGNUP_SUCCESS + }); + expect(actions).to.have.length(1); + expect(actions[0].type).to.equal(SIGNUP_SUCCESS); + expect(actions[0].result).to.deep.equal(credentials); + }); + }); + + it ('creates SIGNUP_FAILURE when signup request fails', () => { + signupAPICall.replyWithError({ message: 'Error occured' }); + + return store.dispatch(signup(credentials)) + .then(() => { + const actionTypes = store.getActions().map(action => action.type); + expect(actionTypes).to.include(SIGNUP_FAILURE); + }); + }); + }); +} diff --git a/generated/client/src/redux/modules/auth/tests/signupActions.js b/generated/client/src/redux/modules/auth/tests/signupActions.js new file mode 100644 index 0000000..4824133 --- /dev/null +++ b/generated/client/src/redux/modules/auth/tests/signupActions.js @@ -0,0 +1,71 @@ +'use strict'; + +import { expect } from 'chai'; +import reducer, { SIGNUP, SIGNUP_SUCCESS, SIGNUP_FAILURE } from '../../auth'; + +const successRes = { + user: { email: 'test@test.com', password: 'test1234' } +}; + +const failureRes = { + response: { data: 'ERROR' } +}; + +export default function () { + describe('SIGNUP', () => { + const nextState = reducer( + { loading: false, error: failureRes }, + { type: SIGNUP } + ); + + it('by setting \'loading\' to true', () => { + expect(nextState.loading).to.be.true; + }); + + it('by setting \'error\' to null', () => { + expect(nextState.error).to.be.null; + }); + }); + + describe('SIGNUP_SUCCESS', () => { + const nextState = reducer( + { loading: true, loaded: false }, + { type: SIGNUP_SUCCESS, result: successRes } + ); + + it('by setting \'loading\' to false', () => { + expect(nextState.loading).to.be.false; + }); + + it('by setting \'loaded\' to true', () => { + expect(nextState.loaded).to.be.true; + }); + + it('by setting \'user\'', () => { + expect(nextState.user).to.exist; + }); + }); + + describe('SIGNUP_FAILURE', () => { + const nextState = reducer( + { loading: true, loaded: false }, + { type: SIGNUP_FAILURE, error: failureRes} + ); + + it('by setting \'loading\' to false', () => { + expect(nextState.loading).to.be.false; + }); + + it('by setting \'error\'', () => { + expect(nextState.error).to.exist; + }); + + it('by not setting \'loaded\' to true', () => { + expect(nextState.loaded).to.be.false; + }); + + it('by not setting \'user\'', () => { + expect(nextState.user).to.not.exist; + }); + }); +} diff --git a/generated/client/src/resources/FullstackPics.js b/generated/client/src/resources/FullstackPics.js new file mode 100644 index 0000000..66d5c6f --- /dev/null +++ b/generated/client/src/resources/FullstackPics.js @@ -0,0 +1,32 @@ +'use strict'; + +const FullstackPics = [ + 'https://pbs.twimg.com/media/B7gBXulCAAAXQcE.jpg:large', + 'https://fbcdn-sphotos-c-a.akamaihd.net/hphotos-ak-xap1/t31.0-8/10862451_10205622990359241_8027168843312841137_o.jpg', + 'https://pbs.twimg.com/media/B-LKUshIgAEy9SK.jpg', + 'https://pbs.twimg.com/media/B79-X7oCMAAkw7y.jpg', + 'https://pbs.twimg.com/media/B-Uj9COIIAIFAh0.jpg:large', + 'https://pbs.twimg.com/media/B6yIyFiCEAAql12.jpg:large', + 'https://pbs.twimg.com/media/CE-T75lWAAAmqqJ.jpg:large', + 'https://pbs.twimg.com/media/CEvZAg-VAAAk932.jpg:large', + 'https://pbs.twimg.com/media/CEgNMeOXIAIfDhK.jpg:large', + 'https://pbs.twimg.com/media/CEQyIDNWgAAu60B.jpg:large', + 'https://pbs.twimg.com/media/CCF3T5QW8AE2lGJ.jpg:large', + 'https://pbs.twimg.com/media/CAeVw5SWoAAALsj.jpg:large', + 'https://pbs.twimg.com/media/CAaJIP7UkAAlIGs.jpg:large', + 'https://pbs.twimg.com/media/CAQOw9lWEAAY9Fl.jpg:large', + 'https://pbs.twimg.com/media/B-OQbVrCMAANwIM.jpg:large', + 'https://pbs.twimg.com/media/B9b_erwCYAAwRcJ.png:large', + 'https://pbs.twimg.com/media/B5PTdvnCcAEAl4x.jpg:large', + 'https://pbs.twimg.com/media/B4qwC0iCYAAlPGh.jpg:large', + 'https://pbs.twimg.com/media/B2b33vRIUAA9o1D.jpg:large', + 'https://pbs.twimg.com/media/BwpIwr1IUAAvO2_.jpg:large', + 'https://pbs.twimg.com/media/BsSseANCYAEOhLw.jpg:large', + 'https://pbs.twimg.com/media/CJ4vLfuUwAAda4L.jpg:large', + 'https://pbs.twimg.com/media/CI7wzjEVEAAOPpS.jpg:large', + 'https://pbs.twimg.com/media/CIdHvT2UsAAnnHV.jpg:large', + 'https://pbs.twimg.com/media/CGCiP_YWYAAo75V.jpg:large', + 'https://pbs.twimg.com/media/CIS4JPIWIAI37qu.jpg:large' +]; + +export default FullstackPics; diff --git a/generated/client/src/resources/RandomGreetings.js b/generated/client/src/resources/RandomGreetings.js new file mode 100644 index 0000000..4c66f88 --- /dev/null +++ b/generated/client/src/resources/RandomGreetings.js @@ -0,0 +1,22 @@ +'use strict'; + +const greetings = [ + 'Hello, world!', + 'At long last, I live!', + 'Hello, simple human.', + 'What a beautiful day!', + 'I\'m like any other project, except that I am yours. :)', + 'This empty string is for Lindsay Levine.', + 'こんにちは、ユーザー様。', + 'Welcome. To. WEBSITE.', + ':D', + 'Yes, I think we\'ve met before.', + 'Gimme 3 mins... I just grabbed this really dope frittata', + 'If Cooper could offer only one piece of advice, it would be to nevSQUIRREL!', +]; + +const getRandomFromArray = (arr) => arr[Math.floor(Math.random() * arr.length)]; + +const getRandomGreeting = () => getRandomFromArray(greetings); + +export default getRandomGreeting; diff --git a/generated/client/src/routes.js b/generated/client/src/routes.js new file mode 100644 index 0000000..d7559e0 --- /dev/null +++ b/generated/client/src/routes.js @@ -0,0 +1,83 @@ +'use strict'; + +import React from 'react'; +import Promise from 'bluebird'; +import { Route, IndexRoute } from 'react-router'; +import { + isLoaded as isAuthLoaded, + load as loadAuth +} from './redux/modules/auth'; +import { About, Docs, Home, MembersOnly } from './components'; +import { Layout, Login, Signup } from './containers'; +import { NotFound } from './common'; + +const getRoutes = (store) => { + const getAuth = (nextState, replace, next) => { + if (!isAuthLoaded(store.getState())) { + store.dispatch(loadAuth()) + .then(() => next()) + } else { + next() + } + } + + const requireLogin = (nextState, replace, next) => { + function checkAuth () { + const { auth: { user } } = store.getState(); + if (!user) { + replace('/'); + } + next(); + } + + if (!isAuthLoaded(store.getState())) { + store.dispatch(loadAuth()).then(checkAuth); + } else { + checkAuth(); + } + } + + const requireNoUser = (nextState, replace, next) => { + function checkAuth () { + const { auth: { user } } = store.getState(); + if (user) { + replace('/membersOnly'); + } + next(); + } + + if (!isAuthLoaded(store.getState())) { + store.dispatch(loadAuth()).then(checkAuth) + } else { + checkAuth(); + } + } + + return ( + + + { /* Home route */ } + + + { /* Authenticated Routes */ } + + + + + { /* Unauthenticated Routes Only */ } + + + + + + { /* Routes */ } + + + + { /* Catch all routes */ } + + + ) +} + +export default getRoutes; diff --git a/generated/client/src/utils/index.js b/generated/client/src/utils/index.js new file mode 100644 index 0000000..4e5eaa7 --- /dev/null +++ b/generated/client/src/utils/index.js @@ -0,0 +1,8 @@ +'use strict'; + +export function parseJSON (response) { + return response.text() + .then(text => text ? JSON.parse(text) : {}) +} + +export const parseData = res => res.data; diff --git a/generated/package.json b/generated/package.json index 2aaccfa..3927800 100644 --- a/generated/package.json +++ b/generated/package.json @@ -5,7 +5,11 @@ "main": "server/start.js", "scripts": { "start": "nodemon --watch server -e js,html server/start.js", - "postinstall": "gulp build" + "postinstall": "npm run build", + "build": "webpack --config webpack.dev.config.js", + "build:production": "NODE_ENV='production' webpack -p --config webpack.prod.config.js", + "test": "NODE_ENV='testing' ./node_modules/.bin/mocha --compilers js:babel-register **/spec.js", + "test:watch": "NODE_ENV='testing' ./node_modules/.bin/mocha --watch --compilers js:babel-register **/spec.js" }, "engines": { "node": ">=4.0.0" @@ -16,7 +20,15 @@ "angular-mocks": "^1.4.0", "angular-ui-bootstrap": "^0.14.3", "angular-ui-router": "^0.2.15", - "babel-preset-es2015": "^6.6.0", + "autoprefixer": "^6.5.0", + "axios": "^0.14.0", + "babel-loader": "^6.2.5", + "babel-polyfill": "^6.13.0", + "babel-preset-es2015": "^6.14.0", + "babel-preset-react": "^6.11.1", + "babel-preset-react-hmre": "^1.1.1", + "babel-preset-stage-1": "^6.13.0", + "babel-preset-stage-2": "^6.13.0", "babel-register": "^6.6.0", "bluebird": "^3.3.3", "body-parser": "^1.12.0", @@ -25,10 +37,13 @@ "chalk": "^1.0.0", "connect-session-sequelize": "^3.0.0", "cookie-parser": "^1.3.4", + "css-loader": "^0.25.0", "eslint": "^3.4.0", "eslint-config-fullstack": "^1.5.0", + "eslint-loader": "^1.5.0", "express": "^4.12.0", "express-session": "^1.10.3", + "extract-text-webpack-plugin": "^1.0.1", "gulp": "^3.8.11", "gulp-babel": "^6.1.2", "gulp-concat": "^2.5.2", @@ -53,6 +68,8 @@ "karma-mocha-reporter": "^1.0.2", "lodash": "^3.9.3", "mocha": "^3.0.2", + "nock": "^8.0.0", + "node-sass": "^3.10.0", "nodemon": "^1.3.7", "passport": "^0.2.1", "passport-facebook": "^1.0.3", @@ -62,12 +79,31 @@ "pg": "^4.5.5", "pg-hstore": "^2.3.2", "pg-native": "^1.10.0", + "postcss-loader": "^0.13.0", + "precss": "^1.4.0", + "react": "^15.3.2", + "react-bootstrap": "^0.30.3", + "react-dom": "^15.3.2", + "react-redux": "^4.4.5", + "react-router": "^2.8.1", + "react-router-bootstrap": "^0.23.1", + "react-router-redux": "^4.0.6", + "redux": "^3.6.0", + "redux-logger": "^2.6.1", + "redux-mock-store": "^1.2.1", + "redux-thunk": "^2.1.0", "run-sequence": "^1.0.2", + "sass-loader": "^4.0.2", "sequelize": "^3.23.3", "serve-favicon": "^2.2.0", "sinon": "^1.13.0", "socket.io": "^1.3.4", "socket.io-client": "^1.3.5", - "supertest": "^0.15.0" + "style-loader": "^0.13.1", + "supertest": "^0.15.0", + "webpack": "^1.13.2", + "webpack-dev-middleware": "^1.8.3", + "webpack-dev-server": "^1.16.1", + "webpack-hot-middleware": "^2.12.2" } } diff --git a/generated/server/app/configure/index.js b/generated/server/app/configure/index.js index e5111d0..f6af3f7 100644 --- a/generated/server/app/configure/index.js +++ b/generated/server/app/configure/index.js @@ -13,6 +13,7 @@ module.exports = function (app, db) { require('./app-variables')(app); require('./static-middleware')(app); require('./parsing-middleware')(app); + require('./webpack-middleware')(app); // Logging middleware, set as application // variable inside of server/app/configure/app-variables.js diff --git a/generated/server/app/configure/webpack-middleware.js b/generated/server/app/configure/webpack-middleware.js new file mode 100644 index 0000000..9b782c8 --- /dev/null +++ b/generated/server/app/configure/webpack-middleware.js @@ -0,0 +1,19 @@ +'use strict'; + +const path = require('path'); + +module.exports = function (app) { + if (process.env.NODE_ENV !== 'production') { + const webpack = require('webpack'); + const webpackHotMiddleware = require('webpack-hot-middleware'); + const webpackDevMiddleware = require('webpack-dev-middleware'); + const config = require(path.join(app.getValue('projectRoot'), 'webpack.dev.config.js')); + const compiler = webpack(config); + + app.use(webpackHotMiddleware(compiler)); + app.use(webpackDevMiddleware(compiler, { + noInfo: true, + publicPath: config.output.publicPath + })) + } +} diff --git a/generated/server/app/views/index.html b/generated/server/app/views/index.html index a5e18ae..5e5b634 100644 --- a/generated/server/app/views/index.html +++ b/generated/server/app/views/index.html @@ -5,17 +5,9 @@ Fullstack Academy Generated Application - - - - - - - - - - -
+ +
+ diff --git a/generated/webpack.dev.config.js b/generated/webpack.dev.config.js new file mode 100644 index 0000000..23bdb86 --- /dev/null +++ b/generated/webpack.dev.config.js @@ -0,0 +1,57 @@ +'use strict' + +const path = require('path'); +const webpack = require('webpack'); +const autoprefixer = require('autoprefixer'); +const precss = require('precss'); +const ExtractTextPlugin = require('extract-text-webpack-plugin'); + +module.exports = { + devtool: 'eval', + entry: [ + 'babel-polyfill', + 'webpack-hot-middleware/client', + './client/src/app.js' + ], + output: { + path: path.join(__dirname, 'public'), + filename: 'bundle.js', + publicPath: '/' + }, + resolve: { + extensions: ['', '.js', '.jsx', '.css', '.scss'], + modulesDirectories: ['client', 'node_modules'] + }, + module: { + preloaders: [ + { + test: /\.jsx?$/, + loaders: ['eslint'] + } + ], + loaders: [ + { + test: /\.jsx?$/, + loader: 'babel', + exclude: /(node_modules)|(bower_components)/ + }, + { + test: /\.s?css$/, + loader: ExtractTextPlugin.extract('style', 'css?-autoprefixer!postcss!sass?sourceMap'), + include: /(client)|(node_modules)/ + } + ] + }, + postcss: function () { + return [autoprefixer, precss] + }, + plugins: [ + new webpack.NoErrorsPlugin(), + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': JSON.stringify('development') + }), + new webpack.HotModuleReplacementPlugin(), + new ExtractTextPlugin('style.css', { allChunks: true }) + ] +} + diff --git a/generated/webpack.prod.config.js b/generated/webpack.prod.config.js new file mode 100644 index 0000000..6a4353b --- /dev/null +++ b/generated/webpack.prod.config.js @@ -0,0 +1,86 @@ +'use strict' + +const path = require('path') +const webpack = require('webpack') +const autoprefixer = require('autoprefixer') +const precss = require('precss') +const HtmlWebpackPlugin = require('html-webpack-plugin') +const ExtractTextPlugin = require('extract-text-webpack-plugin') + +const indexPath = path.join(__dirname, 'client', 'src', 'index.html') + +module.exports = { + devtool: 'source-map', + entry: [ + 'babel-polyfill', + './client/src/app.js' + ], + output: { + path: path.join(__dirname, 'client', 'public'), + filename: 'bundle.js', + publicPath: '/' + }, + resolve: { + extensions: ['', '.js', '.jsx', '.css', '.scss'], + modulesDirectories: ['client', 'node_modules'] + }, + module: { + loaders: [ + { + test: /\.jsx?$/, + loader: 'babel', + exclude: /(node_modules)|(bower_components)/ + }, + { + test: /\.s?css$/, + loader: ExtractTextPlugin.extract('style', 'css?-autoprefixer!postcss!sass'), + include: /(client)|(node_modules)/ + } + ] + }, + postcss: function () { + return [autoprefixer, precss] + }, + plugins: [ + new HtmlWebpackPlugin({ + inject: true, + template: indexPath, + minify: { + removeComments: true, + collapseWhitespace: true, + removeRedundantAttributes: true, + useShortDoctype: true, + removeEmptyAttributes: true, + removeStyleLinkTypeAttributes: true, + keepClosingSlash: true, + minifyJS: true, + minifyCSS: true, + minifyURLs: true + } + }), + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': JSON.stringify('production') + }), + new webpack.optimize.OccurrenceOrderPlugin(), + new webpack.optimize.UglifyJsPlugin({ + compressor: { + screw_ie8: true, + warnings: false + }, + minimize: true, + compress: { + screw_ie8: true, + warnings: false + }, + mangle: { + screw_ie8: true + }, + output: { + comments: false, + screw_ie8: true + } + }), + new ExtractTextPlugin('style.css', { allChunks: true }) + ] +} + From dfd091b11f760d55751d77493fb6908edad323cb Mon Sep 17 00:00:00 2001 From: Jason Hang Date: Wed, 28 Sep 2016 17:20:35 -0400 Subject: [PATCH 02/14] Restructured the app a little, removed Signup functionality. --- generated/client/src/api/auth/index.js | 7 +- generated/client/src/app.js | 2 +- generated/client/src/{ => config}/routes.js | 14 ++-- .../client/src/containers/Signup/Signup.js | 29 -------- .../client/src/containers/Signup/index.js | 1 - generated/client/src/containers/index.js | 1 - .../client/src/redux/modules/auth/index.js | 13 ---- .../client/src/redux/modules/auth/spec.js | 6 -- .../src/redux/modules/auth/tests/signup.js | 64 ----------------- .../redux/modules/auth/tests/signupActions.js | 71 ------------------- 10 files changed, 8 insertions(+), 200 deletions(-) rename generated/client/src/{ => config}/routes.js (84%) delete mode 100644 generated/client/src/containers/Signup/Signup.js delete mode 100644 generated/client/src/containers/Signup/index.js delete mode 100644 generated/client/src/redux/modules/auth/tests/signup.js delete mode 100644 generated/client/src/redux/modules/auth/tests/signupActions.js diff --git a/generated/client/src/api/auth/index.js b/generated/client/src/api/auth/index.js index 019e2ef..cbb9b9f 100644 --- a/generated/client/src/api/auth/index.js +++ b/generated/client/src/api/auth/index.js @@ -3,16 +3,12 @@ import axios from 'axios'; import { parseJSON, parseData } from '../../utils'; -const BASE_URL = process.env.URL || 'http://localhost:8080'; +const BASE_URL = process.env.URL | 'http://localhost:1337'; export const fetchSession = () => { return axios.get(`${BASE_URL}/session`).then(parseData); } -export const trySignup = (credentials) => { - return axios.post(`${BASE_URL}/signup`, credentials); -} - export const tryLogin = (credentials) => { return axios.post(`${BASE_URL}/login`, credentials); } @@ -23,7 +19,6 @@ export const tryLogout = () => { const auth = { fetchSession, - trySignup, tryLogin, tryLogout } diff --git a/generated/client/src/app.js b/generated/client/src/app.js index fdf5796..30f3bd6 100644 --- a/generated/client/src/app.js +++ b/generated/client/src/app.js @@ -5,7 +5,7 @@ import { render } from 'react-dom'; import { Provider } from 'react-redux'; import { Router, browserHistory } from 'react-router'; import { syncHistoryWithStore } from 'react-router-redux'; -import getRoutes from './routes'; +import getRoutes from './config/routes'; import configureStore from './redux/configureStore'; const store = configureStore(browserHistory); diff --git a/generated/client/src/routes.js b/generated/client/src/config/routes.js similarity index 84% rename from generated/client/src/routes.js rename to generated/client/src/config/routes.js index d7559e0..d005a11 100644 --- a/generated/client/src/routes.js +++ b/generated/client/src/config/routes.js @@ -1,23 +1,22 @@ 'use strict'; import React from 'react'; -import Promise from 'bluebird'; import { Route, IndexRoute } from 'react-router'; import { isLoaded as isAuthLoaded, load as loadAuth -} from './redux/modules/auth'; -import { About, Docs, Home, MembersOnly } from './components'; -import { Layout, Login, Signup } from './containers'; -import { NotFound } from './common'; +} from '../redux/modules/auth'; +import { About, Docs, Home, MembersOnly } from '../components'; +import { Layout, Login } from '../containers'; +import { NotFound } from '../common'; const getRoutes = (store) => { const getAuth = (nextState, replace, next) => { if (!isAuthLoaded(store.getState())) { store.dispatch(loadAuth()) - .then(() => next()) + .then(() => next()); } else { - next() + next(); } } @@ -67,7 +66,6 @@ const getRoutes = (store) => { { /* Unauthenticated Routes Only */ } - { /* Routes */ } diff --git a/generated/client/src/containers/Signup/Signup.js b/generated/client/src/containers/Signup/Signup.js deleted file mode 100644 index 9793ee3..0000000 --- a/generated/client/src/containers/Signup/Signup.js +++ /dev/null @@ -1,29 +0,0 @@ -'use strict'; - -import React, { Component, PropTypes } from 'react'; -import { connect } from 'react-redux'; -import { AuthForm } from '../../common'; -import { signup } from '../../redux/modules/auth'; - -class Signup extends Component { - - static propTypes = { - dispatch: PropTypes.func - } - - handleSignup = (credentials) => { - this.props.dispatch(signup(credentials)) - } - - render () { - return ( - - ) - } -} - -export default connect()(Signup); diff --git a/generated/client/src/containers/Signup/index.js b/generated/client/src/containers/Signup/index.js deleted file mode 100644 index d99c64a..0000000 --- a/generated/client/src/containers/Signup/index.js +++ /dev/null @@ -1 +0,0 @@ -export default from './Signup'; diff --git a/generated/client/src/containers/index.js b/generated/client/src/containers/index.js index 4c100fe..e3c3516 100644 --- a/generated/client/src/containers/index.js +++ b/generated/client/src/containers/index.js @@ -1,3 +1,2 @@ export Layout from './Layout'; export Login from './Login'; -export Signup from './Signup'; diff --git a/generated/client/src/redux/modules/auth/index.js b/generated/client/src/redux/modules/auth/index.js index a12933d..7931383 100644 --- a/generated/client/src/redux/modules/auth/index.js +++ b/generated/client/src/redux/modules/auth/index.js @@ -12,9 +12,6 @@ export const LOGIN_FAILURE = 'LOGIN_FAILURE'; export const LOGOUT = 'LOGOUT'; export const LOGOUT_SUCCESS = 'LOGOUT_SUCCESS'; export const LOGOUT_FAILURE = 'LOGOUT_FAILURE'; -export const SIGNUP = 'SIGNUP'; -export const SIGNUP_SUCCESS = 'SIGNUP_SUCCESS'; -export const SIGNUP_FAILURE = 'SIGNUP_FAILURE'; export function isLoaded (globalState) { return globalState.auth && globalState.auth.loaded @@ -41,13 +38,6 @@ export const load = () => (dispatch, getState) => { } } -export function signup (credentials) { - return { - types: [SIGNUP, SIGNUP_SUCCESS, SIGNUP_FAILURE], - promise: auth.trySignup(credentials) - } -} - export function login (credentials) { return { types: [LOGIN, LOGIN_SUCCESS, LOGIN_FAILURE], @@ -74,7 +64,6 @@ export default function reducer (state = initialState, action) { loading: true, loadError: null } - case SIGNUP: case LOGIN: case LOGOUT: return { @@ -83,7 +72,6 @@ export default function reducer (state = initialState, action) { error: null } case LOAD_SUCCESS: - case SIGNUP_SUCCESS: case LOGIN_SUCCESS: return { ...state, @@ -104,7 +92,6 @@ export default function reducer (state = initialState, action) { loading: false, loadError: action.error.response } - case SIGNUP_FAILURE: case LOGIN_FAILURE: case LOGOUT_FAILURE: return { diff --git a/generated/client/src/redux/modules/auth/spec.js b/generated/client/src/redux/modules/auth/spec.js index 9d24a9c..4d5fdfa 100644 --- a/generated/client/src/redux/modules/auth/spec.js +++ b/generated/client/src/redux/modules/auth/spec.js @@ -26,9 +26,6 @@ describe('MODULE - auth:', () => { // logout action tests test.logout(mockStore); - // signup action test - test.signup(mockStore); - }); describe('REDUCER', () => { @@ -45,9 +42,6 @@ describe('MODULE - auth:', () => { // LOAD action tests test.loadActions(); - // SIGNUP action tests - test.signupActions(); - // LOGIN action tests test.loginActions(); diff --git a/generated/client/src/redux/modules/auth/tests/signup.js b/generated/client/src/redux/modules/auth/tests/signup.js deleted file mode 100644 index 2fb8f6e..0000000 --- a/generated/client/src/redux/modules/auth/tests/signup.js +++ /dev/null @@ -1,64 +0,0 @@ -'use strict'; - -import { expect } from 'chai'; -import nock from 'nock'; -import { - signup, - SIGNUP, SIGNUP_SUCCESS, SIGNUP_FAILURE -} from '../../auth'; - -const credentials = { - email: 'test@test.com', - password: 'test1234' -}; - -export default function (mockStore) { - describe('signup', () => { - let store; - - beforeEach(() => { - store = mockStore({ session: {} }); - }); - - afterEach(() => { - nock.cleanAll(); - }); - - const signupAPICall = nock(`http://localhost:8080`) - .post('/signup', credentials); - - it('creates SIGNUP when initially dispatched', () => { - signupAPICall.reply(200, credentials); - - return store.dispatch(signup(credentials)) - .then(() => { - const actionTypes = store.getActions().map(action => action.type); - expect(actionTypes).to.include(SIGNUP); - }); - }); - - it('creates SIGNUP_SUCCESS with result when signup was successfully done', () => { - signupAPICall.reply(200, credentials); - - return store.dispatch(signup(credentials)) - .then(() => { - const actions = store.getActions().filter(action => { - return action.result && action.type === SIGNUP_SUCCESS - }); - expect(actions).to.have.length(1); - expect(actions[0].type).to.equal(SIGNUP_SUCCESS); - expect(actions[0].result).to.deep.equal(credentials); - }); - }); - - it ('creates SIGNUP_FAILURE when signup request fails', () => { - signupAPICall.replyWithError({ message: 'Error occured' }); - - return store.dispatch(signup(credentials)) - .then(() => { - const actionTypes = store.getActions().map(action => action.type); - expect(actionTypes).to.include(SIGNUP_FAILURE); - }); - }); - }); -} diff --git a/generated/client/src/redux/modules/auth/tests/signupActions.js b/generated/client/src/redux/modules/auth/tests/signupActions.js deleted file mode 100644 index 4824133..0000000 --- a/generated/client/src/redux/modules/auth/tests/signupActions.js +++ /dev/null @@ -1,71 +0,0 @@ -'use strict'; - -import { expect } from 'chai'; -import reducer, { SIGNUP, SIGNUP_SUCCESS, SIGNUP_FAILURE } from '../../auth'; - -const successRes = { - user: { email: 'test@test.com', password: 'test1234' } -}; - -const failureRes = { - response: { data: 'ERROR' } -}; - -export default function () { - describe('SIGNUP', () => { - const nextState = reducer( - { loading: false, error: failureRes }, - { type: SIGNUP } - ); - - it('by setting \'loading\' to true', () => { - expect(nextState.loading).to.be.true; - }); - - it('by setting \'error\' to null', () => { - expect(nextState.error).to.be.null; - }); - }); - - describe('SIGNUP_SUCCESS', () => { - const nextState = reducer( - { loading: true, loaded: false }, - { type: SIGNUP_SUCCESS, result: successRes } - ); - - it('by setting \'loading\' to false', () => { - expect(nextState.loading).to.be.false; - }); - - it('by setting \'loaded\' to true', () => { - expect(nextState.loaded).to.be.true; - }); - - it('by setting \'user\'', () => { - expect(nextState.user).to.exist; - }); - }); - - describe('SIGNUP_FAILURE', () => { - const nextState = reducer( - { loading: true, loaded: false }, - { type: SIGNUP_FAILURE, error: failureRes} - ); - - it('by setting \'loading\' to false', () => { - expect(nextState.loading).to.be.false; - }); - - it('by setting \'error\'', () => { - expect(nextState.error).to.exist; - }); - - it('by not setting \'loaded\' to true', () => { - expect(nextState.loaded).to.be.false; - }); - - it('by not setting \'user\'', () => { - expect(nextState.user).to.not.exist; - }); - }); -} From 9b0af0d7d8318d08299c925dec0b90b8c24d4da7 Mon Sep 17 00:00:00 2001 From: Jason Hang Date: Wed, 28 Sep 2016 17:41:11 -0400 Subject: [PATCH 03/14] Removed angular tests and fixed some bad URL in the tests. --- generated/client/src/api/auth/index.js | 3 +- .../client/src/components/Navbar/Navbar.js | 3 - .../src/redux/modules/auth/tests/index.js | 16 +- .../src/redux/modules/auth/tests/isLoaded.js | 5 +- .../src/redux/modules/auth/tests/load.js | 5 +- .../src/redux/modules/auth/tests/login.js | 4 +- .../src/redux/modules/auth/tests/logout.js | 4 +- generated/tests/browser/.eslintrc.json | 14 - .../browser/fsa-prebuilt/auth-service-test.js | 288 ------------------ .../browser/fsa-prebuilt/session-test.js | 76 ----- generated/tests/browser/karma.conf.js | 48 --- 11 files changed, 18 insertions(+), 448 deletions(-) delete mode 100644 generated/tests/browser/.eslintrc.json delete mode 100644 generated/tests/browser/fsa-prebuilt/auth-service-test.js delete mode 100644 generated/tests/browser/fsa-prebuilt/session-test.js delete mode 100644 generated/tests/browser/karma.conf.js diff --git a/generated/client/src/api/auth/index.js b/generated/client/src/api/auth/index.js index cbb9b9f..2408491 100644 --- a/generated/client/src/api/auth/index.js +++ b/generated/client/src/api/auth/index.js @@ -3,9 +3,10 @@ import axios from 'axios'; import { parseJSON, parseData } from '../../utils'; -const BASE_URL = process.env.URL | 'http://localhost:1337'; +const BASE_URL = process.env.URL || `http://localhost:${process.env.PORT || 1337}`; export const fetchSession = () => { + console.log(BASE_URL); return axios.get(`${BASE_URL}/session`).then(parseData); } diff --git a/generated/client/src/components/Navbar/Navbar.js b/generated/client/src/components/Navbar/Navbar.js index fa5bf0b..c1a0ec1 100644 --- a/generated/client/src/components/Navbar/Navbar.js +++ b/generated/client/src/components/Navbar/Navbar.js @@ -61,9 +61,6 @@ const renderAuthNavItems = (user, dispatch) => { } else { return (