From c60d2c3143da31efd8319809723834fc7794e5fb Mon Sep 17 00:00:00 2001 From: Luciano Nooijen Date: Thu, 6 Dec 2018 13:47:33 +0100 Subject: [PATCH] Added category functionality --- README.md | 4 +- controllers/categories.js | 57 +++++++++++++++++++++ tests/controllers/categories.test.ts | 74 ++++++++++++++++++++++++++++ 3 files changed, 132 insertions(+), 3 deletions(-) create mode 100644 controllers/categories.js create mode 100644 tests/controllers/categories.test.ts diff --git a/README.md b/README.md index 14efffa..e23edf4 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,6 @@ [![NodeJS Version](https://img.shields.io/badge/Node%20Version-%3E%3D%20v8.0.0-green.svg)](https://img.shields.io/badge/Node%20Version-%3E%3D%20v8.0.0-green.svg) [![GPLv3 license](https://img.shields.io/badge/License-GPLv3-blue.svg)](http://perso.crans.org/besson/LICENSE.html) -**NOTE: THIS PACKAGE IS STILL IN DEVELOPMENT! RELEASE OF v1.0.0 WILL BE AROUND DECEMBER 1st, 2018.** - Blog API developed by Bytecode Digital Agency as free (as in freedom) open source software. Built in NodeJS. Available as a standalone server, or as a NPM package ## Installation @@ -58,7 +56,7 @@ Then you can use the imported functions as you wish, for example: const posts = await articles.list(blog); ``` -Just send the `blog` instance as the first argument and the rest of the arguments second. +Just send the `blog` instance as the first argument and the rest of the arguments second. This is because this way the same logic can be applied to multiple blog instances within an application. The available methods are: diff --git a/controllers/categories.js b/controllers/categories.js new file mode 100644 index 0000000..becf087 --- /dev/null +++ b/controllers/categories.js @@ -0,0 +1,57 @@ +const listCategories = async knex => { + const Categories = await knex.select('*').from('categories'); + return Categories; +}; + +const getCategory = async (knex, id) => { + const category = await knex + .select('*') + .from('categories') + .where({ id }); + return category[0]; +}; + +const addCategory = async (knex, category) => { + const newCategoryData = { + name: category.name, + slug: category.slug, + }; + const returning = ['id', 'name', 'slug']; + const newCategory = await knex('categories') + .insert([newCategoryData]) + .returning(returning); + return newCategory[0]; +}; + +const modifyCategory = async (knex, id, category) => { + const { name, slug } = category; + const newCategoryData = { name, slug }; + const returning = ['id', 'name', 'slug']; + const oldCategoryData = getCategory(knex, id); + const newCategory = Object.assign( + {}, + { ...oldCategoryData, ...newCategoryData }, + ); + const modifiedCategory = await knex('categories') + .returning(returning) + .where('id', '=', id) + .update(newCategory); + return modifiedCategory[0]; +}; + +const deleteCategory = async (knex, id) => + new Promise(resolve => + knex('categories') + .returning(['id']) + .where({ id }) + .delete() + .then(data => resolve(data[0])), + ); // eslint-disable-line + +module.exports = { + listCategories, + getCategory, + addCategory, + modifyCategory, + deleteCategory, +}; diff --git a/tests/controllers/categories.test.ts b/tests/controllers/categories.test.ts new file mode 100644 index 0000000..5ff43d1 --- /dev/null +++ b/tests/controllers/categories.test.ts @@ -0,0 +1,74 @@ +import { useTestDatabase } from '../config/index'; +import blog from '../config/blog'; + +const { authHelper } = require('../../helpers'); + +const { + listCategories, + getCategory, + addCategory, + modifyCategory, + deleteCategory, +} = require('../../controllers/categories'); + +useTestDatabase(); + +const newCategory = { + name: 'The new category name', + slug: 'the-new-slug', +}; + +describe('Test if Categories CRUD operations are working correctly', () => { + test('Listing all Categories should return rows', async () => { + expect.assertions(1); + const categories = await listCategories(blog); + expect(categories.length).toBeGreaterThan(0); + }); + + test('Fetching a single Category should return an Categorie', async () => { + expect.assertions(3); + const category = await getCategory(blog, 1); + expect(category.id).toBe(1); + expect(typeof category.name).toBe('string'); + expect(typeof category.slug).toBe('string'); + }); + + test('Adding a new Category should add a single row', async () => { + expect.assertions(1); + const categoriesBefore = await listCategories(blog); + const categorieLengthBefore = categoriesBefore.length; + await addCategory(blog, newCategory); + const categoriesAfter = await listCategories(blog); + const categorieLengthAfter = categoriesAfter.length; + expect(categorieLengthAfter).toBe(categorieLengthBefore + 1); + }); + + test('Adding a new Category should return the new Category', async () => { + expect.assertions(3); + const addedCategory = await addCategory(blog, newCategory); + expect(typeof addedCategory.id).toBe('number'); + expect(addedCategory.name).toBe(newCategory.name); + expect(addedCategory.slug).toBe(newCategory.slug); + }); + + test('Updating an Category should return the modified data', async () => { + expect.assertions(7); + const originalCategory = await getCategory(blog, 1); + expect(originalCategory.id).toBe(1); + expect(originalCategory.name).not.toBe(newCategory.name); + expect(originalCategory.slug).not.toBe(newCategory.slug); + const modifiedCategory = await modifyCategory(blog, 1, newCategory); + expect(modifiedCategory.id).toBeDefined(); + expect(typeof modifiedCategory.id).toBe('number'); + expect(modifiedCategory.name).toBe(newCategory.name); + expect(modifiedCategory.slug).toBe(newCategory.slug); + }); + + test('Deleting an Category should return undefined', async () => { + expect.assertions(2); + return deleteCategory(blog, 2) + .then(data => expect(data.id).toBe(2)) + .then(async () => + expect(await getCategory(blog, 2)).toBeUndefined()); + }); +});