Commit f7c1860b5bb9ed4bde0cd7198931fa2f48adb05d

Authored by tmcdeveloper
1 parent b2b910457f
Exists in master

add basic acceptance tests for signup and login with Chimp

... ... @@ -30,3 +30,7 @@ alanning:roles
30 30 react-meteor-data
31 31 themeteorchef:jquery-validation
32 32 themeteorchef:bert
  33 +static-html
  34 +xolvio:cleaner
  35 +practicalmeteor:mocha
  36 +xolvio:backdoor
... ...
... ... @@ -24,6 +24,7 @@ caching-compiler@1.0.2
24 24 caching-html-compiler@1.0.4
25 25 callback-hook@1.0.6
26 26 check@1.1.2
  27 +coffeescript@1.0.15
27 28 ddp@1.2.3
28 29 ddp-client@1.2.3
29 30 ddp-common@1.2.3
... ... @@ -66,6 +67,11 @@ npm-bcrypt@0.7.8_2
66 67 npm-mongo@1.4.41
67 68 observe-sequence@1.0.9
68 69 ordered-dict@1.0.5
  70 +practicalmeteor:chai@2.1.0_1
  71 +practicalmeteor:loglevel@1.2.0_2
  72 +practicalmeteor:mocha@2.1.0_8
  73 +practicalmeteor:mocha-core@0.1.4
  74 +practicalmeteor:sinon@1.14.1_2
69 75 promise@0.6.5
70 76 raix:eventemitter@0.1.3
71 77 random@1.0.7
... ... @@ -84,14 +90,18 @@ spacebars-compiler@1.0.9
84 90 srp@1.0.6
85 91 standard-minifier-css@1.0.4
86 92 standard-minifier-js@1.0.4
  93 +static-html@1.0.5
87 94 templating@1.1.7
88 95 templating-tools@1.0.2
89 96 themeteorchef:bert@2.1.0
90 97 themeteorchef:jquery-validation@1.14.0
91 98 tmeasday:check-npm-versions@0.2.0
  99 +tmeasday:test-reporter-helpers@0.2.1
92 100 tracker@1.0.11
93 101 ui@1.0.9
94 102 underscore@1.0.6
95 103 url@1.0.7
96 104 webapp@1.2.6
97 105 webapp-hashing@1.0.7
  106 +xolvio:backdoor@0.1.2
  107 +xolvio:cleaner@0.2.0
... ...
... ... @@ -0,0 +1,12 @@
  1 +<head>
  2 + <meta charset="utf-8">
  3 + <title>Application Name</title>
  4 + <meta name="description" content="A description for the application.">
  5 + <meta name="viewport" content="initial-scale=1, minimal-ui, maximum-scale=1, minimum-scale=1" />
  6 + <link rel="shortcut icon" type="image/png" href="favicon.png?v1" sizes="16x16 32x32 64x64">
  7 + <link rel="apple-touch-icon" sizes="120x120" href="apple-touch-icon-precomposed.png">
  8 +</head>
  9 +
  10 +<body>
  11 + <div id="react-root"></div>
  12 +</body>
... ...
client/stylesheets/application.scss
... ... @@ -6,3 +6,5 @@
6 6 @import "module/loading";
7 7 @import "module/login";
8 8 @import "module/signup";
  9 +
  10 +@import "state/navbar";
... ...
client/stylesheets/state/_navbar.scss
... ... @@ -0,0 +1,6 @@
  1 +.navbar-default .navbar-nav > li > a.active,
  2 +.navbar-default .navbar-nav > li > a.active:focus,
  3 +.navbar-default .navbar-nav > li > a.active:hover {
  4 + color: #555;
  5 + background-color: #e7e7e7;
  6 +}
