diff --git a/README.md b/README.md index 9000506..b6b816f 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Answers to [openfullstack.com](https://fullstackopen.com) course exercises from _Details solutions: [4.1](https://github.com/patchamama/fullstackopen-part4-bloglist/commit/01104c7798ad53f35ee73994826f5cc3602b9b3e) | [4.2](https://github.com/patchamama/fullstackopen-part4-bloglist/commit/7c913309759236084783f4bdfdec443c5b9e19d5)_ - [Exercises 4.3.-4.7.](https://fullstackopen.com/en/part4/structure_of_backend_application_introduction_to_testing#exercises-4-3-4-7) - _Details solutions: [4.3](https://github.com/patchamama/fullstackopen-part4-bloglist/commit/0f1a759e78310de711531ed481917496e2f50ec8) | [4.4](https://github.com/patchamama/fullstackopen-part4-bloglist/commit/2585dc72841e8382123fa481aa149d19dd611482) | [4.5]() | [4.6]() | [4.7]()_ + _Details solutions: [4.3](https://github.com/patchamama/fullstackopen-part4-bloglist/commit/0f1a759e78310de711531ed481917496e2f50ec8) | [4.4](https://github.com/patchamama/fullstackopen-part4-bloglist/commit/2585dc72841e8382123fa481aa149d19dd611482) | [4.5](https://github.com/patchamama/fullstackopen-part4-bloglist/commit/4fd94b8779e33ea32b3703a6e6a823291d247e0c) | [4.6]() | [4.7]()_ ### b. Testing the backend diff --git a/package-lock.json b/package-lock.json index be2907a..38357dc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "cors": "2.8.5", "dotenv": "16.3.1", "express": "4.18.2", + "lodash": "^4.17.21", "mongoose": "7.5.0" }, "devDependencies": { @@ -3902,6 +3903,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", diff --git a/package.json b/package.json index 7d248c1..f43e2ef 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "cors": "2.8.5", "dotenv": "16.3.1", "express": "4.18.2", + "lodash": "^4.17.21", "mongoose": "7.5.0" }, "devDependencies": { diff --git a/tests/blog.test.js b/tests/blog.test.js index 814c0cc..dc54a74 100644 --- a/tests/blog.test.js +++ b/tests/blog.test.js @@ -162,3 +162,82 @@ describe('favorites', () => { expect(result.likes).toEqual(12) }) }) + +describe('Authors with more blogs', () => { + test('More blogs with empty list', () => { + const blogs = [{}] + const result = listHelper.mostBlogs(blogs) + console.log(result) + expect(result).toEqual({ author: undefined, entries: 1 }) + }) + test('More blogs with one element in the list', () => { + const blogs = [ + { + _id: '5a422bc61b54a676234d17fc', + title: 'Type wars', + author: 'Robert C. Martin', + url: 'http://blog.cleancoder.com/uncle-bob/2016/05/01/TypeWars.html', + likes: 2, + __v: 0, + }, + ] + const result = listHelper.mostBlogs(blogs) + console.log(result) + expect(result).toEqual({ author: 'Robert C. Martin', entries: 1 }) + }) + test('More blogs with big list', () => { + const blogs = [ + { + _id: '5a422b3a1b54a676234d17f9', + title: 'Canonical string reduction', + author: 'Edsger W. Dijkstra', + url: 'http://www.cs.utexas.edu/~EWD/transcriptions/EWD08xx/EWD808.html', + likes: 12, + __v: 0, + }, + { + _id: '5a422a851b54a676234d17f7', + title: 'React patterns', + author: 'Michael Chan', + url: 'https://reactpatterns.com/', + likes: 7, + __v: 0, + }, + { + _id: '5a422aa71b54a676234d17f8', + title: 'Go To Statement Considered Harmful', + author: 'Edsger W. Dijkstra', + url: 'http://www.u.arizona.edu/~rubinson/copyright_violations/Go_To_Considered_Harmful.html', + likes: 5, + __v: 0, + }, + { + _id: '5a422b891b54a676234d17fa', + title: 'First class tests', + author: 'Robert C. Martin', + url: 'http://blog.cleancoder.com/uncle-bob/2017/05/05/TestDefinitions.htmll', + likes: 10, + __v: 0, + }, + { + _id: '5a422ba71b54a676234d17fb', + title: 'TDD harms architecture', + author: 'Robert C. Martin', + url: 'http://blog.cleancoder.com/uncle-bob/2017/03/03/TDD-Harms-Architecture.html', + likes: 0, + __v: 0, + }, + { + _id: '5a422bc61b54a676234d17fc', + title: 'Type wars', + author: 'Robert C. Martin', + url: 'http://blog.cleancoder.com/uncle-bob/2016/05/01/TypeWars.html', + likes: 2, + __v: 0, + }, + ] + const result = listHelper.mostBlogs(blogs) + console.log(result) + expect(result).toEqual({ author: 'Robert C. Martin', entries: 3 }) + }) +}) diff --git a/utils/list_helper.js b/utils/list_helper.js index 0c7bad2..4ac8036 100644 --- a/utils/list_helper.js +++ b/utils/list_helper.js @@ -1,3 +1,5 @@ +const _ = require('lodash') + const dummy = (blogs) => { // ... return 1 @@ -14,12 +16,27 @@ const favoriteBlog = (blogs) => { const reducer = (max, item) => { return max.likes > item.likes ? max : item } - console.log(blogs.reduce(reducer, 0)) + // console.log(blogs.reduce(reducer, 0)) return blogs.length === 0 ? {} : blogs.reduce(reducer, { likes: 0 }) } +const mostBlogs = (blogs) => { + if (blogs.length === 0) return { author: undefined, entries: 1 } + else if (blogs.length === 1) return { author: blogs[0].author, entries: 1 } + else { + const blogsByAuthor = _.groupBy(blogs, 'author') + const authorEntries = _.map(blogsByAuthor, (blogs, author) => ({ + author, + entries: blogs.length, + })) + console.log(_.maxBy(authorEntries, 'entries')) + return _.maxBy(authorEntries, 'entries') + } +} + module.exports = { dummy, totalLikes, favoriteBlog, + mostBlogs, }