diff --git a/part4/bloglist/app.js b/part4/bloglist/app.js index df2d810..5b13529 100644 --- a/part4/bloglist/app.js +++ b/part4/bloglist/app.js @@ -1,5 +1,6 @@ const config = require('./utils/config') const express = require('express') +require('express-async-errors') const app = express() const cors = require('cors') const blogsRouter = require('./controllers/blogs') diff --git a/part4/bloglist/controllers/blogs.js b/part4/bloglist/controllers/blogs.js index d72edbc..f8748e7 100644 --- a/part4/bloglist/controllers/blogs.js +++ b/part4/bloglist/controllers/blogs.js @@ -1,24 +1,23 @@ const blogsRouter = require('express').Router() const Blog = require('../models/blog') -blogsRouter.get('/', (request, response, next) => { - Blog - .find({}) - .then(blogs => { - response.json(blogs) - }) - .catch(error => next(error)) +blogsRouter.get('/', async (request, response) => { + const blogs = await Blog.find({}) + response.json(blogs) }) -blogsRouter.post('/', (request, response, next) => { - const blog = new Blog(request.body) - console.log(request.body) - blog - .save() - .then(result => { - response.status(201).json(result) - }) - .catch(error => next(error)) +blogsRouter.post('/', async (request, response) => { + const body = request.body + + const blog = await (new Blog({ + title: body.title, + author: body.author, + url: body.url, + likes: body.likes + })).save() + + response.status(201).json(blog) + }) module.exports = blogsRouter \ No newline at end of file diff --git a/part4/bloglist/models/blog.js b/part4/bloglist/models/blog.js index fecc149..811c03c 100644 --- a/part4/bloglist/models/blog.js +++ b/part4/bloglist/models/blog.js @@ -1,10 +1,22 @@ const mongoose = require('mongoose') const blogSchema = new mongoose.Schema({ - title: String, - author: String, - url: String, - likes: Number + title: { + type: String, + required: true + }, + author: { + type: String, + required: true + }, + url: { + type: String, + required: true + }, + likes: { + type: Number, + required: true + } }) blogSchema.set('toJSON', { diff --git a/part4/bloglist/package-lock.json b/part4/bloglist/package-lock.json index 8d596a1..370118c 100644 --- a/part4/bloglist/package-lock.json +++ b/part4/bloglist/package-lock.json @@ -13,6 +13,7 @@ "cross-env": "^7.0.3", "dotenv": "^16.1.1", "express": "^4.18.2", + "express-async-errors": "^3.1.1", "mongoose": "^7.2.2" }, "devDependencies": { @@ -2430,6 +2431,14 @@ "node": ">= 0.10.0" } }, + "node_modules/express-async-errors": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/express-async-errors/-/express-async-errors-3.1.1.tgz", + "integrity": "sha512-h6aK1da4tpqWSbyCa3FxB/V6Ehd4EEB15zyQq9qe75OZBp0krinNKuH4rAY+S/U/2I36vdLAUFSjQJ+TFmODng==", + "peerDependencies": { + "express": "^4.16.2" + } + }, "node_modules/express/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", diff --git a/part4/bloglist/package.json b/part4/bloglist/package.json index c818d95..b0dbe18 100644 --- a/part4/bloglist/package.json +++ b/part4/bloglist/package.json @@ -15,6 +15,7 @@ "cross-env": "^7.0.3", "dotenv": "^16.1.1", "express": "^4.18.2", + "express-async-errors": "^3.1.1", "mongoose": "^7.2.2" }, "devDependencies": { diff --git a/part4/bloglist/tests/blog_api.test.js b/part4/bloglist/tests/blog_api.test.js index 65fd55e..712a7d5 100644 --- a/part4/bloglist/tests/blog_api.test.js +++ b/part4/bloglist/tests/blog_api.test.js @@ -4,6 +4,14 @@ const app = require('../app') const api = supertest(app) +const Blog = require('../models/blog') +const helper = require('./test_helper') + +beforeEach(async () => { + await Blog.deleteMany({}) + await Blog.insertMany(helper.initialBlogs) +}) + test('blogs are returned as json', async () => { await api .get('/api/blogs') @@ -11,6 +19,48 @@ test('blogs are returned as json', async () => { .expect('Content-Type', /application\/json/) }) +test('all blogs are returned', async () => { + const response = await api.get('/api/blogs') + expect(response.body).toHaveLength(helper.initialBlogs.length) +}) + +test('a specific blog is within the returned blogs', async () => { + const response = await api.get('/api/blogs') + const contents = response.body.map((r) => r.title) + expect(contents).toContain('Another blog') +}) + +test('a valid blog can be added ', async () => { + const newBlog = { + title: 'Test', + author: 'Tester', + url: 'http:/test.com', + likes: 999 + } + + await api + .post('/api/blogs') + .send(newBlog) + .expect(201) + .expect('Content-Type', /application\/json/) + + const blogsAtEnd = await helper.blogsInDb() + expect(blogsAtEnd).toHaveLength(helper.initialBlogs.length + 1) + const contents = blogsAtEnd.map((n) => n.title) + expect(contents).toContain('Test') +}) + +test('blog without content is not added', async () => { + const newBlog = { + likes: 999 + } + + await api.post('/api/blogs').send(newBlog).expect(400) + + const blogsAtEnd = await helper.blogsInDb() + expect(blogsAtEnd).toHaveLength(helper.initialBlogs.length) +}) + afterAll(async () => { await mongoose.connection.close() -}) \ No newline at end of file +}) diff --git a/part4/bloglist/tests/test_helper.js b/part4/bloglist/tests/test_helper.js new file mode 100644 index 0000000..6e082a2 --- /dev/null +++ b/part4/bloglist/tests/test_helper.js @@ -0,0 +1,45 @@ +const Blog = require('../models/blog') + +const initialBlogs = [ + { + title: 'My blog', + author: 'Andrew', + url: 'www.andrew.eu', + likes: 1000, + }, + { + title: 'My blog 2', + author: 'Andrew', + url: 'www.andrew.eu', + likes: 3000, + }, + { + title: 'Another blog', + author: 'Hans', + url: 'www.andrew.eu', + likes: 5000, + } +] + +const nonExistingId = async () => { + const blog = new Blog({ + title: 'Test', + author: 'tester', + url: 'www.test.eu', + likes: 999, + }) + + await blog.save() + await blog.deleteOne() + + return blog._id.toString() +} + +const blogsInDb = async () => { + const blogs = await Blog.find({}) + return blogs.map(blog => blog.toJSON()) +} + +module.exports = { + initialBlogs, nonExistingId, blogsInDb +} \ No newline at end of file diff --git a/part4/bloglist/utils/config.js b/part4/bloglist/utils/config.js index 979b2c7..807c7e3 100644 --- a/part4/bloglist/utils/config.js +++ b/part4/bloglist/utils/config.js @@ -1,7 +1,9 @@ require('dotenv').config() const PORT = process.env.PORT -const MONGODB_URI = process.env.MONGODB_URI +const MONGODB_URI = process.env.NODE_ENV === 'test' + ? process.env.TEST_MONGODB_URI + : process.env.MONGODB_URI module.exports = { MONGODB_URI, diff --git a/part4/bloglist/utils/logger.js b/part4/bloglist/utils/logger.js index 3c55ba7..2fe10f5 100644 --- a/part4/bloglist/utils/logger.js +++ b/part4/bloglist/utils/logger.js @@ -1,9 +1,13 @@ const info = (...params) => { - console.log(...params) + if (process.env.NODE_ENV !== 'test') { + console.log(...params) + } } const error = (...params) => { - console.error(...params) + if (process.env.NODE_ENV !== 'test') { + console.error(...params) + } } module.exports = {