diff --git a/modules/articles/client/articles.client.module.js b/modules/articles/client/articles.client.module.js index 3c94d0cb57..a425ccf79e 100644 --- a/modules/articles/client/articles.client.module.js +++ b/modules/articles/client/articles.client.module.js @@ -2,3 +2,5 @@ // Use Applicaion configuration module to register a new module ApplicationConfiguration.registerModule('articles'); +ApplicationConfiguration.registerModule('articles.admin', ['core.admin']); +ApplicationConfiguration.registerModule('articles.admin.routes', ['core.admin.routes']); diff --git a/modules/articles/client/config/articles-admin.client.config.js b/modules/articles/client/config/articles-admin.client.config.js new file mode 100644 index 0000000000..4746c4cab5 --- /dev/null +++ b/modules/articles/client/config/articles-admin.client.config.js @@ -0,0 +1,11 @@ +'use strict'; + +// Configuring the Articles module +angular.module('articles.admin').run(['Menus', + function (Menus) { + Menus.addSubMenuItem('topbar', 'admin', { + title: 'Manage Articles', + state: 'admin.articles.list' + }); + } +]); diff --git a/modules/articles/client/config/articles-admin.client.routes.js b/modules/articles/client/config/articles-admin.client.routes.js new file mode 100644 index 0000000000..3370cfc87b --- /dev/null +++ b/modules/articles/client/config/articles-admin.client.routes.js @@ -0,0 +1,37 @@ +'use strict'; + +// Setting up route +angular.module('articles.admin.routes').config(['$stateProvider', + function ($stateProvider) { + $stateProvider + .state('admin.articles', { + abstract: true, + url: '/articles', + template: '' + }) + .state('admin.articles.list', { + url: '', + templateUrl: 'modules/articles/client/views/admin/list-articles.client.view.html', + controller: 'ArticlesAdminController', + data: { + roles: ['admin'] + } + }) + .state('admin.articles.create', { + url: '/create', + templateUrl: 'modules/articles/client/views/admin/create-article.client.view.html', + controller: 'ArticlesAdminController', + data: { + roles: ['admin'] + } + }) + .state('admin.articles.edit', { + url: '/:articleId/edit', + templateUrl: 'modules/articles/client/views/admin/edit-article.client.view.html', + controller: 'ArticlesAdminController', + data: { + roles: ['admin'] + } + }); + } +]); diff --git a/modules/articles/client/config/articles.client.config.js b/modules/articles/client/config/articles.client.config.js index c44990dc9e..bc6035dbb3 100644 --- a/modules/articles/client/config/articles.client.config.js +++ b/modules/articles/client/config/articles.client.config.js @@ -14,14 +14,8 @@ angular.module('articles').run(['Menus', // Add the dropdown list item Menus.addSubMenuItem('topbar', 'articles', { title: 'List Articles', - state: 'articles.list' - }); - - // Add the dropdown create item - Menus.addSubMenuItem('topbar', 'articles', { - title: 'Create Articles', - state: 'articles.create', - roles: ['user'] + state: 'articles.list', + roles: ['*'] }); } ]); diff --git a/modules/articles/client/config/articles.client.routes.js b/modules/articles/client/config/articles.client.routes.js index 6938867d90..f8d3c8105c 100644 --- a/modules/articles/client/config/articles.client.routes.js +++ b/modules/articles/client/config/articles.client.routes.js @@ -5,32 +5,18 @@ angular.module('articles').config(['$stateProvider', function ($stateProvider) { // Articles state routing $stateProvider - .state('articles', { - abstract: true, - url: '/articles', - template: '' - }) - .state('articles.list', { - url: '', - templateUrl: 'modules/articles/client/views/list-articles.client.view.html' - }) - .state('articles.create', { - url: '/create', - templateUrl: 'modules/articles/client/views/create-article.client.view.html', - data: { - roles: ['user', 'admin'] - } - }) - .state('articles.view', { - url: '/:articleId', - templateUrl: 'modules/articles/client/views/view-article.client.view.html' - }) - .state('articles.edit', { - url: '/:articleId/edit', - templateUrl: 'modules/articles/client/views/edit-article.client.view.html', - data: { - roles: ['user', 'admin'] - } - }); + .state('articles', { + abstract: true, + url: '/articles', + template: '' + }) + .state('articles.list', { + url: '', + templateUrl: 'modules/articles/client/views/list-articles.client.view.html' + }) + .state('articles.view', { + url: '/:articleId', + templateUrl: 'modules/articles/client/views/view-article.client.view.html' + }); } ]); diff --git a/modules/articles/client/controllers/admin.articles.client.controller.js b/modules/articles/client/controllers/admin.articles.client.controller.js new file mode 100644 index 0000000000..c8930df44a --- /dev/null +++ b/modules/articles/client/controllers/admin.articles.client.controller.js @@ -0,0 +1,70 @@ +'use strict'; + +// Articles controller +angular.module('articles.admin').controller('ArticlesAdminController', ['$scope', '$stateParams', '$state', 'Authentication', 'Articles', + function ($scope, $stateParams, $state, Authentication, Articles) { + $scope.authentication = Authentication; + + // Create new Article + $scope.create = function () { + // Create new Article object + var article = new Articles({ + title: this.title, + content: this.content + }); + + // Redirect after save + article.$save(function (response) { + $state.go('admin.articles.list'); + + // Clear form fields + $scope.title = ''; + $scope.content = ''; + }, function (errorResponse) { + $scope.error = errorResponse.data.message; + }); + }; + + // Remove existing Article + $scope.remove = function (article) { + if (confirm('Are you sure you want to delete this article?')) { + if (article) { + article.$remove(); + + for (var i in $scope.articles) { + if ($scope.articles[i] === article) { + $scope.articles.splice(i, 1); + } + } + } else { + $scope.article.$remove(function () { + $state.go('admin.articles.list'); + }); + } + } + }; + + // Update existing Article + $scope.update = function () { + var article = $scope.article; + + article.$update(function () { + $state.go('admin.articles.list'); + }, function (errorResponse) { + $scope.error = errorResponse.data.message; + }); + }; + + // Find a list of Articles + $scope.find = function () { + $scope.articles = Articles.query(); + }; + + // Find existing Article + $scope.findOne = function () { + $scope.article = Articles.get({ + articleId: $stateParams.articleId + }); + }; + } +]); diff --git a/modules/articles/client/controllers/articles.client.controller.js b/modules/articles/client/controllers/articles.client.controller.js index 4a47d5a27b..e79ba8b5e2 100644 --- a/modules/articles/client/controllers/articles.client.controller.js +++ b/modules/articles/client/controllers/articles.client.controller.js @@ -1,58 +1,10 @@ 'use strict'; // Articles controller -angular.module('articles').controller('ArticlesController', ['$scope', '$stateParams', '$location', 'Authentication', 'Articles', - function ($scope, $stateParams, $location, Authentication, Articles) { +angular.module('articles').controller('ArticlesController', ['$scope', '$stateParams', 'Authentication', 'Articles', + function ($scope, $stateParams, Authentication, Articles) { $scope.authentication = Authentication; - // Create new Article - $scope.create = function () { - // Create new Article object - var article = new Articles({ - title: this.title, - content: this.content - }); - - // Redirect after save - article.$save(function (response) { - $location.path('articles/' + response._id); - - // Clear form fields - $scope.title = ''; - $scope.content = ''; - }, function (errorResponse) { - $scope.error = errorResponse.data.message; - }); - }; - - // Remove existing Article - $scope.remove = function (article) { - if (article) { - article.$remove(); - - for (var i in $scope.articles) { - if ($scope.articles[i] === article) { - $scope.articles.splice(i, 1); - } - } - } else { - $scope.article.$remove(function () { - $location.path('articles'); - }); - } - }; - - // Update existing Article - $scope.update = function () { - var article = $scope.article; - - article.$update(function () { - $location.path('articles/' + article._id); - }, function (errorResponse) { - $scope.error = errorResponse.data.message; - }); - }; - // Find a list of Articles $scope.find = function () { $scope.articles = Articles.query(); diff --git a/modules/articles/client/views/admin/create-article.client.view.html b/modules/articles/client/views/admin/create-article.client.view.html new file mode 100644 index 0000000000..b24b91959e --- /dev/null +++ b/modules/articles/client/views/admin/create-article.client.view.html @@ -0,0 +1,29 @@ +
+ +
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+
+ +
+
+
+
+
diff --git a/modules/articles/client/views/admin/edit-article.client.view.html b/modules/articles/client/views/admin/edit-article.client.view.html new file mode 100644 index 0000000000..948540e99f --- /dev/null +++ b/modules/articles/client/views/admin/edit-article.client.view.html @@ -0,0 +1,34 @@ +
+ +
+
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+
+ +
+
+
+
+
diff --git a/modules/articles/client/views/admin/list-articles.client.view.html b/modules/articles/client/views/admin/list-articles.client.view.html new file mode 100644 index 0000000000..6a87f48ddd --- /dev/null +++ b/modules/articles/client/views/admin/list-articles.client.view.html @@ -0,0 +1,25 @@ +
+ + +
+ No articles yet, why don't you create one? +
+
diff --git a/modules/articles/client/views/list-articles.client.view.html b/modules/articles/client/views/list-articles.client.view.html index 689c9c030a..41c139ba4b 100644 --- a/modules/articles/client/views/list-articles.client.view.html +++ b/modules/articles/client/views/list-articles.client.view.html @@ -14,7 +14,4 @@

