Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hb1 #30

Open
wants to merge 26 commits into
base: main
Choose a base branch
from
Open

Hb1 #30

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
4c3c18d
Update README.md
williamlines Nov 28, 2022
747e826
Merge pull request #1 from williamlines/williamlines-patch-1
williamlines Nov 28, 2022
fa6072c
Understanding the code
Nov 30, 2022
3074b52
fixed broken tests
williamlines Dec 1, 2022
18a29cc
added the rest of the files missed by first commit
williamlines Dec 1, 2022
98b5d13
fixed spelling error
williamlines Dec 1, 2022
de6f9a2
Home page established and route to /home created
Dec 1, 2022
a2f1908
Add tests for date and implement method
kwatts949 Dec 1, 2022
6c24d68
added route to new post form and mostly built the functionality
williamlines Dec 1, 2022
9a53af5
fixed post request
williamlines Dec 1, 2022
cd7d956
driver switch
robin277t Dec 1, 2022
5f1c9c5
now updates token (maybe?)
tomfyfe85 Dec 1, 2022
c460972
cypress homepage test
tbuller Dec 1, 2022
061ba58
switch driver
kwatts949 Dec 1, 2022
32a458a
Merge pull request #2 from williamlines/feature_newest_post
kwatts949 Dec 1, 2022
ccfeafc
can post to feed with an updated token (NewPostForm.js). NewPostForm.…
tomfyfe85 Dec 1, 2022
879419c
Homepage complete with testing in end to end
tbuller Dec 2, 2022
8a5715d
started test
williamlines Dec 2, 2022
f0a4e15
fixed component test
williamlines Dec 2, 2022
181eb90
feature complete and tested
robin277t Dec 2, 2022
be98534
making_a_post_on_a_page.cy.js completed
tomfyfe85 Dec 2, 2022
0e14dce
Merge pull request #4 from williamlines/post-have-users-2
robin277t Dec 2, 2022
5e01bf6
merge conflict
williamlines Dec 2, 2022
78409f4
Merge pull request #5 from williamlines/expl
williamlines Dec 2, 2022
dd7ed5e
solve conflicts
tbuller Dec 2, 2022
de5593d
Merge branch 'main' into HB1
robin277t Dec 2, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Acebook

# Trello Board:

https://trello.com/b/Ckf68HAB/acebook

In this project, you are tasked with working on an existing application. A significant part of the challenge will be to familiarise yourself with the codebase you've inherited, as you work to **improve and extend** it.

## Videos
Expand Down
19 changes: 10 additions & 9 deletions api/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,30 @@ const JWT = require("jsonwebtoken");
const postsRouter = require("./routes/posts");
const tokensRouter = require("./routes/tokens");
const usersRouter = require("./routes/users");
const homeRouter = require("./routes/home");

const app = express();

// setup for receiving JSON
app.use(express.json())
app.use(express.json());

app.use(logger("dev"));
app.use(express.json());
app.use(express.static(path.join(__dirname, "public")));

