Compare commits
No commits in common. "b839aeba78fb51b0e4a542fc5dd76cb4ec718db7" and "8bb31432c72ac468c5c660eee36c50f557ee6f43" have entirely different histories.
b839aeba78
...
8bb31432c7
13 changed files with 34 additions and 387 deletions
|
|
@ -5,7 +5,7 @@
|
|||
"scripts": {
|
||||
"start": "node src/app.js",
|
||||
"dev": "node --watch src/app.js",
|
||||
"test": "node --test"
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
|
|
|
|||
|
|
@ -1,12 +1,37 @@
|
|||
const express = require("express");
|
||||
const { addRoutes } = require("./routes");
|
||||
const app = express();
|
||||
const express = require('express')
|
||||
const mongoose = require('mongoose')
|
||||
|
||||
app.use(express.json());
|
||||
const app = express()
|
||||
|
||||
addRoutes(app);
|
||||
const blogSchema = mongoose.Schema({
|
||||
title: String,
|
||||
author: String,
|
||||
url: String,
|
||||
likes: Number,
|
||||
})
|
||||
|
||||
const PORT = 3003;
|
||||
const Blog = mongoose.model('Blog', blogSchema)
|
||||
|
||||
const mongoUrl = 'mongodb://localhost/bloglist'
|
||||
mongoose.connect(mongoUrl)
|
||||
|
||||
app.use(express.json())
|
||||
|
||||
app.get('/api/blogs', (request, response) => {
|
||||
Blog.find({}).then((blogs) => {
|
||||
response.json(blogs)
|
||||
})
|
||||
})
|
||||
|
||||
app.post('/api/blogs', (request, response) => {
|
||||
const blog = new Blog(request.body)
|
||||
|
||||
blog.save().then((result) => {
|
||||
response.status(201).json(result)
|
||||
})
|
||||
})
|
||||
|
||||
const PORT = 3003
|
||||
app.listen(PORT, () => {
|
||||
console.log(`Server running on port ${PORT}`);
|
||||
});
|
||||
console.log(`Server running on port ${PORT}`)
|
||||
})
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
const mongoose = require('mongoose')
|
||||
|
||||
const blogSchema = mongoose.Schema({
|
||||
title: String,
|
||||
author: String,
|
||||
url: String,
|
||||
likes: Number,
|
||||
})
|
||||
|
||||
const Blog = mongoose.model('Blog', blogSchema)
|
||||
|
||||
const mongoUrl = 'mongodb://localhost/bloglist'
|
||||
mongoose.connect(mongoUrl)
|
||||
|
||||
module.exports = {models: {Blog}}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
const { models } = require("./db");
|
||||
const Blog = models.Blog;
|
||||
|
||||
BASE_API_PATH = "/api";
|
||||
|
||||
const addRoutes = (app) => {
|
||||
app.get(`${BASE_API_PATH}/blogs`, (request, response) => {
|
||||
Blog.find({}).then((blogs) => {
|
||||
response.json(blogs);
|
||||
});
|
||||
});
|
||||
|
||||
app.post(`${BASE_API_PATH}/blogs`, (request, response) => {
|
||||
const blog = new Blog(request.body);
|
||||
|
||||
blog.save().then((result) => {
|
||||
response.status(201).json(result);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = { addRoutes };
|
||||
|
|
@ -1,89 +0,0 @@
|
|||
const reverse = (string) => {
|
||||
return string.split("").reverse().join("");
|
||||
};
|
||||
|
||||
const average = (array) => {
|
||||
const reducer = (sum, item) => {
|
||||
return sum + item;
|
||||
};
|
||||
|
||||
return array.length === 0 ? 0 : array.reduce(reducer, 0) / array.length;
|
||||
};
|
||||
|
||||
const listHelper = (posts) => {
|
||||
console.log("lol");
|
||||
return 1;
|
||||
};
|
||||
|
||||
const totalLikes = (posts) => {
|
||||
if (!posts) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const likeCount = posts
|
||||
.map((post) => post.likes)
|
||||
.reduce((cum, value) => cum + value, 0);
|
||||
|
||||
return likeCount;
|
||||
};
|
||||
|
||||
const favoritePost = (posts) => {
|
||||
if (!posts || posts.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const highestLikes = posts.reduce(
|
||||
(max, post) => (post.likes > max ? (max = post.likes) : max),
|
||||
0
|
||||
);
|
||||
|
||||
const favoritePost = posts.find((post) => post.likes == highestLikes);
|
||||
|
||||
return favoritePost;
|
||||
};
|
||||
|
||||
const mostPosts = (posts) => {
|
||||
if (!posts || posts.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const countMap = posts.reduce((acc, post) => {
|
||||
acc[post.author] = (acc[post.author] || 0) + 1;
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
const [author, postsCount] = Object.entries(countMap).reduce(
|
||||
(max, entry) => (entry[1] > max[1] ? entry : max),
|
||||
['', 0]
|
||||
);
|
||||
|
||||
return { author, posts: postsCount };
|
||||
};
|
||||
|
||||
const mostLikes = (posts) => {
|
||||
if (!posts || posts.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const likesMap = posts.reduce((acc, post) => {
|
||||
acc[post.author] = (acc[post.author] || 0) + post.likes;
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
const [author, likesCount] = Object.entries(likesMap).reduce(
|
||||
(max, entry) => (entry[1] > max[1] ? entry : max),
|
||||
['', 0]
|
||||
);
|
||||
|
||||
return { author, likes: likesCount };
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
reverse,
|
||||
average,
|
||||
listHelper,
|
||||
totalLikes,
|
||||
favoritePost,
|
||||
mostPosts,
|
||||
mostLikes
|
||||
};
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
const { test, describe } = require('node:test')
|
||||
const assert = require('node:assert')
|
||||
|
||||
const average = require('../src/utils').average
|
||||
|
||||
describe('average', () => {
|
||||
test('of one value is the value itself', () => {
|
||||
assert.strictEqual(average([1]), 1)
|
||||
})
|
||||
|
||||
test('of many is calculated right', () => {
|
||||
assert.strictEqual(average([1, 2, 3, 4, 5, 6]), 3.5)
|
||||
})
|
||||
|
||||
test('of empty array is zero', () => {
|
||||
assert.strictEqual(average([]), 0)
|
||||
})
|
||||
})
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
const { test, describe } = require("node:test");
|
||||
const assert = require("node:assert");
|
||||
const { favoritePost } = require("../src/utils");
|
||||
|
||||
describe("favoritePost ", () => {
|
||||
const posts = [
|
||||
{
|
||||
_id: "5a422aa71b54a676234d17f8",
|
||||
title: "Go To Statement Considered Harmful",
|
||||
author: "Edsger W. Dijkstra",
|
||||
url: "https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.pdf",
|
||||
likes: 5,
|
||||
__v: 0,
|
||||
},
|
||||
{
|
||||
_id: "5a422aa71b54a676234d17f8",
|
||||
title: "Go To Statement Considered Harmful",
|
||||
author: "Edsger W. Dijkstra",
|
||||
url: "https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.pdf",
|
||||
likes: 2,
|
||||
__v: 0,
|
||||
},
|
||||
];
|
||||
|
||||
const emptyArray = [];
|
||||
|
||||
const gibberish = "asdaSd123asd";
|
||||
|
||||
test("finds top properly", () => {
|
||||
assert.strictEqual(favoritePost(posts), posts[0]);
|
||||
});
|
||||
|
||||
test("works fine with empty array", () => {
|
||||
assert.strictEqual(favoritePost(emptyArray), null);
|
||||
});
|
||||
|
||||
test("fails with gibberish input", () => {
|
||||
const failedCall = () => {
|
||||
favoritePost(gibberish);
|
||||
};
|
||||
assert.throws(failedCall, Error);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
const { test, describe } = require("node:test");
|
||||
const assert = require("node:assert");
|
||||
const { listHelper } = require("../src/utils");
|
||||
|
||||
test("dummy returns one", () => {
|
||||
const blogs = [];
|
||||
|
||||
const result = listHelper(blogs);
|
||||
assert.strictEqual(result, 1);
|
||||
});
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
const { test, describe } = require("node:test");
|
||||
const assert = require("node:assert");
|
||||
const { mostLikes } = require("../src/utils");
|
||||
|
||||
describe("most likes ", () => {
|
||||
const posts = [
|
||||
{
|
||||
_id: "5a422aa71b54a676234d17f8",
|
||||
title: "Go To Statement Considered Harmful",
|
||||
author: "Edsger W. Dijkstra",
|
||||
url: "https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.pdf",
|
||||
likes: 5,
|
||||
__v: 0,
|
||||
},
|
||||
{
|
||||
_id: "5a422aa71b54a676234d17f8",
|
||||
title: "Go To Statement Considered Harmful",
|
||||
author: "Edsger W. Dijkstra",
|
||||
url: "https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.pdf",
|
||||
likes: 2,
|
||||
__v: 0,
|
||||
},
|
||||
{
|
||||
_id: "123",
|
||||
title: "Lololo",
|
||||
author: "John Doe",
|
||||
url: "https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.pdf",
|
||||
likes: 1,
|
||||
__v: 0,
|
||||
},
|
||||
];
|
||||
|
||||
const emptyArray = [];
|
||||
|
||||
const gibberish = "asdaSd123asd";
|
||||
|
||||
test("finds top author properly", () => {
|
||||
assert.deepStrictEqual(mostLikes(posts), {
|
||||
author: "Edsger W. Dijkstra",
|
||||
likes: 7,
|
||||
});
|
||||
});
|
||||
|
||||
test("works fine with empty array", () => {
|
||||
assert.strictEqual(mostLikes(emptyArray), null);
|
||||
});
|
||||
|
||||
test("fails with gibberish input", () => {
|
||||
const failedCall = () => {
|
||||
mostLikes(gibberish);
|
||||
};
|
||||
assert.throws(failedCall, Error);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
const { test, describe } = require("node:test");
|
||||
const assert = require("node:assert");
|
||||
const { mostPosts } = require("../src/utils");
|
||||
|
||||
describe("most posts ", () => {
|
||||
const posts = [
|
||||
{
|
||||
_id: "5a422aa71b54a676234d17f8",
|
||||
title: "Go To Statement Considered Harmful",
|
||||
author: "Edsger W. Dijkstra",
|
||||
url: "https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.pdf",
|
||||
likes: 5,
|
||||
__v: 0,
|
||||
},
|
||||
{
|
||||
_id: "5a422aa71b54a676234d17f8",
|
||||
title: "Go To Statement Considered Harmful",
|
||||
author: "Edsger W. Dijkstra",
|
||||
url: "https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.pdf",
|
||||
likes: 2,
|
||||
__v: 0,
|
||||
},
|
||||
{
|
||||
_id: "123",
|
||||
title: "Lololo",
|
||||
author: "John Doe",
|
||||
url: "https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.pdf",
|
||||
likes: 1,
|
||||
__v: 0,
|
||||
},
|
||||
];
|
||||
|
||||
const emptyArray = [];
|
||||
|
||||
const gibberish = "asdaSd123asd";
|
||||
|
||||
test("finds top author properly", () => {
|
||||
assert.deepStrictEqual(mostPosts(posts), {
|
||||
author: "Edsger W. Dijkstra",
|
||||
posts: 2,
|
||||
});
|
||||
});
|
||||
|
||||
test("works fine with empty array", () => {
|
||||
assert.strictEqual(mostPosts(emptyArray), null);
|
||||
});
|
||||
|
||||
test("fails with gibberish input", () => {
|
||||
const failedCall = () => {
|
||||
mostPosts(gibberish);
|
||||
};
|
||||
assert.throws(failedCall, Error);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
const { test } = require('node:test')
|
||||
const assert = require('node:assert')
|
||||
|
||||
const reverse = require('../src/utils.js').reverse
|
||||
|
||||
test('reverse of a', () => {
|
||||
const result = reverse('a')
|
||||
|
||||
assert.strictEqual(result, 'a')
|
||||
})
|
||||
|
||||
test('reverse of react', () => {
|
||||
const result = reverse('react')
|
||||
|
||||
assert.strictEqual(result, 'tcaer')
|
||||
})
|
||||
|
||||
test('reverse of saippuakauppias', () => {
|
||||
const result = reverse('saippuakauppias')
|
||||
|
||||
assert.strictEqual(result, 'saippuakauppias')
|
||||
})
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
const { test, describe } = require("node:test");
|
||||
const assert = require("node:assert");
|
||||
const { totalLikes } = require("../src/utils");
|
||||
|
||||
describe("total likes ", () => {
|
||||
const posts = [
|
||||
{
|
||||
_id: "5a422aa71b54a676234d17f8",
|
||||
title: "Go To Statement Considered Harmful",
|
||||
author: "Edsger W. Dijkstra",
|
||||
url: "https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.pdf",
|
||||
likes: 5,
|
||||
__v: 0,
|
||||
},
|
||||
{
|
||||
_id: "5a422aa71b54a676234d17f8",
|
||||
title: "Go To Statement Considered Harmful",
|
||||
author: "Edsger W. Dijkstra",
|
||||
url: "https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.pdf",
|
||||
likes: 2,
|
||||
__v: 0,
|
||||
},
|
||||
];
|
||||
|
||||
const emptyArray = [];
|
||||
|
||||
const gibberish = "asdaSd123asd";
|
||||
|
||||
test("counts likes properly", () => {
|
||||
assert.strictEqual(totalLikes(posts), 7);
|
||||
});
|
||||
|
||||
test("works fine with empty array", () => {
|
||||
assert.strictEqual(totalLikes(emptyArray), 0);
|
||||
});
|
||||
|
||||
test("fails with gibberish input", () => {
|
||||
const failedCall = () => {
|
||||
totalLikes(gibberish);
|
||||
};
|
||||
assert.throws(failedCall, Error);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
Exercises:
|
||||
* [X] 4.1
|
||||
* [X] 4.2
|
||||
* [X] 4.3
|
||||
* [X] 4.4
|
||||
* [X] 4.5
|
||||
* [X] 4.6
|
||||
* [X] 4.7
|
||||
Loading…
Add table
Add a link
Reference in a new issue