Skip to content

Commit

Permalink
ft(sharing-articles):user-can-share-articles-on-socialMedias
Browse files Browse the repository at this point in the history
  • Loading branch information
Emmanuel Rukundo authored and EmyRukundo committed Jun 28, 2019
1 parent 306cab5 commit 783f72d
Show file tree
Hide file tree
Showing 11 changed files with 178 additions and 38 deletions.
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ NODE_ENV=
PORT=
DATABASE_URL=
DEV_DATABASE_URL=
APP_URL_FRONTEND=
DATABASE_TEST_URL=
AUTHOSHAVEN_USER=
AUTHOSHAVEN_PASS=
Expand Down
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
env:
global:
- APP_URL_FRONTEND=http://localhost:3000/api
language: node_js
node_js:
- 'stable'
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"morgan": "^1.9.1",
"multer": "^1.4.1",
"nodemailer": "^6.2.1",
"open": "^6.3.0",
"passport": "^0.4.0",
"passport-facebook": "^3.0.0",
"passport-google-oauth20": "^2.0.0",
Expand All @@ -53,6 +54,7 @@
"request": "^2.88.0",
"sequelize": "^5.8.7",
"slug": "^1.1.0",
"social-share": "^0.1.0",
"swagger-ui-express": "^4.0.6",
"underscore": "^1.9.1",
"uniqid": "^5.0.3"
Expand Down
12 changes: 12 additions & 0 deletions src/api/controllers/articlesController.js
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,18 @@ class articlesController {
}
});
}

/**
* @param {object} req
* @param {object} res
* @returns {object} Object representing the response returned
*/
static async share(req, res) {
return res.status(200).json({
message: 'Thanks for sharing!',
article: req.article
});
}
}

export default articlesController;
10 changes: 8 additions & 2 deletions src/api/routes/articlesRouter.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import RatingController from '../controllers/ratingController';
import slugExist from '../../middleware/slugExist';
import bookmarkController from '../controllers/bookmark';
import checkLikesandDislikes from '../../middleware/checkLikesDislikes';

import shareArticle from '../../helpers/shareArticle';

const articlesRouter = Router();
const {
Expand All @@ -23,6 +23,7 @@ const {
getLikes,
getDislikes,
reportArticle,
share
} = articlesController;
const { verifyToken } = Auth;
const { createRatings, UpdateRatings } = RatingController;
Expand Down Expand Up @@ -54,7 +55,6 @@ articlesRouter
.post('/:slug/dislike', verifyToken, dislikeArticle);

// Comments routes

articlesRouter.post('/:slug/comments', verifyToken, validateBody('checkComment'), articleExists, checkComment, createComment);
articlesRouter.post('/:slug/comments/:commentId', verifyToken, validateBody('checkComment'), articleExists, checkComment, commentAcomment);
articlesRouter.patch('/comments/:commentId', verifyToken, validateBody('checkComment'), checkParameter, editComment);
Expand All @@ -74,6 +74,12 @@ articlesRouter.post('/comments/:commentId/dislike', verifyToken, checkParameter,

articlesRouter.get('/comments/:commentId/dislikes', checkParameter, countDislikes);
articlesRouter.get('/comments/:commentId/likes', checkParameter, countLikes);
// sharing articles
articlesRouter.get('/:slug/share/twitter', verifyToken, slugExist, shareArticle, share);
articlesRouter.get('/:slug/share/facebook', verifyToken, slugExist, shareArticle, share);
articlesRouter.get('/:slug/share/linkedin', verifyToken, slugExist, shareArticle, share);
articlesRouter.get('/:slug/share/pinterest', verifyToken, slugExist, shareArticle, share);
articlesRouter.get('/:slug/share/email', verifyToken, slugExist, shareArticle, share);

articlesRouter.post('/:slug/bookmark', verifyToken, slugExist, bookmark);

Expand Down
1 change: 1 addition & 0 deletions src/api/routes/profilesRouter.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Router } from 'express';
// eslint-disable-next-line import/no-named-as-default
import ProfilesController from '../controllers/profiles';
import Auth from '../../middleware/auth';
import validUser from '../../middleware/validUser';
Expand Down
29 changes: 29 additions & 0 deletions src/helpers/shareArticle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import open from 'open';
import dotenv from 'dotenv';
import share from 'social-share';
import db from '../sequelize/models';

dotenv.config();
const { Article } = db;
const { APP_URL_FRONTEND } = process.env;

export default async (req, res, next) => {
const { slug } = req.params;
const { title } = await Article.findOne({ where: { slug } });
if (req.url.search(/\/twitter/g) > 0) {
const url = share('twitter', { url: `${APP_URL_FRONTEND}/api/articles/${slug}` });
await open(`${url}`, { wait: false });
} else if (req.url.search(/\/facebook/g) > 0) {
const url = share('facebook', { url: `${APP_URL_FRONTEND}/api/articles/${slug}` });
await open(`${url}`, { wait: false });
} else if (req.url.search(/\/email/g) > 0) {
await open(
`mailto:?subject=${title}&body=${APP_URL_FRONTEND}/articles/${slug}`,
{
wait: false
}
);
}

next();
};
21 changes: 21 additions & 0 deletions src/middleware/checkUsernameExist.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import models from '../sequelize/models';

const usernameAvailability = {
async usernameExist(req, res, next) {
const { username } = req.params;
const user = await models.User.findAll({
where: {
username
}
});
if (!user.length) {
return res.status(404).json({
error: 'username does not exist'
});
}

next();
}
};

export default usernameAvailability;
59 changes: 23 additions & 36 deletions src/sequelize/seeders/20190620204605-articles-test.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,26 @@
module.exports = {
up: queryInterface => queryInterface.bulkInsert('Articles', [
{
slug: '73H7812',
title: 'How to survive at Andela',
description: 'YoYo',
body:
'Lorem Ipsum is simply dummy text of the printing and typesetting industry.',
image: '',
createdAt: new Date(),
updatedAt: new Date(),
readtime: '2 min'
},
{
slug: '73H99992',
title: 'Wow',
description: 'YoYo',
readtime: '2 min',
body:
'Lorem Ipsum is simply dummy text of the printing and typesetting industry.',
image: '',
createdAt: new Date(),
updatedAt: new Date(),
},
{
slug: 'This_is_andela_2433546h34',
title: 'Wow',
description: 'YoYo',
readtime: '2 min',
body:
'Lorem Ipsum is simply dummy text of the printing and typesetting industry.',
image: '',
createdAt: new Date(),
updatedAt: new Date()
}
]),

up: queryInterface => queryInterface.bulkInsert('Articles', [{
slug: '73H7812',
title: 'How to survive at Andela',
authorId: '1',
description: 'YoYo',
body:
'Lorem Ipsum is simply dummy text of the printing and typesetting industry.',
image: '',
readtime: '1min',
createdAt: new Date(),
updatedAt: new Date(),
}, {
slug: '73H99992',
title: 'Wow',
description: 'YoYo',
authorId: '2',
body:
'Lorem Ipsum is simply dummy text of the printing and typesetting industry.',
image: '',
readtime: '1min',
createdAt: new Date(),
updatedAt: new Date(),
}]),
down: queryInterface => queryInterface.bulkDelete('Articles', null, {})
};
61 changes: 61 additions & 0 deletions test/articles.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -378,5 +378,66 @@ describe('Like/Unlike Articles', () => {
done();
});
});