// middleware function to check for valid tokens
const tokenChecker = (req, res, next) => {

let token;
const authHeader = req.get("Authorization")
const authHeader = req.get("Authorization");

if(authHeader) {
token = authHeader.slice(7)
if (authHeader) {
token = authHeader.slice(7);
}

JWT.verify(token, process.env.JWT_SECRET, (err, payload) => {
if(err) {
console.log(err)
res.status(401).json({message: "auth error"});
if (err) {
console.log(err);
res.status(401).json({ message: "auth error" });
} else {
req.user_id = payload.user_id;
next();
Expand All @@ -42,6 +42,7 @@ const tokenChecker = (req, res, next) => {
app.use("/posts", tokenChecker, postsRouter);
app.use("/tokens", tokensRouter);
app.use("/users", usersRouter);
app.use("/", homeRouter);

// catch 404 and forward to error handler
app.use((req, res, next) => {
Expand All @@ -55,7 +56,7 @@ app.use((err, req, res) => {
res.locals.error = req.app.get("env") === "development" ? err : {};

// respond with details of the error
res.status(err.status || 500).json({message: 'server error'})
res.status(err.status || 500).json({ message: "server error" });
});

module.exports = app;
10 changes: 6 additions & 4 deletions api/controllers/posts.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,21 @@ const PostsController = {
if (err) {
throw err;
}
const token = await TokenGenerator.jsonwebtoken(req.user_id)
const token = await TokenGenerator.jsonwebtoken(req.user_id);
res.status(200).json({ posts: posts, token: token });
});
}).sort({ time: -1 });
},
Create: (req, res) => {
req.body.time = Date.now();
req.body.posterUserId = req.user_id;
const post = new Post(req.body);
post.save(async (err) => {
if (err) {
throw err;
}

const token = await TokenGenerator.jsonwebtoken(req.user_id)
res.status(201).json({ message: 'OK', token: token });
const token = await TokenGenerator.jsonwebtoken(req.user_id);
res.status(201).json({ message: "OK", token: token });
});
},
};
Expand Down
11 changes: 5 additions & 6 deletions api/controllers/tokens.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
const User = require("../models/user");
const TokenGenerator = require("../models/token_generator")
const TokenGenerator = require("../models/token_generator");

const SessionsController = {

Create: (req, res) => {
const email = req.body.email;
const password = req.body.password;

User.findOne({ email: email }).then(async (user) => {
if (!user) {
console.log("auth error: user not found")
console.log("auth error: user not found");
res.status(401).json({ message: "auth error" });
} else if (user.password !== password) {
console.log("auth error: passwords do not match")
console.log("auth error: passwords do not match");
res.status(401).json({ message: "auth error" });
} else {
const token = await TokenGenerator.jsonwebtoken(user.id)
const token = await TokenGenerator.jsonwebtoken(user.id);
res.status(201).json({ token: token, message: "OK" });
}
});
}
},
};

module.exports = SessionsController;
4 changes: 2 additions & 2 deletions api/controllers/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ const UsersController = {
const user = new User(req.body);
user.save((err) => {
if (err) {
res.status(400).json({message: 'Bad request'})
res.status(400).json({ message: "Bad request" });
} else {
res.status(201).json({ message: 'OK' });
res.status(201).json({ message: "OK" });
}
});
},
Expand Down
4 changes: 3 additions & 1 deletion api/models/post.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
const mongoose = require("mongoose");

const PostSchema = new mongoose.Schema({
message: String
message: String,
time: Number,
posterUserId: String
});

const Post = mongoose.model("Post", PostSchema);
Expand Down
4 changes: 2 additions & 2 deletions api/models/token_generator.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
const JWT = require("jsonwebtoken");
const options = {expiresIn: "10m"};
const options = { expiresIn: "10m" };
const secret = process.env.JWT_SECRET;

class TokenGenerator {
static jsonwebtoken(user_id) {
return JWT.sign({user_id: user_id, iat: Date.now()}, secret, options);
return JWT.sign({ user_id: user_id, iat: Date.now() }, secret, options);
}
}

Expand Down
2 changes: 1 addition & 1 deletion api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"scripts": {
"start": "nodemon ./bin/www",
"start:test": "MONGODB_URL='mongodb://0.0.0.0/acebook_test' npm start",
"test": "jest"
"test": "jest --runInBand"
},
"engines": {
"node": ">=18.1.0"
Expand Down
132 changes: 82 additions & 50 deletions api/spec/controllers/posts.spec.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
const app = require("../../app");
const request = require("supertest");
require("../mongodb_helper");
const Post = require('../../models/post');
const User = require('../../models/user');
const TokenGenerator = require('../../models/token_generator');
const Post = require("../../models/post");
const User = require("../../models/user");
const TokenGenerator = require("../../models/token_generator");
const JWT = require("jsonwebtoken");
let token;

describe("/posts", () => {
beforeAll( async () => {
const user = new User({email: "[email protected]", password: "12345678"});
beforeAll(async () => {
const user = new User({ email: "[email protected]", password: "12345678" });
userIdTest = user.id
await user.save();
token = TokenGenerator.jsonwebtoken(user.id);
});

beforeEach( async () => {
beforeEach(async () => {
await Post.deleteMany({});
})
});

afterAll( async () => {
afterAll(async () => {
await User.deleteMany({});
await Post.deleteMany({});
})
});

describe("POST, when token is present", () => {
test("responds with a 201", async () => {
Expand All @@ -31,7 +32,7 @@ describe("/posts", () => {
.send({ message: "hello world", token: token });
expect(response.status).toEqual(201);
});

test("creates a new post", async () => {
await request(app)
.post("/posts")
Expand All @@ -41,112 +42,143 @@ describe("/posts", () => {
expect(posts.length).toEqual(1);
expect(posts[0].message).toEqual("hello world");
});


test("creates a new post and adds in the time", async () => {
const time = Date.now();
await request(app)
.post("/posts")
.set("Authorization", `Bearer ${token}`)
.send({ message: "hello world", token: token });
let posts = await Post.find();
expect(posts.length).toEqual(1);
expect(posts[0].message).toEqual("hello world");
expect(posts[0].time / 10000).toBeCloseTo(time / 10000);
});

test("creates a new post and adds in the userID", async () => {
await request(app)
.post("/posts")
.set("Authorization", `Bearer ${token}`)
.send({ message: "hello world", token: token });
let posts = await Post.find();
expect(posts.length).toEqual(1);
expect(posts[0].message).toEqual("hello world");
expect(posts[0].posterUserId).toEqual(userIdTest);
});

test("returns a new token", async () => {
let response = await request(app)
.post("/posts")
.set("Authorization", `Bearer ${token}`)
.send({ message: "hello world", token: token })
.send({ message: "hello world", token: token });
let newPayload = JWT.decode(response.body.token, process.env.JWT_SECRET);
let originalPayload = JWT.decode(token, process.env.JWT_SECRET);
expect(newPayload.iat > originalPayload.iat).toEqual(true);
});
});
});

describe("POST, when token is missing", () => {
test("responds with a 401", async () => {
let response = await request(app)
.post("/posts")
.send({ message: "hello again world" });
expect(response.status).toEqual(401);
});

test("a post is not created", async () => {
await request(app)
.post("/posts")
.send({ message: "hello again world" });
await request(app).post("/posts").send({ message: "hello again world" });
let posts = await Post.find();
expect(posts.length).toEqual(0);
});

test("a token is not returned", async () => {
let response = await request(app)
.post("/posts")
.send({ message: "hello again world" });
expect(response.body.token).toEqual(undefined);
});
})
});

describe("GET, when token is present", () => {
test("returns every post in the collection", async () => {
let post1 = new Post({message: "howdy!"});
let post2 = new Post({message: "hola!"});
let post1 = new Post({ message: "howdy!" });
let post2 = new Post({ message: "hola!" });
await post1.save();
await post2.save();
let response = await request(app)
.get("/posts")
.set("Authorization", `Bearer ${token}`)
.send({token: token});
let messages = response.body.posts.map((post) => ( post.message ));
.send({ token: token });
let messages = response.body.posts.map((post) => post.message);
expect(messages).toEqual(["howdy!", "hola!"]);
})
});

test("the response code is 200", async () => {
let post1 = new Post({message: "howdy!"});
let post2 = new Post({message: "hola!"});
let post1 = new Post({ message: "howdy!" });
let post2 = new Post({ message: "hola!" });
await post1.save();
await post2.save();
let response = await request(app)
.get("/posts")
.set("Authorization", `Bearer ${token}`)
.send({token: token});
.send({ token: token });
expect(response.status).toEqual(200);
})
});

test("returns every post in the collection in reverse time order", async () => {
let post1 = new Post({ message: "howdy!", time: 1669897643479 });
let post2 = new Post({ message: "hola!", time: 1669897643480 });
await post1.save();
await post2.save();
let response = await request(app)
.get("/posts")
.set("Authorization", `Bearer ${token}`)
.send({ token: token });
let messages = response.body.posts.map((post) => post.message);
expect(messages).toEqual(["hola!", "howdy!"]);
});

test("returns a new token", async () => {
let post1 = new Post({message: "howdy!"});
let post2 = new Post({message: "hola!"});
let post1 = new Post({ message: "howdy!" });
let post2 = new Post({ message: "hola!" });
await post1.save();
await post2.save();
let response = await request(app)
.get("/posts")
.set("Authorization", `Bearer ${token}`)
.send({token: token});
.send({ token: token });
let newPayload = JWT.decode(response.body.token, process.env.JWT_SECRET);
let originalPayload = JWT.decode(token, process.env.JWT_SECRET);
expect(newPayload.iat > originalPayload.iat).toEqual(true);
})
})
});
});

describe("GET, when token is missing", () => {
test("returns no posts", async () => {
let post1 = new Post({message: "howdy!"});
let post2 = new Post({message: "hola!"});
let post1 = new Post({ message: "howdy!" });
let post2 = new Post({ message: "hola!" });
await post1.save();
await post2.save();
let response = await request(app)
.get("/posts");
let response = await request(app).get("/posts");
expect(response.body.posts).toEqual(undefined);
})
});

test("the response code is 401", async () => {
let post1 = new Post({message: "howdy!"});
let post2 = new Post({message: "hola!"});
let post1 = new Post({ message: "howdy!" });
let post2 = new Post({ message: "hola!" });
await post1.save();
await post2.save();
let response = await request(app)
.get("/posts");
let response = await request(app).get("/posts");
expect(response.status).toEqual(401);
})
});

test("does not return a new token", async () => {
let post1 = new Post({message: "howdy!"});
let post2 = new Post({message: "hola!"});
let post1 = new Post({ message: "howdy!" });
let post2 = new Post({ message: "hola!" });
await post1.save();
await post2.save();
let response = await request(app)
.get("/posts");
let response = await request(app).get("/posts");
expect(response.body.token).toEqual(undefined);
})
})
});
});
});
Loading