From a90d63f594e733bf902a3b9b2e520dd0933dc954 Mon Sep 17 00:00:00 2001 From: remyyounes Date: Fri, 26 Jul 2013 22:02:08 -0700 Subject: [PATCH 01/19] adding restler dependency to package.json --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index d4ad104..b6f0954 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,8 @@ "dependencies": { "express": "3.3.4", "ejs": "~0.8.4", - "jade": "*" + "jade": "*", + "restler": "*" }, "scripts": { "test": "grunt test", From c41717dd95d50ae5ab7a13e77bfb72a814290223 Mon Sep 17 00:00:00 2001 From: remyyounes Date: Sat, 27 Jul 2013 15:32:55 -0700 Subject: [PATCH 02/19] githubCfg file, response in JSON, jshint edits.. --- app/scripts/controllers/main.js | 14 +++--- bower.json | 3 +- github.conf.json | 5 ++ server.js | 88 +++++++++++++++++---------------- 4 files changed, 60 insertions(+), 50 deletions(-) create mode 100644 github.conf.json diff --git a/app/scripts/controllers/main.js b/app/scripts/controllers/main.js index 3376807..f5c3656 100644 --- a/app/scripts/controllers/main.js +++ b/app/scripts/controllers/main.js @@ -2,12 +2,12 @@ angular.module('sbjsApp') .controller('MainCtrl', function ($scope, utils) { - console.log("MainCtrl.location: ", location); - console.log("MainCtrl.location.search: ", location.search); - var queryParams = location.search + console.log('MainCtrl.location: ', location); + console.log('MainCtrl.location.search: ', location.search); + var queryParams = location.search; var params = utils.getParamsFromString(location.search); - console.log("MainCtrl.params.code: ", params); - console.log("MainCtrl.params.code: ", params.code); + console.log('MainCtrl.params.code: ', params); + console.log('MainCtrl.params.code: ', params.code); if(params.code){ @@ -20,8 +20,8 @@ angular.module('sbjsApp') ]; }) .controller('AuthCtrl', function ($scope) { - console.log("AuthCtrl.location: ", location); - console.log("AuthCtrl.location.search: ", location.search); + console.log('AuthCtrl.location: ', location); + console.log('AuthCtrl.location.search: ', location.search); // http://localhost/?code=537fb3f6697752be4951 $scope.awesomeThings = [ diff --git a/bower.json b/bower.json index 829c3c2..86293ec 100644 --- a/bower.json +++ b/bower.json @@ -9,7 +9,8 @@ "es5-shim": "~2.0.8", "angular-resource": "~1.0.7", "angular-cookies": "~1.0.7", - "angular-sanitize": "~1.0.7" + "angular-sanitize": "~1.0.7", + "angular-bootstrap": "*" }, "devDependencies": { "angular-mocks": "~1.0.7", diff --git a/github.conf.json b/github.conf.json new file mode 100644 index 0000000..5d4a98d --- /dev/null +++ b/github.conf.json @@ -0,0 +1,5 @@ +{ + "client_id": "f9aa961f63df8c7b766a", + "redirect_uri":"", + "client_secret": "CUT_AND_PASTE YOUR CLIENT SECRET HERE. ACTUALLY USE THE BUILD SCRIPTS DONT CHECK THIS IN!" +} diff --git a/server.js b/server.js index 40a630f..ee025dd 100644 --- a/server.js +++ b/server.js @@ -1,14 +1,16 @@ +'use strict'; /** * Module dependencies. */ -var express = require('express') - , routes = require('./routes') - , user = require('./routes/user') - , http = require('http') - , path = require('path') - , rest = require('restler'); +var express = require('express'), + routes = require('./routes'), + user = require('./routes/user'), + http = require('http'), + path = require('path'), + rest = require('restler'), + githubCfg = require('./github.conf.json'); var app = express(); @@ -28,19 +30,18 @@ app.use(app.router); // development only -if ('development' == app.get('env')) { - console.log("\n**** RUNNING IN DEVELOPMENT ENV ****\n") - app.use(express.errorHandler()); - app.set('views', __dirname + '/app'); - app.use(express.static(path.join(__dirname, 'app'))); -} -else { - console.log("ENV: ", app.get('env')) - console.log("\n**** RUNNING IN PRODUCTION ENV ****\n") - console.log("\n**** WHICH MEANS OUT OF DIST DIRECTORY! ****\n") - app.use(express.errorHandler()); - app.set('views', __dirname + '/dist'); - app.use(express.static(path.join(__dirname, 'dist'))); +if ('development' === app.get('env')) { + console.log('\n**** RUNNING IN DEVELOPMENT ENV ****\n'); + app.use(express.errorHandler()); + app.set('views', __dirname + '/app'); + app.use(express.static(path.join(__dirname, 'app'))); +}else{ + console.log('ENV: ', app.get('env')); + console.log('\n**** RUNNING IN PRODUCTION ENV ****\n'); + console.log('\n**** WHICH MEANS OUT OF DIST DIRECTORY! ****\n'); + app.use(express.errorHandler()); + app.set('views', __dirname + '/dist'); + app.use(express.static(path.join(__dirname, 'dist'))); } // If you want to use node and express, here are some examples @@ -53,29 +54,32 @@ else { // we could configure this to run in dev vs production. But make sure the default is for // production, as that is what azure will use to run the app app.get('/', function(request, response) { - var code= request.query.code; - - if(code){ - console.log("CODE: ", code); - - var data = { - client_id: 'f9aa961f63df8c7b766a', - //redirect_uri: '', - client_secret: 'CUT_AND_PASTE YOUR CLIENT SECRET HERE. ACTUALLY USE THE BUILD SCRIPTS DONT CHECK THIS IN!', - code: code - }; - rest.post('https://github.com/login/oauth/access_token', data) - .on('complete', function(data, response){ - console.log("DONE:", data) - if (response.statusCode == 200){ - console.log(data); // prints HTML - console.log("access_token", data.access_token); // prints HTML - - } - }); - } - - response.render('index.html') + var code = request.query.code; + + if(code){ + console.log('CODE: ', code); + + var options = { + 'data':{ + 'client_id': githubCfg.client_id, + 'client_secret': githubCfg.client_secret, + 'code': code + }, + 'headers':{ + 'Accept': 'application/json' + } + }; + + rest.post('https://github.com/login/oauth/access_token', options) + .on('complete', function(data, response){ + console.log('DONE:', data); + if (response.statusCode == 200){ + console.log(data); // prints HTML + console.log('access_token', data.access_token); // prints HTML + } + }); + } + response.render('index.html'); }); From 9e13c4f1b48aef155f5a3d4251de9239d0e64361 Mon Sep 17 00:00:00 2001 From: remyyounes Date: Sun, 28 Jul 2013 02:34:12 -0700 Subject: [PATCH 03/19] Github Profile working prototype + JsHint reformatting --- README.md | 2 +- app/index.html | 1 + app/scripts/app.js | 3 ++- app/scripts/controllers/main.js | 41 +++++++++--------------------- app/scripts/controllers/profile.js | 24 +++++++++++++++++ app/scripts/lib/utils.js | 35 ++++++++++++------------- app/styles/main.css | 10 ++++++++ app/views/main.html | 5 ++-- app/views/profile.html | 20 +++++++++++++++ karma.conf.js | 1 + server.js | 20 +++++++-------- test/spec/controllers/main.js | 3 --- test/spec/controllers/profile.js | 19 ++++++++++++++ 13 files changed, 120 insertions(+), 64 deletions(-) create mode 100644 app/scripts/controllers/profile.js create mode 100644 app/views/profile.html create mode 100644 test/spec/controllers/profile.js diff --git a/README.md b/README.md index 0575946..0f7ae2e 100644 --- a/README.md +++ b/README.md @@ -44,4 +44,4 @@ Now, issuing a `git remove -v` you should see: ## VoilĂ ! -You should now be able to run `grunt server` +You should now be able to run `grunt server` or `node --debug server.js` if you want node.js with express. diff --git a/app/index.html b/app/index.html index 76f44b8..133ec0a 100644 --- a/app/index.html +++ b/app/index.html @@ -64,6 +64,7 @@ + diff --git a/app/scripts/app.js b/app/scripts/app.js index a7affc8..3a61446 100644 --- a/app/scripts/app.js +++ b/app/scripts/app.js @@ -1,10 +1,11 @@ 'use strict'; -angular.module('sbjsApp', []) +angular.module('sbjsApp', ['ngCookies']) .config(function ($routeProvider) { $routeProvider .when('/', {templateUrl: 'views/main.html',controller: 'MainCtrl'}) .when('/auth', {templateUrl: 'views/auth.html',controller: 'AuthCtrl'}) + .when('/profile', {templateUrl: 'views/profile.html', controller: 'ProfileCtrl'}) .otherwise({ redirectTo: '/' }); diff --git a/app/scripts/controllers/main.js b/app/scripts/controllers/main.js index f5c3656..300a3ad 100644 --- a/app/scripts/controllers/main.js +++ b/app/scripts/controllers/main.js @@ -1,32 +1,15 @@ 'use strict'; angular.module('sbjsApp') - .controller('MainCtrl', function ($scope, utils) { - console.log('MainCtrl.location: ', location); - console.log('MainCtrl.location.search: ', location.search); - var queryParams = location.search; - var params = utils.getParamsFromString(location.search); - console.log('MainCtrl.params.code: ', params); - console.log('MainCtrl.params.code: ', params.code); - - if(params.code){ - - } - // http://localhost/?code=537fb3f6697752be4951 - $scope.awesomeThings = [ - 'HTML5 Boilerplate', - 'AngularJS', - 'Karma' - ]; - }) - .controller('AuthCtrl', function ($scope) { - console.log('AuthCtrl.location: ', location); - console.log('AuthCtrl.location.search: ', location.search); - - // http://localhost/?code=537fb3f6697752be4951 - $scope.awesomeThings = [ - 'HTML5 Boilerplate', - 'AngularJS', - 'Karma' - ]; - }); +.controller('MainCtrl', function ($scope, utils) { + var options = ['client_id=f9aa961f63df8c7b766a','scope=user,user:email,public_repo']; + $scope.githubLoginUrl = 'https://github.com/login/oauth/authorize?'+options.join('&'); + + //debug + console.log('MainCtrl.location: ', location); + console.log('MainCtrl.location.search: ', location.search); + // var queryParams = location.search; + var params = utils.getParamsFromString(location.search); + console.log('MainCtrl.params.code: ', params); + console.log('MainCtrl.params.code: ', params.code); +}); diff --git a/app/scripts/controllers/profile.js b/app/scripts/controllers/profile.js new file mode 100644 index 0000000..1e9146b --- /dev/null +++ b/app/scripts/controllers/profile.js @@ -0,0 +1,24 @@ +'use strict'; + +angular.module('sbjsApp') +.controller('ProfileCtrl', function ($scope, $http, $location, $cookies) { + + //TODO: refactor getToken out of here. or find a more elegant way + $scope.getToken = function(){ + if ($location.search().access_token){ + $cookies.token = $location.search().access_token; + $location.search('access_token', null); + } + // if we dont have a token, redirect to home to authenticate + if(!$cookies.token) { $location.path( '/' ); } + return $cookies.token; + }; + + var token = $scope.getToken(); + $http.get('https://api.github.com/user?access_token='+token).then(function(res){ + $scope.user = res.data; + $scope.user.avatar_url += '&s=420'; + console.log($scope.user); + }); + +}); diff --git a/app/scripts/lib/utils.js b/app/scripts/lib/utils.js index b9b4677..8909f50 100644 --- a/app/scripts/lib/utils.js +++ b/app/scripts/lib/utils.js @@ -1,23 +1,24 @@ 'use strict'; angular.module('sbjsApp') - .service('utils', function(){ - this.getParamsFromString = function (paramString) { - // From: http://stackoverflow.com/a/2880929/39758 - if(paramString.charAt(0) == '?'){ - paramString = paramString.substring(1); - } - var match, - pl = /\+/g, // Regex for replacing addition symbol with a space - search = /([^&=]+)=?([^&]*)/g, - decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); }, - query = paramString,//.substring(1), - urlParams = {}; +.service('utils', function(){ + this.getParamsFromString = function (paramString) { + // From: http://stackoverflow.com/a/2880929/39758 + if(paramString.charAt(0) === '?'){ + paramString = paramString.substring(1); + } + var match, + pl = /\+/g, // Regex for replacing addition symbol with a space + search = /([^&=]+)=?([^&]*)/g, + decode = function (s) { return decodeURIComponent(s.replace(pl, ' ')); }, + query = paramString,//.substring(1), + urlParams = {}; - while (match = search.exec(query)) - urlParams[decode(match[1])] = decode(match[2]); - return urlParams; - }; - }); + while ((match = search.exec(query))){ + urlParams[decode(match[1])] = decode(match[2]); + } + return urlParams; + }; +}); diff --git a/app/styles/main.css b/app/styles/main.css index c754fdd..4e94f3a 100644 --- a/app/styles/main.css +++ b/app/styles/main.css @@ -19,4 +19,14 @@ body { font-size: 60px; line-height: 1; letter-spacing: -1px; + margin: 10px auto; } + +.profile { + width: 430px; +} + +.profile table tr th{ + text-align: left; + width: 150px; +} \ No newline at end of file diff --git a/app/views/main.html b/app/views/main.html index 6268c86..c8b6c67 100644 --- a/app/views/main.html +++ b/app/views/main.html @@ -1,5 +1,4 @@
-

Welcome to SBJS

-

Login to Github

-

Pretend Token

+

Welcome to SBJS

+ Login to Github
diff --git a/app/views/profile.html b/app/views/profile.html new file mode 100644 index 0000000..ed040f5 --- /dev/null +++ b/app/views/profile.html @@ -0,0 +1,20 @@ +
+ +

{{user.login}}

+
+ + + + + + + + + + + + + +
Name:{{user.name}}
Public Repos:{{user.public_repos}}
Location:{{user.location}}
+
+
diff --git a/karma.conf.js b/karma.conf.js index 2d6194b..e16108c 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -9,6 +9,7 @@ files = [ JASMINE_ADAPTER, 'app/bower_components/angular/angular.js', 'app/bower_components/angular-mocks/angular-mocks.js', + 'app/bower_components/angular-cookies/angular-cookies.js', 'app/scripts/*.js', 'app/scripts/**/*.js', 'test/mock/**/*.js', diff --git a/server.js b/server.js index ee025dd..6ec4547 100644 --- a/server.js +++ b/server.js @@ -26,6 +26,8 @@ app.use(express.favicon()); app.use(express.logger('dev')); app.use(express.bodyParser()); app.use(express.methodOverride()); +app.use(express.cookieParser()); +app.use(express.session({secret: 'sbjsSecretHash'})); app.use(app.router); @@ -54,11 +56,10 @@ if ('development' === app.get('env')) { // we could configure this to run in dev vs production. But make sure the default is for // production, as that is what azure will use to run the app app.get('/', function(request, response) { - var code = request.query.code; + var code = request.query.code; + //TODO: refactor? if(code){ - console.log('CODE: ', code); - var options = { 'data':{ 'client_id': githubCfg.client_id, @@ -71,18 +72,17 @@ app.get('/', function(request, response) { }; rest.post('https://github.com/login/oauth/access_token', options) - .on('complete', function(data, response){ - console.log('DONE:', data); - if (response.statusCode == 200){ - console.log(data); // prints HTML - console.log('access_token', data.access_token); // prints HTML + .on('complete', function(data, resp){ + if (resp.statusCode == 200){ + request.session.access_token = data.access_token; + response.redirect('/#/profile?access_token='+data.access_token); } }); + }else{ + response.render('index.html'); } - response.render('index.html'); }); - var port = process.env.PORT || 9000; // var port = app.get('port') diff --git a/test/spec/controllers/main.js b/test/spec/controllers/main.js index 6129950..3e53161 100644 --- a/test/spec/controllers/main.js +++ b/test/spec/controllers/main.js @@ -16,7 +16,4 @@ describe('Controller: MainCtrl', function () { }); })); - it('should attach a list of awesomeThings to the scope', function () { - expect(scope.awesomeThings.length).toBe(3); - }); }); diff --git a/test/spec/controllers/profile.js b/test/spec/controllers/profile.js new file mode 100644 index 0000000..db71718 --- /dev/null +++ b/test/spec/controllers/profile.js @@ -0,0 +1,19 @@ +'use strict'; + +describe('Controller: ProfileCtrl', function () { + + // load the controller's module + beforeEach(module('sbjsApp')); + + var ProfileCtrl, + scope; + + // Initialize the controller and a mock scope + beforeEach(inject(function ($controller, $rootScope) { + scope = $rootScope.$new(); + ProfileCtrl = $controller('ProfileCtrl', { + $scope: scope + }); + })); + +}); From 3a80a1ef6902a50ad0c5f66e88024638d1efeb32 Mon Sep 17 00:00:00 2001 From: remyyounes Date: Sun, 28 Jul 2013 13:28:54 -0700 Subject: [PATCH 04/19] Nav test --- app/index.html | 16 +++++++++++++++- app/scripts/app.js | 2 +- bower.json | 4 +++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/app/index.html b/app/index.html index 133ec0a..d55b072 100644 --- a/app/index.html +++ b/app/index.html @@ -32,6 +32,18 @@ + + +
@@ -57,7 +69,9 @@ - + + + diff --git a/app/scripts/app.js b/app/scripts/app.js index 3a61446..5531bfd 100644 --- a/app/scripts/app.js +++ b/app/scripts/app.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('sbjsApp', ['ngCookies']) +angular.module('sbjsApp', ['ngCookies','$strap.directives']) .config(function ($routeProvider) { $routeProvider .when('/', {templateUrl: 'views/main.html',controller: 'MainCtrl'}) diff --git a/bower.json b/bower.json index 86293ec..86f87a8 100644 --- a/bower.json +++ b/bower.json @@ -10,7 +10,9 @@ "angular-resource": "~1.0.7", "angular-cookies": "~1.0.7", "angular-sanitize": "~1.0.7", - "angular-bootstrap": "*" + "angular-bootstrap": "*", + "angular-strap": "*" + }, "devDependencies": { "angular-mocks": "~1.0.7", From a433240dd3be0604d90fd864c2620a8185a484d4 Mon Sep 17 00:00:00 2001 From: remyyounes Date: Sun, 28 Jul 2013 17:02:49 -0700 Subject: [PATCH 05/19] Members page + refactor getToken --- app/index.html | 4 ++++ app/scripts/app.js | 1 + app/scripts/controllers/members.js | 10 ++++++++++ app/scripts/controllers/profile.js | 15 ++------------- app/scripts/lib/utils.js | 14 +++++++++++++- app/styles/main.css | 19 ++++++++++++++++++- app/views/members.html | 9 +++++++++ app/views/profile.html | 8 ++++---- bower.json | 3 ++- test/spec/controllers/members.js | 22 ++++++++++++++++++++++ 10 files changed, 85 insertions(+), 20 deletions(-) create mode 100644 app/scripts/controllers/members.js create mode 100644 app/views/members.html create mode 100644 test/spec/controllers/members.js diff --git a/app/index.html b/app/index.html index d55b072..ee17329 100644 --- a/app/index.html +++ b/app/index.html @@ -38,6 +38,8 @@ SBJS.org @@ -72,6 +74,7 @@ + @@ -79,6 +82,7 @@ + diff --git a/app/scripts/app.js b/app/scripts/app.js index 5531bfd..c951344 100644 --- a/app/scripts/app.js +++ b/app/scripts/app.js @@ -6,6 +6,7 @@ angular.module('sbjsApp', ['ngCookies','$strap.directives']) .when('/', {templateUrl: 'views/main.html',controller: 'MainCtrl'}) .when('/auth', {templateUrl: 'views/auth.html',controller: 'AuthCtrl'}) .when('/profile', {templateUrl: 'views/profile.html', controller: 'ProfileCtrl'}) + .when('/members', {templateUrl: 'views/members.html', controller: 'MembersCtrl'}) .otherwise({ redirectTo: '/' }); diff --git a/app/scripts/controllers/members.js b/app/scripts/controllers/members.js new file mode 100644 index 0000000..9a5dcf9 --- /dev/null +++ b/app/scripts/controllers/members.js @@ -0,0 +1,10 @@ +'use strict'; + +angular.module('sbjsApp') +.controller('MembersCtrl', function ($scope, $http, utils) { + var token = utils.getToken(); + $http.get('https://api.github.com/repos/sbjs/sbjs.org/forks?access_token='+token).then(function(res){ + $scope.members = _.pluck(res.data, 'owner'); + }); + +}); diff --git a/app/scripts/controllers/profile.js b/app/scripts/controllers/profile.js index 1e9146b..5b3b8f2 100644 --- a/app/scripts/controllers/profile.js +++ b/app/scripts/controllers/profile.js @@ -1,20 +1,9 @@ 'use strict'; angular.module('sbjsApp') -.controller('ProfileCtrl', function ($scope, $http, $location, $cookies) { +.controller('ProfileCtrl', function ($scope, $http, utils) { - //TODO: refactor getToken out of here. or find a more elegant way - $scope.getToken = function(){ - if ($location.search().access_token){ - $cookies.token = $location.search().access_token; - $location.search('access_token', null); - } - // if we dont have a token, redirect to home to authenticate - if(!$cookies.token) { $location.path( '/' ); } - return $cookies.token; - }; - - var token = $scope.getToken(); + var token = utils.getToken(); $http.get('https://api.github.com/user?access_token='+token).then(function(res){ $scope.user = res.data; $scope.user.avatar_url += '&s=420'; diff --git a/app/scripts/lib/utils.js b/app/scripts/lib/utils.js index 8909f50..fdf2af8 100644 --- a/app/scripts/lib/utils.js +++ b/app/scripts/lib/utils.js @@ -1,7 +1,19 @@ 'use strict'; angular.module('sbjsApp') -.service('utils', function(){ +.service('utils', function($cookies, $location){ + + // Still trying to find a good way of handling tokens + this.getToken = function(){ + if ($location.search().access_token){ + $cookies.token = $location.search().access_token; + $location.search('access_token', null); + } + // if we dont have a token, redirect to home to authenticate + if(!$cookies.token) { $location.path( '/' ); } + return $cookies.token; + }; + this.getParamsFromString = function (paramString) { // From: http://stackoverflow.com/a/2880929/39758 if(paramString.charAt(0) === '?'){ diff --git a/app/styles/main.css b/app/styles/main.css index 4e94f3a..a9ca81f 100644 --- a/app/styles/main.css +++ b/app/styles/main.css @@ -29,4 +29,21 @@ body { .profile table tr th{ text-align: left; width: 150px; -} \ No newline at end of file +} + +.members { + width: 400px; +} + +.members li { + list-style: none; +} + +.members li img.thumbnail { + width:80px; + display: inline-block; +} + +.members li h2 { + display: inline-block; +} diff --git a/app/views/members.html b/app/views/members.html new file mode 100644 index 0000000..1198c40 --- /dev/null +++ b/app/views/members.html @@ -0,0 +1,9 @@ +
+

Members

+
    +
  • + +

    {{member.login}}

    +
  • +
+
diff --git a/app/views/profile.html b/app/views/profile.html index ed040f5..cf9057c 100644 --- a/app/views/profile.html +++ b/app/views/profile.html @@ -7,14 +7,14 @@

{{user.login}}

Name: {{user.name}} - - Public Repos: - {{user.public_repos}} - Location: {{user.location}} + + Public Repos: + {{user.public_repos}} + diff --git a/bower.json b/bower.json index 86f87a8..f7167e9 100644 --- a/bower.json +++ b/bower.json @@ -11,7 +11,8 @@ "angular-cookies": "~1.0.7", "angular-sanitize": "~1.0.7", "angular-bootstrap": "*", - "angular-strap": "*" + "angular-strap": "*", + "underscore": "*" }, "devDependencies": { diff --git a/test/spec/controllers/members.js b/test/spec/controllers/members.js new file mode 100644 index 0000000..f4b3d00 --- /dev/null +++ b/test/spec/controllers/members.js @@ -0,0 +1,22 @@ +'use strict'; + +describe('Controller: MembersCtrl', function () { + + // load the controller's module + beforeEach(module('sbjsApp')); + + var MembersCtrl, + scope; + + // Initialize the controller and a mock scope + beforeEach(inject(function ($controller, $rootScope) { + scope = $rootScope.$new(); + MembersCtrl = $controller('MembersCtrl', { + $scope: scope + }); + })); + + it('should attach a list of awesomeThings to the scope', function () { + expect(scope.awesomeThings.length).toBe(3); + }); +}); From d0ea972a814baa918b485a42ffe97441063e4366 Mon Sep 17 00:00:00 2001 From: Jim McGaw Date: Sun, 28 Jul 2013 23:31:23 -0700 Subject: [PATCH 06/19] specs and other checks in code --- app/index.html | 2 +- app/scripts/app.js | 4 ++-- app/scripts/controllers/members.js | 2 +- app/scripts/lib/utils.js | 5 +++-- karma.conf.js | 1 + server.js | 2 +- test/spec/controllers/main.js | 6 ++++++ test/spec/controllers/members.js | 4 ---- test/spec/controllers/profile.js | 6 ++---- test/spec/lib/utils.js | 4 ++++ 10 files changed, 21 insertions(+), 15 deletions(-) create mode 100644 test/spec/lib/utils.js diff --git a/app/index.html b/app/index.html index ee17329..b674e16 100644 --- a/app/index.html +++ b/app/index.html @@ -33,7 +33,7 @@ - @@ -77,6 +77,9 @@ + + + @@ -88,6 +91,7 @@ + diff --git a/app/scripts/app.js b/app/scripts/app.js index a59452e..60d8971 100644 --- a/app/scripts/app.js +++ b/app/scripts/app.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('sbjsApp', ['ngCookies','$strap.directives']) +angular.module('sbjsApp', ['ngCookies','$strap.directives','firebase']) .config(function ($routeProvider, $httpProvider) { $routeProvider .when('/', {templateUrl: 'views/main.html', controller: 'MainCtrl'}) @@ -8,6 +8,10 @@ angular.module('sbjsApp', ['ngCookies','$strap.directives']) .when('/profile', {templateUrl: 'views/profile.html', controller: 'ProfileCtrl'}) .when('/members', {templateUrl: 'views/members.html', controller: 'MembersCtrl'}) .when('/registration', {templateUrl: 'views/registration.html', controller: 'RegistrationCtrl'}) + .when('/fire', { + templateUrl: 'views/fire.html', + controller: 'FireCtrl' + }) .otherwise({redirectTo: '/'}); //Interceptor is used in case the token becomes invalid while the session is active. diff --git a/app/scripts/controllers/fire.js b/app/scripts/controllers/fire.js new file mode 100644 index 0000000..0d3a882 --- /dev/null +++ b/app/scripts/controllers/fire.js @@ -0,0 +1,25 @@ +'use strict'; + +angular.module('sbjsApp') + .controller('FireCtrl', function ($scope, angularFire) { + + $scope.notes = []; + var url = 'https://sbjs.firebaseio.com/notes'; + var promise = angularFire(url, $scope, 'notes', []) + .then( function(todos){ + startWatch($scope); + }); + } +); + + +function startWatch($scope) { + $scope.addNote = function(){ + var note = { + 'githubUserId': 'HardCoded', + 'message': $scope.newMessage + }; + $scope.notes.push(note); + $scope.newMessage = ''; + }; +} diff --git a/app/views/fire.html b/app/views/fire.html new file mode 100644 index 0000000..566cd24 --- /dev/null +++ b/app/views/fire.html @@ -0,0 +1,8 @@ +
+
+

{{note.githubUserId}}

+
{{note.message}}
+
+ + +
diff --git a/bower.json b/bower.json index f7167e9..cde0172 100644 --- a/bower.json +++ b/bower.json @@ -12,8 +12,8 @@ "angular-sanitize": "~1.0.7", "angular-bootstrap": "*", "angular-strap": "*", - "underscore": "*" - + "underscore": "*", + "angular-fire":"*" }, "devDependencies": { "angular-mocks": "~1.0.7", diff --git a/test/spec/controllers/fire.js b/test/spec/controllers/fire.js new file mode 100644 index 0000000..4e81bd3 --- /dev/null +++ b/test/spec/controllers/fire.js @@ -0,0 +1,22 @@ +'use strict'; + +describe('Controller: FireCtrl', function () { + + // load the controller's module + beforeEach(module('sbjsApp')); + + var FireCtrl, + scope; + + // Initialize the controller and a mock scope + beforeEach(inject(function ($controller, $rootScope) { + scope = $rootScope.$new(); + FireCtrl = $controller('FireCtrl', { + $scope: scope + }); + })); + + it('should attach a list of awesomeThings to the scope', function () { + expect(scope.awesomeThings.length).toBe(3); + }); +}); From d02e1d7f0089dcd8b4e63a6f3c9485b4923b73e1 Mon Sep 17 00:00:00 2001 From: Jim McGaw Date: Wed, 31 Jul 2013 22:40:10 -0700 Subject: [PATCH 19/19] specs not passing, but refactor of profile / members fetch into auth module, pass into controllers --- app/scripts/app.js | 15 ++++++------- app/scripts/controllers/members.js | 16 +++----------- app/scripts/controllers/profile.js | 19 ++++------------- app/scripts/services/auth.js | 27 ++++++++++++++++++++++-- app/views/members.html | 6 +++--- app/views/profile.html | 10 ++++----- karma.conf.js | 1 + package.json | 3 ++- test/spec/controllers/fire.js | 3 --- test/spec/controllers/members.js | 14 +++++------- test/spec/controllers/profile.js | 34 ------------------------------ test/spec/services/auth.js | 34 ++++++++++++++++++++++++++++++ 12 files changed, 88 insertions(+), 94 deletions(-) diff --git a/app/scripts/app.js b/app/scripts/app.js index 60d8971..be6924a 100644 --- a/app/scripts/app.js +++ b/app/scripts/app.js @@ -3,15 +3,12 @@ angular.module('sbjsApp', ['ngCookies','$strap.directives','firebase']) .config(function ($routeProvider, $httpProvider) { $routeProvider - .when('/', {templateUrl: 'views/main.html', controller: 'MainCtrl'}) - .when('/auth', {templateUrl: 'views/auth.html', controller: 'AuthCtrl'}) - .when('/profile', {templateUrl: 'views/profile.html', controller: 'ProfileCtrl'}) - .when('/members', {templateUrl: 'views/members.html', controller: 'MembersCtrl'}) - .when('/registration', {templateUrl: 'views/registration.html', controller: 'RegistrationCtrl'}) - .when('/fire', { - templateUrl: 'views/fire.html', - controller: 'FireCtrl' - }) + .when('/', {templateUrl: 'views/main.html', controller: 'MainCtrl' }) + .when('/auth', {templateUrl: 'views/auth.html', controller: 'AuthCtrl' }) + .when('/profile', {templateUrl: 'views/profile.html', controller: 'ProfileCtrl' }) + .when('/members', {templateUrl: 'views/members.html', controller: 'MembersCtrl' }) + .when('/registration', {templateUrl: 'views/registration.html', controller: 'RegistrationCtrl' }) + .when('/fire', { templateUrl: 'views/fire.html', controller: 'FireCtrl' }) .otherwise({redirectTo: '/'}); //Interceptor is used in case the token becomes invalid while the session is active. diff --git a/app/scripts/controllers/members.js b/app/scripts/controllers/members.js index a9dae2d..b2ea374 100644 --- a/app/scripts/controllers/members.js +++ b/app/scripts/controllers/members.js @@ -1,17 +1,7 @@ 'use strict'; angular.module('sbjsApp') -.controller('MembersCtrl', function ($scope, $http, $cookies) { - - $scope.parseMembers = function(result){ - $scope.members = _.pluck(result.data, 'owner'); - }; - - $scope.fetchMembers = function(){ - var url = 'https://api.github.com/repos/sbjs/sbjs.profiles/forks?access_token=' + $cookies.token; - $http.get(url).then($scope.parseMembers); + .controller('MembersCtrl', function($scope, auth){ + $scope.members = auth.fetchMembers(); } - - $scope.fetchMembers(); - -}); +); diff --git a/app/scripts/controllers/profile.js b/app/scripts/controllers/profile.js index 2f3d890..869567d 100644 --- a/app/scripts/controllers/profile.js +++ b/app/scripts/controllers/profile.js @@ -1,18 +1,7 @@ 'use strict'; angular.module('sbjsApp') -.controller('ProfileCtrl', function ($scope, $http, $cookies) { - - $scope.parseUser = function(result) { - $scope.user = result.data; - $scope.user.avatar_url += "&s=420"; - }; - - $scope.fetchUserProfile = function() { - var url = 'https://api.github.com/user?access_token=' + $cookies.token; - $http.get(url).then($scope.parseUser); - }; - - $scope.fetchUserProfile(); - -}); + .controller('ProfileCtrl', function($scope, auth){ + $scope.profile = auth.fetchUserProfile(); + } +); diff --git a/app/scripts/services/auth.js b/app/scripts/services/auth.js index 7141d5b..aa82d9b 100644 --- a/app/scripts/services/auth.js +++ b/app/scripts/services/auth.js @@ -1,7 +1,8 @@ 'use strict'; angular.module('sbjsApp') -.service('auth', function auth($cookies, $location) { +.service('auth', function auth($cookies, $http, $location) { + this.GITHUB_BASE_URL = "https://api.github.com"; this.getToken = function(){ var access_token = $location.search().access_token; @@ -10,8 +11,30 @@ angular.module('sbjsApp') $location.search('access_token', null); } // if we dont have a token, redirect to home to authenticate - if(!$cookies.token) { $location.path( '/' ); } + if(!$cookies.token) { + $location.path( '/' ); + } return $cookies.token; }; + this.parseUser = function(result){ + var user = result.data; + user.avatar_url += "&s=420"; + return user; + }; + + this.fetchUserProfile = function(){ + var url = this.GITHUB_BASE_URL + '/user?access_token=' + this.getToken(); + return $http.get(url).then(this.parseUser); + }; + + this.parseMembers = function(result){ + return _.pluck(result.data, 'owner'); + }; + + this.fetchMembers = function(){ + var url = this.GITHUB_BASE_URL + '/repos/sbjs/sbjs.profiles/forks?access_token=' + this.getToken(); + return $http.get(url).then(this.parseMembers); + } + }); diff --git a/app/views/members.html b/app/views/members.html index 0968a79..82b3b0a 100644 --- a/app/views/members.html +++ b/app/views/members.html @@ -2,9 +2,9 @@

Members

diff --git a/app/views/profile.html b/app/views/profile.html index cf9057c..41c1fc0 100644 --- a/app/views/profile.html +++ b/app/views/profile.html @@ -1,19 +1,19 @@
- -

{{user.login}}

+ +

{{profile.login}}

- + - + - +
Name:{{user.name}}{{profile.name}}
Location:{{user.location}}{{profile.location}}
Public Repos:{{user.public_repos}}{{profile.public_repos}}
diff --git a/karma.conf.js b/karma.conf.js index 5796820..758499a 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -12,6 +12,7 @@ files = [ 'app/bower_components/angular-cookies/angular-cookies.js', 'app/bower_components/angular-strap/dist/angular-strap.js', 'app/bower_components/underscore/underscore.js', + 'app/bower_components/angular-fire/angularFire.js', 'app/scripts/*.js', 'app/scripts/**/*.js', 'test/mock/**/*.js', diff --git a/package.json b/package.json index b6f0954..12360f0 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,8 @@ "express": "3.3.4", "ejs": "~0.8.4", "jade": "*", - "restler": "*" + "restler": "*", + "firebase" : "0.6.1" }, "scripts": { "test": "grunt test", diff --git a/test/spec/controllers/fire.js b/test/spec/controllers/fire.js index 4e81bd3..6fbcae1 100644 --- a/test/spec/controllers/fire.js +++ b/test/spec/controllers/fire.js @@ -16,7 +16,4 @@ describe('Controller: FireCtrl', function () { }); })); - it('should attach a list of awesomeThings to the scope', function () { - expect(scope.awesomeThings.length).toBe(3); - }); }); diff --git a/test/spec/controllers/members.js b/test/spec/controllers/members.js index 32c9465..b11947e 100644 --- a/test/spec/controllers/members.js +++ b/test/spec/controllers/members.js @@ -10,22 +10,18 @@ describe('Controller: MembersCtrl', function () { // Initialize the controller and a mock scope beforeEach(inject(function ($controller, $rootScope, $http, $cookies) { - cookies = $cookies; - http = $http; scope = $rootScope.$new(); - // stubbing here so constructor does not trigger HTTP GET request - getSpy = spyOn(http, "get"); - getSpy.andReturn({ then: jasmine.createSpy("then") }); - MembersCtrl = $controller('MembersCtrl', { - $scope: scope, - $http: http, - $cookies : cookies + $scope: scope }); })); + it("has members defined", function() { + expect(scope.members).toBeDefined(); + }); + describe("#parseMembers", function() { it("parses owner objects out of result data", function() { expect(scope.members).not.toBeDefined(); diff --git a/test/spec/controllers/profile.js b/test/spec/controllers/profile.js index 0328e45..3aeb7e1 100644 --- a/test/spec/controllers/profile.js +++ b/test/spec/controllers/profile.js @@ -23,38 +23,4 @@ describe('Controller: ProfileCtrl', function () { }); })); - describe("#parseUser", function() { - it("parses the user data from results", function() { - expect(scope.user).not.toBeDefined(); - - var result = { - data : { - "name" : "myName", - "avatar_url" : "http://www.avatar_url.com/?arg1=456" - } - }; - - scope.parseUser(result); - - result.data.avatar_url += "&s=420"; - expect(scope.user).toEqual(result.data); - }); - }); - - describe("#fetchUserProfile", function() { - it("fetches user profile data from git URL", function() { - cookies.token = "f7djv6d5susnrn4nw"; - var thenSpy = jasmine.createSpy("then"); - getSpy.andReturn({ - "then" : thenSpy - }); - var url = 'https://api.github.com/user?access_token=' + cookies.token; - - scope.fetchUserProfile(); - - expect(http.get).toHaveBeenCalledWith(url); - expect(thenSpy).toHaveBeenCalledWith(scope.parseUser); - }); - }); - }); diff --git a/test/spec/services/auth.js b/test/spec/services/auth.js index 345dcd9..1da692e 100644 --- a/test/spec/services/auth.js +++ b/test/spec/services/auth.js @@ -15,4 +15,38 @@ describe('Service: auth', function () { expect(!!auth).toBe(true); }); + describe("#parseUser", function() { + it("parses the user data from results", function() { + expect(scope.user).not.toBeDefined(); + + var result = { + data : { + "name" : "myName", + "avatar_url" : "http://www.avatar_url.com/?arg1=456" + } + }; + + scope.parseUser(result); + + result.data.avatar_url += "&s=420"; + expect(scope.user).toEqual(result.data); + }); + }); + + describe("#fetchUserProfile", function() { + it("fetches user profile data from git URL", function() { + cookies.token = "f7djv6d5susnrn4nw"; + var thenSpy = jasmine.createSpy("then"); + getSpy.andReturn({ + "then" : thenSpy + }); + var url = 'https://api.github.com/user?access_token=' + cookies.token; + + scope.fetchUserProfile(); + + expect(http.get).toHaveBeenCalledWith(url); + expect(thenSpy).toHaveBeenCalledWith(scope.parseUser); + }); + }); + });