// share article test
it('should share an article on twitter', (done) => {
chai
.request(app)
.get(`/api/articles/${testArticle.slug}/share/twitter`)
.set('token', userToken)
.send()
.end((err, res) => {
res.should.have.status(200);
done();
});
});

it('should share an article on facebook', (done) => {
chai
.request(app)
.get(`/api/articles/${testArticle.slug}/share/facebook`)
.set('token', userToken)
.send()
.end((err, res) => {
expect(res.status).to.be.equal(200);
done();
});
});

it('should share an article on linkedin', (done) => {
chai
.request(app)
.get(`/api/articles/${testArticle.slug}/share/linkedin`)
.set('token', userToken)
.send()
.end((err, res) => {
expect(res.status).to.be.equal(200);
done();
});
});

it('should share an article on pinterest', (done) => {
chai
.request(app)
.get(`/api/articles/${testArticle.slug}/share/linkedin`)
.set('token', userToken)
.send()
.end((err, res) => {
expect(res.status).to.be.equal(200);
done();
});
});

it('should share an article on email', (done) => {
chai
.request(app)
.get(`/api/articles/${testArticle.slug}/share/email`)
.set('token', userToken)
.send()
.end((err, res) => {
expect(res.status).to.be.equal(200);
done();
});
});
});

17 changes: 17 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2866,6 +2866,11 @@ is-windows@^1.0.2:
resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"
integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==

is-wsl@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d"
integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=

isarray@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
Expand Down Expand Up @@ -3828,6 +3833,13 @@ onetime@^2.0.0:
dependencies:
mimic-fn "^1.0.0"

open@^6.3.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/open/-/open-6.3.0.tgz#60d0b845ee38fae0631f5d739a21bd40e3d2a527"
integrity sha512-6AHdrJxPvAXIowO/aIaeHZ8CeMdDf7qCyRNq8NwJpinmCdXhz+NZR7ie1Too94lpciCDsG+qHGO9Mt0svA4OqA==
dependencies:
is-wsl "^1.1.0"

optimist@^0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686"
Expand Down Expand Up @@ -4822,6 +4834,11 @@ snapdragon@^0.8.1:
source-map-resolve "^0.5.0"
use "^3.1.0"

social-share@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/social-share/-/social-share-0.1.0.tgz#2b2aa93c85efcdc7146816e758b381b20463dddd"
integrity sha1-KyqpPIXvzccUaBbnWLOBsgRj3d0=

source-map-resolve@^0.5.0:
version "0.5.2"
resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259"
Expand Down

0 comments on commit 783f72d

Please sign in to comment.