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);
});
});
});