-
- No articles yet, why don't you create one? -
diff --git a/modules/articles/client/views/view-article.client.view.html b/modules/articles/client/views/view-article.client.view.html index 83a0c40b89..50d22db287 100644 --- a/modules/articles/client/views/view-article.client.view.html +++ b/modules/articles/client/views/view-article.client.view.html @@ -2,14 +2,6 @@ - Posted on diff --git a/modules/articles/server/policies/articles.server.policy.js b/modules/articles/server/policies/articles.server.policy.js index 536f8bccb1..b2dc847c75 100644 --- a/modules/articles/server/policies/articles.server.policy.js +++ b/modules/articles/server/policies/articles.server.policy.js @@ -25,7 +25,7 @@ exports.invokeRolesPolicies = function () { roles: ['user'], allows: [{ resources: '/api/articles', - permissions: ['get', 'post'] + permissions: ['get'] }, { resources: '/api/articles/:articleId', permissions: ['get'] diff --git a/modules/articles/tests/client/admin.articles.client.controller.tests.js b/modules/articles/tests/client/admin.articles.client.controller.tests.js new file mode 100644 index 0000000000..6550e67730 --- /dev/null +++ b/modules/articles/tests/client/admin.articles.client.controller.tests.js @@ -0,0 +1,220 @@ +'use strict'; + +(function () { + // Articles Admin Controller Spec + describe('Articles Admin Controller Tests', function () { + // Initialize global variables + var ArticlesAdminController, + scope, + $httpBackend, + $stateParams, + $location, + $window, + Authentication, + Articles, + mockArticle; + + // The $resource service augments the response object with methods for updating and deleting the resource. + // If we were to use the standard toEqual matcher, our tests would fail because the test values would not match + // the responses exactly. To solve the problem, we define a new toEqualData Jasmine matcher. + // When the toEqualData matcher compares two objects, it takes only object properties into + // account and ignores methods. + beforeEach(function () { + jasmine.addMatchers({ + toEqualData: function (util, customEqualityTesters) { + return { + compare: function (actual, expected) { + return { + pass: angular.equals(actual, expected) + }; + } + }; + } + }); + }); + + // Then we can start by loading the main application module + beforeEach(module(ApplicationConfiguration.applicationModuleName)); + + // The injector ignores leading and trailing underscores here (i.e. _$httpBackend_). + // This allows us to inject a service but then attach it to a variable + // with the same name as the service. + beforeEach(inject(function ($controller, $rootScope, _$location_, _$window_, _$stateParams_, _$httpBackend_, _Authentication_, _Articles_) { + // Set a new global scope + scope = $rootScope.$new(); + + // Point global variables to injected services + $stateParams = _$stateParams_; + $httpBackend = _$httpBackend_; + $location = _$location_; + $window = _$window_; + Authentication = _Authentication_; + Articles = _Articles_; + + // create mock article + mockArticle = new Articles({ + _id: '525a8422f6d0f87f0e407a33', + title: 'An Article about MEAN', + content: 'MEAN rocks!' + }); + + // Mock logged in user + Authentication.user = { + roles: ['user', 'admin'] + }; + + // Initialize the Articles controller. + ArticlesAdminController = $controller('ArticlesAdminController', { + $scope: scope + }); + })); + + it('$scope.find() should create an array with at least one article object fetched from XHR', inject(function (Articles) { + // Create a sample articles array that includes the new article + var sampleArticles = [mockArticle]; + + // Set GET response + $httpBackend.expectGET('api/articles').respond(sampleArticles); + + // Run controller functionality + scope.find(); + $httpBackend.flush(); + + // Test scope value + expect(scope.articles).toEqualData(sampleArticles); + })); + + it('$scope.findOne() should create an array with one article object fetched from XHR using a articleId URL parameter', inject(function (Articles) { + // Set the URL parameter + $stateParams.articleId = mockArticle._id; + + // Set GET response + $httpBackend.expectGET(/api\/articles\/([0-9a-fA-F]{24})$/).respond(mockArticle); + + // Run controller functionality + scope.findOne(); + $httpBackend.flush(); + + // Test scope value + expect(scope.article).toEqualData(mockArticle); + })); + + describe('$scope.create()', function () { + var sampleArticlePostData; + + beforeEach(function () { + // Create a sample article object + sampleArticlePostData = new Articles({ + title: 'An Article about MEAN', + content: 'MEAN rocks!' + }); + + // Fixture mock form input values + scope.title = 'An Article about MEAN'; + scope.content = 'MEAN rocks!'; + + spyOn($location, 'path'); + }); + + it('should send a POST request with the form input values and then locate to new object URL', inject(function (Articles) { + // Set POST response + $httpBackend.expectPOST('api/articles', sampleArticlePostData).respond(mockArticle); + + // Run controller functionality + scope.create(); + $httpBackend.flush(); + + // Test form inputs are reset + expect(scope.title).toEqual(''); + expect(scope.content).toEqual(''); + + // Test URL redirection to the Article list after the article was created + expect($location.path.calls.mostRecent().args[0]).toBe('/admin/articles'); + })); + + it('should set scope.error if save error', function () { + var errorMessage = 'this is an error message'; + $httpBackend.expectPOST('api/articles', sampleArticlePostData).respond(400, { + message: errorMessage + }); + + scope.create(); + $httpBackend.flush(); + + expect(scope.error).toBe(errorMessage); + }); + }); + + describe('$scope.update()', function () { + beforeEach(function () { + // Mock article in scope + scope.article = mockArticle; + }); + + it('should update a valid article', inject(function (Articles) { + // Set PUT response + $httpBackend.expectPUT(/api\/articles\/([0-9a-fA-F]{24})$/).respond(); + + // Run controller functionality + scope.update(); + $httpBackend.flush(); + + // Test URL location to Article list + expect($location.path()).toBe('/admin/articles'); + })); + + it('should set scope.error to error response message', inject(function (Articles) { + var errorMessage = 'error'; + $httpBackend.expectPUT(/api\/articles\/([0-9a-fA-F]{24})$/).respond(400, { + message: errorMessage + }); + + scope.update(); + $httpBackend.flush(); + + expect(scope.error).toBe(errorMessage); + })); + }); + + describe('$scope.remove(article)', function () { + beforeEach(function () { + // Create new articles array and include the article + scope.articles = [mockArticle, {}]; + + // Set expected DELETE response + $httpBackend.expectDELETE(/api\/articles\/([0-9a-fA-F]{24})$/).respond(204); + + // Mock the confirm dialog as true + spyOn($window, 'confirm').and.callFake(function () { + return true; + }); + // Run controller functionality + scope.remove(mockArticle); + }); + + it('should send a DELETE request with a valid articleId and remove the article from the scope', inject(function (Articles) { + expect(scope.articles.length).toBe(1); + })); + }); + + describe('scope.remove()', function () { + beforeEach(function () { + spyOn($location, 'path'); + scope.article = mockArticle; + + $httpBackend.expectDELETE(/api\/articles\/([0-9a-fA-F]{24})$/).respond(204); + + // Mock the confirm dialog as true + spyOn($window, 'confirm').and.callFake(function () { + return true; + }); + scope.remove(); + $httpBackend.flush(); + }); + + it('should redirect to articles', function () { + expect($location.path.calls.mostRecent().args[0]).toBe('/admin/articles'); + }); + }); + }); +}()); diff --git a/modules/articles/tests/client/articles.client.controller.tests.js b/modules/articles/tests/client/articles.client.controller.tests.js index 2e6f317f34..dd7718ef9f 100644 --- a/modules/articles/tests/client/articles.client.controller.tests.js +++ b/modules/articles/tests/client/articles.client.controller.tests.js @@ -96,115 +96,5 @@ // Test scope value expect(scope.article).toEqualData(mockArticle); })); - - describe('$scope.craete()', function () { - var sampleArticlePostData; - - beforeEach(function () { - // Create a sample article object - sampleArticlePostData = new Articles({ - title: 'An Article about MEAN', - content: 'MEAN rocks!' - }); - - // Fixture mock form input values - scope.title = 'An Article about MEAN'; - scope.content = 'MEAN rocks!'; - - spyOn($location, 'path'); - }); - - it('should send a POST request with the form input values and then locate to new object URL', inject(function (Articles) { - // Set POST response - $httpBackend.expectPOST('api/articles', sampleArticlePostData).respond(mockArticle); - - // Run controller functionality - scope.create(); - $httpBackend.flush(); - - // Test form inputs are reset - expect(scope.title).toEqual(''); - expect(scope.content).toEqual(''); - - // Test URL redirection after the article was created - expect($location.path.calls.mostRecent().args[0]).toBe('articles/' + mockArticle._id); - })); - - it('should set scope.error if save error', function () { - var errorMessage = 'this is an error message'; - $httpBackend.expectPOST('api/articles', sampleArticlePostData).respond(400, { - message: errorMessage - }); - - scope.create(); - $httpBackend.flush(); - - expect(scope.error).toBe(errorMessage); - }); - }); - - describe('$scope.update()', function () { - beforeEach(function () { - // Mock article in scope - scope.article = mockArticle; - }); - - it('should update a valid article', inject(function (Articles) { - // Set PUT response - $httpBackend.expectPUT(/api\/articles\/([0-9a-fA-F]{24})$/).respond(); - - // Run controller functionality - scope.update(); - $httpBackend.flush(); - - // Test URL location to new object - expect($location.path()).toBe('/articles/' + mockArticle._id); - })); - - it('should set scope.error to error response message', inject(function (Articles) { - var errorMessage = 'error'; - $httpBackend.expectPUT(/api\/articles\/([0-9a-fA-F]{24})$/).respond(400, { - message: errorMessage - }); - - scope.update(); - $httpBackend.flush(); - - expect(scope.error).toBe(errorMessage); - })); - }); - - describe('$scope.remove(article)', function () { - beforeEach(function () { - // Create new articles array and include the article - scope.articles = [mockArticle, {}]; - - // Set expected DELETE response - $httpBackend.expectDELETE(/api\/articles\/([0-9a-fA-F]{24})$/).respond(204); - - // Run controller functionality - scope.remove(mockArticle); - }); - - it('should send a DELETE request with a valid articleId and remove the article from the scope', inject(function (Articles) { - expect(scope.articles.length).toBe(1); - })); - }); - - describe('scope.remove()', function () { - beforeEach(function () { - spyOn($location, 'path'); - scope.article = mockArticle; - - $httpBackend.expectDELETE(/api\/articles\/([0-9a-fA-F]{24})$/).respond(204); - - scope.remove(); - $httpBackend.flush(); - }); - - it('should redirect to articles', function () { - expect($location.path).toHaveBeenCalledWith('articles'); - }); - }); }); }()); diff --git a/modules/articles/tests/server/admin.article.server.routes.tests.js b/modules/articles/tests/server/admin.article.server.routes.tests.js new file mode 100644 index 0000000000..71fbc13487 --- /dev/null +++ b/modules/articles/tests/server/admin.article.server.routes.tests.js @@ -0,0 +1,198 @@ +'use strict'; + +var should = require('should'), + request = require('supertest'), + path = require('path'), + mongoose = require('mongoose'), + User = mongoose.model('User'), + Article = mongoose.model('Article'), + express = require(path.resolve('./config/lib/express')); + +/** + * Globals + */ +var app, agent, credentials, user, article; + +/** + * Article routes tests + */ +describe('Article Admin CRUD tests', function () { + before(function (done) { + // Get application + app = express.init(mongoose); + agent = request.agent(app); + + done(); + }); + + beforeEach(function (done) { + // Create user credentials + credentials = { + username: 'username', + password: 'password' + }; + + // Create a new user + user = new User({ + firstName: 'Full', + lastName: 'Name', + displayName: 'Full Name', + email: 'test@test.com', + roles: ['user', 'admin'], + username: credentials.username, + password: credentials.password, + provider: 'local' + }); + + // Save a user to the test db and create new article + user.save(function () { + article = { + title: 'Article Title', + content: 'Article Content' + }; + + done(); + }); + }); + + it('should be able to save an article if logged in', function (done) { + agent.post('/api/auth/signin') + .send(credentials) + .expect(200) + .end(function (signinErr, signinRes) { + // Handle signin error + if (signinErr) { + return done(signinErr); + } + + // Get the userId + var userId = user.id; + + // Save a new article + agent.post('/api/articles') + .send(article) + .expect(200) + .end(function (articleSaveErr, articleSaveRes) { + // Handle article save error + if (articleSaveErr) { + return done(articleSaveErr); + } + + // Get a list of articles + agent.get('/api/articles') + .end(function (articlesGetErr, articlesGetRes) { + // Handle article save error + if (articlesGetErr) { + return done(articlesGetErr); + } + + // Get articles list + var articles = articlesGetRes.body; + + // Set assertions + (articles[0].user._id).should.equal(userId); + (articles[0].title).should.match('Article Title'); + + // Call the assertion callback + done(); + }); + }); + }); + }); + + it('should be able to update an article if signed in', function (done) { + agent.post('/api/auth/signin') + .send(credentials) + .expect(200) + .end(function (signinErr, signinRes) { + // Handle signin error + if (signinErr) { + return done(signinErr); + } + + // Get the userId + var userId = user.id; + + // Save a new article + agent.post('/api/articles') + .send(article) + .expect(200) + .end(function (articleSaveErr, articleSaveRes) { + // Handle article save error + if (articleSaveErr) { + return done(articleSaveErr); + } + + // Update article title + article.title = 'WHY YOU GOTTA BE SO MEAN?'; + + // Update an existing article + agent.put('/api/articles/' + articleSaveRes.body._id) + .send(article) + .expect(200) + .end(function (articleUpdateErr, articleUpdateRes) { + // Handle article update error + if (articleUpdateErr) { + return done(articleUpdateErr); + } + + // Set assertions + (articleUpdateRes.body._id).should.equal(articleSaveRes.body._id); + (articleUpdateRes.body.title).should.match('WHY YOU GOTTA BE SO MEAN?'); + + // Call the assertion callback + done(); + }); + }); + }); + }); + + it('should be able to delete an article if signed in', function (done) { + agent.post('/api/auth/signin') + .send(credentials) + .expect(200) + .end(function (signinErr, signinRes) { + // Handle signin error + if (signinErr) { + return done(signinErr); + } + + // Get the userId + var userId = user.id; + + // Save a new article + agent.post('/api/articles') + .send(article) + .expect(200) + .end(function (articleSaveErr, articleSaveRes) { + // Handle article save error + if (articleSaveErr) { + return done(articleSaveErr); + } + + // Delete an existing article + agent.delete('/api/articles/' + articleSaveRes.body._id) + .send(article) + .expect(200) + .end(function (articleDeleteErr, articleDeleteRes) { + // Handle article error error + if (articleDeleteErr) { + return done(articleDeleteErr); + } + + // Set assertions + (articleDeleteRes.body._id).should.equal(articleSaveRes.body._id); + + // Call the assertion callback + done(); + }); + }); + }); + }); + + afterEach(function (done) { + User.remove().exec(function () { + Article.remove().exec(done); + }); + }); +}); diff --git a/modules/articles/tests/server/article.server.routes.tests.js b/modules/articles/tests/server/article.server.routes.tests.js index ef0f1ac781..cbfb3f488b 100644 --- a/modules/articles/tests/server/article.server.routes.tests.js +++ b/modules/articles/tests/server/article.server.routes.tests.js @@ -54,7 +54,7 @@ describe('Article CRUD tests', function () { }); }); - it('should be able to save an article if logged in', function (done) { + it('should not be able to save an article if logged in without the "admin" role', function (done) { agent.post('/api/auth/signin') .send(credentials) .expect(200) @@ -64,38 +64,14 @@ describe('Article CRUD tests', function () { return done(signinErr); } - // Get the userId - var userId = user.id; - - // Save a new article agent.post('/api/articles') .send(article) - .expect(200) + .expect(403) .end(function (articleSaveErr, articleSaveRes) { - // Handle article save error - if (articleSaveErr) { - return done(articleSaveErr); - } - - // Get a list of articles - agent.get('/api/articles') - .end(function (articlesGetErr, articlesGetRes) { - // Handle article save error - if (articlesGetErr) { - return done(articlesGetErr); - } - - // Get articles list - var articles = articlesGetRes.body; - - // Set assertions - (articles[0].user._id).should.equal(userId); - (articles[0].title).should.match('Article Title'); - - // Call the assertion callback - done(); - }); + // Call the assertion callback + done(articleSaveErr); }); + }); }); @@ -109,10 +85,7 @@ describe('Article CRUD tests', function () { }); }); - it('should not be able to save an article if no title is provided', function (done) { - // Invalidate title field - article.title = ''; - + it('should not be able to update an article if signed in without the "admin" role', function (done) { agent.post('/api/auth/signin') .send(credentials) .expect(200) @@ -122,70 +95,16 @@ describe('Article CRUD tests', function () { return done(signinErr); } - // Get the userId - var userId = user.id; - - // Save a new article agent.post('/api/articles') .send(article) - .expect(400) + .expect(403) .end(function (articleSaveErr, articleSaveRes) { - // Set message assertion - (articleSaveRes.body.message).should.match('Title cannot be blank'); - - // Handle article save error + // Call the assertion callback done(articleSaveErr); }); }); }); - it('should be able to update an article if signed in', function (done) { - agent.post('/api/auth/signin') - .send(credentials) - .expect(200) - .end(function (signinErr, signinRes) { - // Handle signin error - if (signinErr) { - return done(signinErr); - } - - // Get the userId - var userId = user.id; - - // Save a new article - agent.post('/api/articles') - .send(article) - .expect(200) - .end(function (articleSaveErr, articleSaveRes) { - // Handle article save error - if (articleSaveErr) { - return done(articleSaveErr); - } - - // Update article title - article.title = 'WHY YOU GOTTA BE SO MEAN?'; - - // Update an existing article - agent.put('/api/articles/' + articleSaveRes.body._id) - .send(article) - .expect(200) - .end(function (articleUpdateErr, articleUpdateRes) { - // Handle article update error - if (articleUpdateErr) { - return done(articleUpdateErr); - } - - // Set assertions - (articleUpdateRes.body._id).should.equal(articleSaveRes.body._id); - (articleUpdateRes.body.title).should.match('WHY YOU GOTTA BE SO MEAN?'); - - // Call the assertion callback - done(); - }); - }); - }); - }); - it('should be able to get a list of articles if not signed in', function (done) { // Create new article model instance var articleObj = new Article(article); @@ -246,7 +165,7 @@ describe('Article CRUD tests', function () { }); }); - it('should be able to delete an article if signed in', function (done) { + it('should not be able to delete an article if signed in without the "admin" role', function (done) { agent.post('/api/auth/signin') .send(credentials) .expect(200) @@ -256,35 +175,12 @@ describe('Article CRUD tests', function () { return done(signinErr); } - // Get the userId - var userId = user.id; - - // Save a new article agent.post('/api/articles') .send(article) - .expect(200) + .expect(403) .end(function (articleSaveErr, articleSaveRes) { - // Handle article save error - if (articleSaveErr) { - return done(articleSaveErr); - } - - // Delete an existing article - agent.delete('/api/articles/' + articleSaveRes.body._id) - .send(article) - .expect(200) - .end(function (articleDeleteErr, articleDeleteRes) { - // Handle article error error - if (articleDeleteErr) { - return done(articleDeleteErr); - } - - // Set assertions - (articleDeleteRes.body._id).should.equal(articleSaveRes.body._id); - - // Call the assertion callback - done(); - }); + // Call the assertion callback + done(articleSaveErr); }); }); });