Skip to content

Commit

Permalink
ft(search-functionality): add search functionality and custom filtering
Browse files Browse the repository at this point in the history
based on parameters

- enable filter by author
- enable filter by tag
- enable filter by title
- enable filter by keywords

[Finishes #166790009]
  • Loading branch information
elemanhillary committed Jul 17, 2019
1 parent 698c533 commit ed00e56
Show file tree
Hide file tree
Showing 12 changed files with 238 additions and 15 deletions.
12 changes: 6 additions & 6 deletions controllers/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export const signup = async (req, res) => {
}
} catch (ex) {
await transaction.rollback();
return res.status(409).json({ message: `${ex.errors[0].path.toLowerCase()} already exists` });
return res.status(409).json({ error: `${ex.errors[0].path.toLowerCase()} already exists` });
}
};

Expand All @@ -65,7 +65,7 @@ export const signin = async (req, res) => {
const user = await users.findOne({ where: { email: req.body.email } }, { transaction });
await transaction.commit();
if (!user) {
return res.status(404).json({ message: 'user not found' });
return res.status(404).json({ error: 'user not found' });
}
const passBool = Auth.comparePassword(password, user.password);
const { username } = user;
Expand All @@ -80,10 +80,10 @@ export const signin = async (req, res) => {
},
});
}
return res.status(401).json({ message: 'wrong username or password' });
return res.status(401).json({ error: 'wrong username or password' });
} catch (ex) {
await transaction.rollback();
return res.json({ message: ex });
return res.status(500).json({ error: 'something went wrong' });
}
};

Expand All @@ -95,7 +95,7 @@ export const verifyUser = async (req, res) => {
if (!user) {
return res.status(404).json({
status: res.statusCode,
message: 'user not registered',
error: 'user not registered',
});
}
const updatedUser = await users.update(
Expand All @@ -111,7 +111,7 @@ export const verifyUser = async (req, res) => {
} catch (error) {
return res.status(500).json({
status: 500,
error,
error: 'something went wrong',
});
}
};
Expand Down
18 changes: 12 additions & 6 deletions controllers/comment.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,24 +29,30 @@ export const createComment = async (req, res) => {
as: 'author', model: users, attributes: ['username', 'email'],
}],
});
const {
id,
author,
createdAt,
updatedAt
} = showComment;
return res.status(201).json({
message: 'commented',
comment: {
id: showComment.id,
id,
body: showComment.body,
author: showComment.author,
createdAt: showComment.createdAt,
updatedAt: showComment.updatedAt,
author,
createdAt,
updatedAt,
},
});
}
return;
}
return res.status(404).json({ message: 'article or user not found' });
return res.status(404).json({ error: 'article or user not found' });
} catch (ex) {
await transaction.rollback();
res.status(400).json({
message: 'commenting failed'
error: 'commenting failed'
});
}
};
1 change: 1 addition & 0 deletions controllers/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './auth';
export * from './article';
export * from './comment';
export * from './search';
32 changes: 32 additions & 0 deletions controllers/search.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import searchAlgolia from 'algoliasearch';
import dotenv from 'dotenv';
import db from '../models';
import { sanitize } from '../helpers/searchSanitizer';

dotenv.config();
const { articles } = db;
export const search = async (req, res) => {
const client = searchAlgolia(process.env.ALGO_APP_ID, process.env.ALGO_SEARCH_ONLY);
const index = client.initIndex('authors_haven');
const {
tag,
author,
title,
keyword
} = req.query;
try {
const articlesResults = await articles.findAll();
index.addObjects(articlesResults);
index.search(`${tag || author || title || keyword}`, (err, results) => {
const sanitizedResults = sanitize(results.hits);
if (sanitizedResults.length !== 0) {
return res.status(200).json({ results: sanitizedResults, });
}
return res.status(204).json({ error: 'no results' });
});
} catch (ex) {
return res.status(500).json({
error: 'something went wrong',
});
}
};
26 changes: 26 additions & 0 deletions helpers/searchSanitizer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
export const sanitize = (object) => {
const articleHolder = [];
const objectStr = Object.prototype.toString.call(object);
if (objectStr === '[object Array]' && objectStr) {
object.forEach((element) => {
articleHolder.push(
Object.keys(element).reduce((obj, key) => {
if (key !== '_highlightResult' && key !== 'objectID') {
obj[key] = element[key];
}
return obj;
}, {})
);
});
}
return articleHolder;
};

export const isEmpty = (object) => {
object.forEach((element) => {
if (Object.prototype.hasOwnProperty.call(object, element)) {
return false;
}
return true;
});
};
98 changes: 98 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"@babel/preset-env": "^7.4.5",
"@babel/register": "^7.4.4",
"@sendgrid/mail": "^6.4.0",
"algoliasearch": "^3.33.0",
"bcrypt": "^3.0.6",
"bluebird": "^3.5.5",
"body-parser": "^1.18.3",
Expand Down
3 changes: 3 additions & 0 deletions routes/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ import express from 'express';
import admin from './admin';
import users from './users';
import socialTest from './socialTest';
import search from './search';


const router = express.Router();

router.use('/', admin);
router.use('/', users);
router.use('/', socialTest);
router.use('/', search);

export default router;
8 changes: 8 additions & 0 deletions routes/api/search.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import express from 'express';
import { search } from '../../controllers';

const router = express.Router();

router.get('/articles/', search);

export default router;
4 changes: 2 additions & 2 deletions tests/auth.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ describe('User Authentication Routes', () => {
.send(user.invalidDummy1)
.then((res) => {
expect(res.statusCode).to.be.equal(404);
expect(res.body.message).to.be.equal('user not found');
expect(res.body.error).to.be.equal('user not found');
done();
})
.catch(err => done(err));
Expand All @@ -66,7 +66,7 @@ describe('User Authentication Routes', () => {
.send(user.invalidDummy)
.then((res) => {
expect(res.statusCode).to.be.equal(401);
expect(res.body.message).to.be.equal('wrong username or password');
expect(res.body.error).to.be.equal('wrong username or password');
done();
})
.catch(err => done(err));
Expand Down
2 changes: 1 addition & 1 deletion tests/comment.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ describe('Comment on Article', () => {
.end((err, res) => {
expect(typeof res.statusCode).to.be.equal('number');
expect(res.statusCode).to.be.equal(404);
expect(res.body.message).to.be.equal('article or user not found');
expect(res.body.error).to.be.equal('article or user not found');
done();
});
});
Expand Down
Loading

0 comments on commit ed00e56

Please sign in to comment.