Skip to content

Commit

Permalink
Merge 4fa81ac into 1073d22
Browse files Browse the repository at this point in the history
  • Loading branch information
jojitoon committed Sep 18, 2018
2 parents 1073d22 + 4fa81ac commit c845806
Show file tree
Hide file tree
Showing 18 changed files with 438 additions and 149 deletions.
7 changes: 1 addition & 6 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,9 @@ pids
*.pid
*.seed

#bash file
export_env.bash

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# vscode
.vscode

# Coverage directory used by tools like istanbul
coverage

Expand Down Expand Up @@ -51,6 +45,7 @@ package-lock.json

# bash file
export_env.bash

#vscode files
.vscode

Expand Down
9 changes: 2 additions & 7 deletions server/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import articleRoutes from './routes/articleRoutes';
import passportSetup from './config/passportSetup';
import authRoutes from './routes/authRoutes';
import caseRoutes from './routes/caseRoutes';
import tagRoute from './routes/tagRoutes';

dotenv.config();
const app = express();
Expand All @@ -19,27 +20,21 @@ const port = parseInt(process.env.PORT, 10) || 8000;

// USE CORS TO AVOID CROSS ORIGIN CONFLICT
app.use(cors());
app.use(jsend.middleware);

// USE SWAGGER DOCUMENTATION
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument));

// USE JSEND MIDDLEWARE
app.use(jsend.middleware);

// ALLOW APP TO USE BODY-PARSER.
app.use(urlencoded);
app.use(json);
app.use(jsend.middleware);


app.use(passportSetup.initialize());

// Use user routes
app.use('/api/v1/users', userRoutes);
app.use('/api/v1/users/auth', authRoutes);
app.use('/api/v1/articles', articleRoutes);
app.use('/api/v1/cases', caseRoutes);
app.use('/api/v1/tags', tagRoute);