... ...
imports/startup/client/routes.jsx
... ... @@ -19,15 +19,7 @@ const requireAuth = ( nextState, replace ) =&gt; {
19 19 }
20 20 };
21 21  
22   -const renderReactRoot = () => {
23   - let container = document.createElement( 'div' );
24   - container.id = 'react-root';
25   - document.body.appendChild( container );
26   -};
27   -
28 22 Meteor.startup( () => {
29   - renderReactRoot();
30   -
31 23 render(
32 24 <Router history={ browserHistory }>
33 25 <Route path="/" component={ App }>
... ...
imports/ui/components/app-navigation.js
1 1 import React from 'react';
2 2 import { Navbar, Nav, NavItem, NavDropdown, MenuItem } from 'react-bootstrap';
  3 +import { Link } from 'react-router';
3 4 import { PublicNavigation } from './public-navigation';
4 5 import { AuthenticatedNavigation } from './authenticated-navigation';
5 6  
... ... @@ -12,10 +13,13 @@ export class AppNavigation extends React.Component {
12 13 return <Navbar>
13 14 <Navbar.Header>
14 15 <Navbar.Brand>
15   - <a href="/">Application Name</a>
  16 + <Link to="/">Application Name</Link>
16 17 </Navbar.Brand>
  18 + <Navbar.Toggle />
17 19 </Navbar.Header>
18   - { this.renderNavigation( this.props.hasUser, this.props.activeRoute ) }
  20 + <Navbar.Collapse>
  21 + { this.renderNavigation( this.props.hasUser, this.props.activeRoute ) }
  22 + </Navbar.Collapse>
19 23 </Navbar>;
20 24 }
21 25 }
... ...
imports/ui/components/authenticated-navigation.js
1 1 import React from 'react';
2   -import { browserHistory } from 'react-router';
  2 +import { browserHistory, IndexLink, Link } from 'react-router';
3 3 import { Nav, NavItem, NavDropdown, MenuItem } from 'react-bootstrap';
4   -import { IndexLinkContainer, LinkContainer } from 'react-router-bootstrap';
5 4  
6 5 const handleLogout = () => {
7 6 return Meteor.logout( () => browserHistory.push( '/login' ) );
... ... @@ -15,28 +14,16 @@ const userName = () =&gt; {
15 14 }
16 15 };
17 16  
18   -export const AuthenticatedNavigation = React.createClass({
19   - isActive( route, indexOnly ) {
20   - return this.props.activeRoute( route, indexOnly );
21   - },
22   - handleRouteChange() {
23   - this.forceUpdate();
24   - },
25   - render() {
26   - return <div>
27   - <Nav>
28   - <li className={ this.isActive( '/', true ) } onClick={ this.handleRouteChange }>
29   - <Link to="/">Index</Link>
30   - </li>
31   - <li className={ this.isActive( '/dashboard' ) } onClick={ this.handleRouteChange }>
32   - <Link to="/dashboard">Dashboard</Link>
33   - </li>
34   - </Nav>
35   - <Nav pullRight>
36   - <NavDropdown eventKey={ 3 } title={ userName() } id="basic-nav-dropdown">
37   - <MenuItem eventKey={ 3.3 } onClick={ handleLogout }>Logout</MenuItem>
38   - </NavDropdown>
39   - </Nav>
40   - </div>;
41   - }
42   -});
  17 +export const AuthenticatedNavigation = () => (
  18 + <div>
  19 + <Nav>
  20 + <li><IndexLink to="/" activeClassName="active">Index</IndexLink></li>
  21 + <li><Link to="/dashboard" activeClassName="active">Dashboard</Link></li>
  22 + </Nav>
  23 + <Nav pullRight>
  24 + <NavDropdown eventKey={ 3 } title={ userName() } id="basic-nav-dropdown">
  25 + <MenuItem eventKey={ 3.1 } onClick={ handleLogout }>Logout</MenuItem>
  26 + </NavDropdown>
  27 + </Nav>
  28 + </div>
  29 +)
... ...
imports/ui/components/public-navigation.js
... ... @@ -2,21 +2,9 @@ import React from &#39;react&#39;;
2 2 import { Link } from 'react-router';
3 3 import { Nav, NavItem } from 'react-bootstrap';
4 4  
5   -export const PublicNavigation = React.createClass({
6   - isActive( route, indexOnly ) {
7   - return this.props.activeRoute( route, indexOnly ) ? 'active' : '';
8   - },
9   - handleRouteChange() {
10   - this.forceUpdate();
11   - },
12   - render() {
13   - return <Nav pullRight>
14   - <li className={ this.isActive( '/signup' ) } onClick={ this.handleRouteChange }>
15   - <Link to="/signup">Sign Up</Link>
16   - </li>
17   - <li className={ this.isActive( '/login' ) } onClick={ this.handleRouteChange }>
18   - <Link to="/login">Log In</Link>
19   - </li>
20   - </Nav>;
21   - }
22   -});
  5 +export const PublicNavigation = () => (
  6 + <Nav pullRight>
  7 + <li role="presentation"><Link to="/signup">Sign Up</Link></li>
  8 + <li role="presentation"><Link to="/login">Log In</Link></li>
  9 + </Nav>
  10 +)
... ...
... ... @@ -4,11 +4,14 @@
4 4 "description": "Application description.",
5 5 "scripts": {
6 6 "start": "meteor --settings settings-development.json",
  7 + "chimp-watch": "chimp --ddp=http://localhost:3000 --watch --mocha --path=tests",
  8 + "chimp-test": "chimp --ddp=http://localhost:3000 --mocha --path=tests",
7 9 "staging": "meteor deploy staging.meteor.com --settings settings-development.json",
8 10 "production": "meteor deploy production.meteor.com --settings settings-production.json"
9 11 },
10 12 "devDependencies": {},
11 13 "dependencies": {
  14 + "chimp": "^0.33.0",
12 15 "react": "^0.14.8",
13 16 "react-addons-pure-render-mixin": "^0.14.8",
14 17 "react-bootstrap": "^0.28.4",
... ...
... ... @@ -0,0 +1,30 @@
  1 +describe( 'Log In', function() {
  2 + beforeEach( function() {
  3 + server.execute( function() {
  4 + var user = Meteor.users.findOne( { 'emails.address': 'carl.winslow@abc.com' } );
  5 + if ( user ) {
  6 + Meteor.users.remove( user._id );
  7 + }
  8 + });
  9 + });
  10 +
  11 + it( 'should allow us to login @watch', function() {
  12 + server.execute( function() {
  13 + Accounts.createUser({
  14 + email: 'carl.winslow@abc.com',
  15 + password: 'bigguy1989',
  16 + profile: {
  17 + name: { first: 'Carl', last: 'Winslow' }
  18 + }
  19 + });
  20 + });
  21 +
  22 + browser.url( 'http://localhost:3000/login' )
  23 + .setValue( '[name="emailAddress"]', 'carl.winslow@abc.com' )
  24 + .setValue( '[name="password"]', 'bigguy1989' )
  25 + .submitForm( 'form' );
  26 +
  27 + browser.waitForExist( '.jumbotron' );
  28 + expect( browser.getUrl() ).to.equal( 'http://localhost:3000/' );
  29 + });
  30 +});
... ...
... ... @@ -0,0 +1,22 @@
  1 +describe( 'Sign Up', function() {
  2 + beforeEach( function() {
  3 + server.execute( function() {
  4 + var user = Meteor.users.findOne( { 'emails.address': 'carl.winslow@abc.com' } );
  5 + if ( user ) {
  6 + Meteor.users.remove( user._id );
  7 + }
  8 + });
  9 + });
  10 +
  11 + it( 'should create a new user and login with redirect to index @watch', function() {
  12 + browser.url( 'http://localhost:3000/signup' )
  13 + .setValue( '[name="firstName"]', 'Carl' )
  14 + .setValue( '[name="lastName"]', 'Winslow' )
  15 + .setValue( '[name="emailAddress"]', 'carl.winslow@abc.com' )
  16 + .setValue( '[name="password"]', 'bigguy1989' )
  17 + .submitForm( 'form' );
  18 +
  19 + browser.waitForExist( '.jumbotron' );
  20 + expect( browser.getUrl() ).to.equal( 'http://localhost:3000/' );
  21 + });
  22 +});
... ...