Skip to content

Commit

Permalink
feature[167899197]Users should be able to read articles
Browse files Browse the repository at this point in the history
- create controller method to view article
- write test to test view article controller method
[Delivers #167899197]
  • Loading branch information
JuwonAbiola committed Aug 21, 2019
1 parent 550a208 commit 7f54d1b
Show file tree
Hide file tree
Showing 6 changed files with 217 additions and 1 deletion.
51 changes: 51 additions & 0 deletions server/controllers/Articles.js
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,57 @@ const createLikeOrDislike = async (userAction, userId, article) => {
return serverError(res);
}
}

/**
* @name viewArticle
* @async
* @static
* @memberof Articles
* @param {Object} req express request object
* @param {Object} res express response object
* @returns {JSON} JSON object with details of new article
*/
static async viewArticle(req, res) {
try {
const {
params: { slug }
} = req;
const article = await Article.findBySlug(slug);
if (!article || article.isArchived) {
return serverResponse(res, 404, { error: 'article not found' });
}
const {
id,
title,
description,
image,
articleBody,
likesCount,
dislikesCount,
publishedAt,
createdAt,
updatedAt,
authorId
} = article;
return serverResponse(res, 200, {
article: {
id,
title,
description,
image,
articleBody,
likesCount,
dislikesCount,
publishedAt,
createdAt,
updatedAt,
authorId
}
});
} catch (error) {
return serverError(res);
}
}
}

export default Articles;
13 changes: 13 additions & 0 deletions server/database/seeds/20190731140735-articles-seeds.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,19 @@ export default {
isArchived: false,
createdAt: new Date(),
updatedAt: new Date()
},
{
slug: 'how-to-train-your-drag-6',
title: 'How to train your dragon 6',
description: 'So toothless',
articleBody: 'It is a dragon',
authorId: 1,
likesCount: 0,
dislikesCount: 0,
publishedAt: new Date(),
isArchived: true,
createdAt: new Date(),
updatedAt: new Date()
}
],
{}
Expand Down
69 changes: 69 additions & 0 deletions server/docs/authors-haven-api.yml
Original file line number Diff line number Diff line change
Expand Up @@ -867,6 +867,36 @@ paths:
application/json:
schema:
'$ref': '#/components/schemas/serverResponse'
/api/v1/articles/{slug}:
get:
parameters:
- name: slug
in: path
required: true
description: article slug
schema:
type: string
summary: Route for viewing an article
description: Allow users to view an article
responses:
200:
description: article fetched successfully
content:
application/json:
schema:
'$ref': '#/components/schemas/viewArticle'
404:
description: article not found
content:
application/json:
schema:
'$ref': '#/components/schemas/errorResponse'
500:
description: Internal server error
content:
application/json:
schema:
'$ref': '#/components/schemas/serverResponse'

/api/v1/articles/{slug}/comments/{commentId}:
patch:
Expand Down Expand Up @@ -1432,3 +1462,42 @@ components:
message:
type: string

viewArticle:
type: object
properties:
id:
type: integer
example: 1
title:
type: string
example: seven
description:
type: string
example: pride
image:
type: string
example: 'https://res.cloudinary.com/teamrambo50/image/upload/v1565160704/avatar-1577909_1280_xsoxql.png'
articleBody:
type: string
example: prider
likesCount:
type: integer
example: 1
dislikesCount:
type: integer
example: 0
publishedAt:
type: string
format: date-time
example: 2017-07-21T17:32:28Z
createdAt:
type: string
format: date-time
example: 2017-07-21T17:32:28Z
updatedAt:
type: string
format: date-time
example: 2017-07-21T17:32:28Z
authorId:
type: integer
example: 1
1 change: 1 addition & 0 deletions server/routes/article.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,6 @@ router.delete(
protectedRoutesMiddlewares,
Articles.removeDislike
);
router.get('/:slug', Articles.viewArticle);

export default router;
8 changes: 7 additions & 1 deletion test/articles/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import * as createArticle from './create.test';
import * as likeOrDislikeArticle from './likeOrDislikeArticle.test';
import * as removeArticleLikeOrDislike from './removeArticleLikeOrDislike.test';
import * as viewArticle from './viewArticle.test';

export { createArticle, likeOrDislikeArticle, removeArticleLikeOrDislike };
export {
createArticle,
likeOrDislikeArticle,
removeArticleLikeOrDislike,
viewArticle
};
76 changes: 76 additions & 0 deletions test/articles/viewArticle.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import chai, { expect } from 'chai';
import chaiHttp from 'chai-http';
import { config } from 'dotenv';
import sinon from 'sinon';
import app from '../../server';
import Articles from '../../server/controllers/Articles';

const { viewArticle } = Articles;

config();

chai.use(chaiHttp);

const { BASE_URL } = process.env;

describe('GET Article', () => {
context('when a user views a published article', () => {
it('it returns the user profile', async () => {
const response = await chai
.request(app)
.get(`${BASE_URL}/articles/how-to-train-your-dragon`);
expect(response).to.have.status(200);
expect(response.body.article).to.not.have.property('slug', 'isArchived');
expect(response.body.article).to.have.any.keys(
'id',
'title',
'description',
'image',
'articleBody',
'likesCount',
'dislikesCount',
'publishedAt',
'createdAt',
'updatedAt',
'authorId'
);
});
});

context('when a user tries to view an article that does not exist', () => {
it('it returns a not found error', async () => {
const response = await chai
.request(app)
.get(`${BASE_URL}/articles/90000`);
expect(response).to.have.status(404);
expect(response.body.error).to.equal('article not found');
});
});

context('when a user tries to view an archived article', () => {
it('it returns the user profile', async () => {
const response = await chai
.request(app)
.get(`${BASE_URL}/articles/how-to-train-your-dragon-6`);
expect(response).to.have.status(404);
expect(response.body.error).to.equal('article not found');
});
});

context('when the database is unable to query the user table ', () => {
it('will throw a server error', async () => {
const stubfunc = { viewArticle };
const sandbox = sinon.createSandbox();
sandbox.stub(stubfunc, 'viewArticle').rejects(new Error('Server Error'));

const next = sinon.spy();
const res = {
status: () => ({
json: next
})
};
await viewArticle({}, res);
sinon.assert.calledOnce(next);
});
});
});

0 comments on commit 7f54d1b

Please sign in to comment.