app.get('/', (req, res) => res.status(200).jsend.success({
message: 'Welcome to the sims program'
Expand Down
21 changes: 16 additions & 5 deletions server/controllers/articleController.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import ratingHelpers from '../helpers/ratingHelpers';
import models from '../models';
import { dataUri } from '../config/multer/multerConfig';
import imageUpload from '../helpers/imageUpload';
import tagManager from '../helpers/tagManager';

const {
Cases,
Articles,
Ratings,
ArticleLikes
ArticleLikes,
Tags
} = models;
const { analyseRatings } = ratingHelpers;

Expand Down Expand Up @@ -43,10 +45,19 @@ const articlesController = {
description: fields.description,
body: fields.body,
imageUrl
}).then(createdArticle => res.status(201).jsend.success({
article: createdArticle,
message: 'Article published successfully'
})).catch(err => res.status(500).jsend.fail({
}).then((createdArticle) => {
// checks if tags exist
const tags = !fields.tags || fields.tags === ''
? []
: fields.tags.replace(/\s+/g, '').split(',');

tagManager.createTag(res, tags, Tags, createdArticle);
return res.status(201).jsend.success({
article: createdArticle,
tags,
message: 'Article published successfully'
});
}).catch(err => res.status(500).jsend.fail({
message: 'Something, went wrong. please try again',
error: err.message
}));
Expand Down
36 changes: 36 additions & 0 deletions server/controllers/tagController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import models from '../models';

const { Articles, Tags } = models;

const tagController = {
all: (req, res) => {
Tags
.findAll()
.then(tags => res.status(200).jsend.success({ tags }))
.catch(() => res.status(500).jsend.error({ message: 'Your request cannot be completed at the moment. please try again.' }));
},

single: (req, res) => {
Tags
.findOne({
where: { name: req.params.tagName },
include: [{
model: Articles,
as: 'articles',
attributes: ['id', 'title', 'slug'],
through: {
attributes: ['createdAt']
}
}]
})
.then((tag) => {
if (!tag) {
return res.status(404).jsend.fail({ message: `tag with name ${req.params.tagName} not found` });
}
return res.status(200).jsend.success({ tag });
})
.catch(() => res.status(500).jsend.error({ message: 'Your request cannot be completed at the moment. please try again.' }));
}

};
export default tagController;
26 changes: 26 additions & 0 deletions server/helpers/tagManager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* @description Function to create tags from array of strings
* and add them to the article.
* @param {object} res
* @param {Array} tagsArray
* @param {Model} tagsModel
* @param {Model instance} article
* @returns {object} undefined
*/const tagManager = {
createTag: (res, tagsArray, tagsModel, article) => {
tagsArray.forEach((tag) => {
tagsModel
.findOrCreate({
where: {
name: tag
}
})
.spread((createdTag) => {
article.addTags(createdTag);
})
.catch(() => res.status(500).jsend.fail({ message: 'Something, went wrong. please try again' }));
});
}
};

export default tagManager;
2 changes: 1 addition & 1 deletion server/middleware/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const cryptr = new Cryptr(secret);
*/
const auth = (req, res, next) => {
const token = req.headers.authorization || req.params.token;
if (!token) {
if (!token || token === undefined) {
return res.status(401).jsend.fail({
auth: false,
message: 'No token provided',
Expand Down
34 changes: 34 additions & 0 deletions server/migrations/20180911162010-create-articles-tags.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
module.exports = {
up: (queryInterface, Sequelize) => queryInterface.createTable('ArticlesTags', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
tagId: {
type: Sequelize.INTEGER,
references: {
model: 'Tags',
key: 'id'
}
},
articleId: {
type: Sequelize.INTEGER,
references: {
model: 'Articles',
key: 'id'
}
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
}, { freezeTableName: true }),

down: queryInterface => queryInterface.dropTable('ArticlesTags')
};
4 changes: 2 additions & 2 deletions server/models/articles.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ const articles = (sequelize, DataTypes) => {
});

Articles.belongsToMany(models.Tags, {
as: 'articleTags',
through: 'Tagging',
as: 'tags',
through: models.ArticlesTags,
foreignKey: 'articleId'
});

Expand Down
22 changes: 22 additions & 0 deletions server/models/articlesTags.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module.exports = (sequelize, DataTypes) => {
const Taggings = sequelize.define('ArticlesTags', {
tagId: {
type: DataTypes.INTEGER
},
articleId: {
type: DataTypes.INTEGER
}
});
Taggings.associate = (models) => {
Taggings.belongsTo(models.Articles, {
foreignKey: 'articleId',
onDelete: 'CASCADE'
});

Taggings.belongsTo(models.Tags, {
foreignKey: 'tagId',
onDelete: 'CASCADE'
});
};
return Taggings;
};
4 changes: 2 additions & 2 deletions server/models/tags.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ const tags = (sequelize, DataTypes) => {

Tags.associate = (models) => {
Tags.belongsToMany(models.Articles, {
as: 'tagArticle',
through: 'Tagging',
as: 'articles',
through: models.ArticlesTags,
foreignKey: 'tagId'
});
};
Expand Down
6 changes: 6 additions & 0 deletions server/models/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ const users = (sequelize, DataTypes) => {
allowNull: false,
unique: true
},
firstname: {
type: DataTypes.STRING
},
lastname: {
type: DataTypes.STRING
},
password: {
type: DataTypes.STRING,
allowNull: true,
Expand Down
11 changes: 11 additions & 0 deletions server/routes/tagRoutes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import express from 'express';
import tagController from '../controllers/tagController';
import auth from '../middleware/auth';

const route = express.Router();

// GET TAG ROUTE
route.get('/', auth, tagController.all);
route.get('/:tagName', auth, tagController.single);

export default route;
12 changes: 12 additions & 0 deletions server/seeders/20180911155134-seed-tagger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module.exports = {
up: queryInterface => queryInterface.bulkInsert('Users', [{
username: 'tagger',
email: 'tagger@gmail.com',
password: '$2b$08$Hkj0DXWIk0k/M3lTZWx/luvSTBY3d1DeArh2Zp6SruHoDtMJiBXfS',
isVerified: true,
createdAt: '2018-09-08',
updatedAt: '2018-09-08'
}]),

down: queryInterface => queryInterface.bulkDelete('Users')
};
14 changes: 14 additions & 0 deletions server/seeders/20180911175232-tags.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module.exports = {
up: queryInterface => queryInterface.bulkInsert('Tags', [{
name: 'javascript',
createdAt: '2018-09-08',
updatedAt: '2018-09-08'
},
{
name: 'nodejs',
createdAt: '2018-09-08',
updatedAt: '2018-09-08'
}]),

down: queryInterface => queryInterface.bulkDelete('Tags')
};
Loading

0 comments on commit c845806

Please sign in to comment.