Skip to content

Commit

Permalink
fix(articles): Article edit/delete validation
Browse files Browse the repository at this point in the history
Adds a custom field named `isCurrentUserOwner` to the Article document before
it's returned to the client. This field is used to determine if the current
User should is the "owner", and should see the edit/delete controls on the
client-side when viewing a single article. This custom (ad-hoc) field is NOT
persisted to the database; it's merely attached to the document.

Added server-side route tests for verifying the ad-hoc
"isCurrentUserOwner" field is properly set on the a single Article document.

Fixes meanjs#1146
  • Loading branch information
mleanos committed Feb 8, 2016
1 parent ce3d006 commit 69b8a05
Show file tree
Hide file tree
Showing 3 changed files with 166 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<div class="page-header">
<h1 ng-bind="vm.article.title"></h1>
</div>
<div class="pull-right" ng-show="vm.authentication.user._id == vm.article.user._id">
<div class="pull-right" ng-show="vm.article.isCurrentUserOwner">
<a class="btn btn-primary" ui-sref="articles.edit({ articleId: vm.article._id })">
<i class="glyphicon glyphicon-edit"></i>
</a>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,14 @@ exports.create = function (req, res) {
* Show the current article
*/
exports.read = function (req, res) {
res.json(req.article);
// convert mongoose document to JSON
var article = req.article ? req.article.toJSON() : {};

// Add a custom field to the Article, for determining if the current User is the "owner".
// NOTE: This field is NOT persisted to the database, since it doesn't exist in the Article model.
article.isCurrentUserOwner = req.user && article.user && article.user._id.toString() === req.user._id.toString() ? true : false;

res.json(article);
};

/**
Expand Down
157 changes: 157 additions & 0 deletions modules/articles/tests/server/article.server.routes.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,163 @@ describe('Article CRUD tests', function () {
});
});

it('should be able to get a single article if signed in and verify the custom "isCurrentUserOwner" field is set to "true"', function (done) {
// Create new article model instance
article.user = user;
var articleObj = new Article(article);

// Save the article
articleObj.save(function () {
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 the article
agent.get('/api/articles/' + articleSaveRes.body._id)
.expect(200)
.end(function (articleInfoErr, articleInfoRes) {
// Handle article error
if (articleInfoErr) {
return done(articleInfoErr);
}

// Set assertions
(articleInfoRes.body._id).should.equal(articleSaveRes.body._id);
(articleInfoRes.body.title).should.equal(article.title);

// Assert that the "isCurrentUserOwner" field is set to true since the current User created it
(articleInfoRes.body.isCurrentUserOwner).should.equal(true);

// Call the assertion callback
done();
});
});
});
});
});

it('should be able to get a single article if not signed in and verify the custom "isCurrentUserOwner" field is set to "false"', function (done) {
// Create new article model instance
var articleObj = new Article(article);

// Save the article
articleObj.save(function () {
request(app).get('/api/articles/' + articleObj._id)
.end(function (req, res) {
// Set assertion
res.body.should.be.instanceof(Object).and.have.property('title', article.title);
// Assert the custom field "isCurrentUserOwner" is set to false for the un-authenticated User
res.body.should.be.instanceof(Object).and.have.property('isCurrentUserOwner', false);
// Call the assertion callback
done();
});
});
});

it('should be able to get single article, that a different user created, if logged in & verify the "isCurrentUserOwner" field is set to "false"', function (done) {
// Create temporary user creds
var _creds = {
username: 'temp',
password: 'M3@n.jsI$Aw3$0m3'
};

// Create temporary user
var _user = new User({
firstName: 'Full',
lastName: 'Name',
displayName: 'Full Name',
email: 'temp@test.com',
username: _creds.username,
password: _creds.password,
provider: 'local'
});

_user.save(function (err, _user) {
// Handle save error
if (err) {
return done(err);
}

// Sign in with the user that will create the Article
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);
}

// Set assertions on new article
(articleSaveRes.body.title).should.equal(article.title);
should.exist(articleSaveRes.body.user);
should.equal(articleSaveRes.body.user._id, userId);

// now signin with the temporary user
agent.post('/api/auth/signin')
.send(_creds)
.expect(200)
.end(function (err, res) {
// Handle signin error
if (err) {
return done(err);
}

// Get the article
agent.get('/api/articles/' + articleSaveRes.body._id)
.expect(200)
.end(function (articleInfoErr, articleInfoRes) {
// Handle article error
if (articleInfoErr) {
return done(articleInfoErr);
}

// Set assertions
(articleInfoRes.body._id).should.equal(articleSaveRes.body._id);
(articleInfoRes.body.title).should.equal(article.title);
// Assert that the custom field "isCurrentUserOwner" is set to false since the current User didn't create it
(articleInfoRes.body.isCurrentUserOwner).should.equal(false);

// Call the assertion callback
done();
});
});
});
});
});
});

afterEach(function (done) {
User.remove().exec(function () {
Article.remove().exec(done);
Expand Down

0 comments on commit 69b8a05

Please sign in to comment.