Step 3
Add tests/routes/users.test.js
with the following content. Notice that we decided only "admins" were allowed to work with the "users" endpoints.
const faker = require("faker");
const mongoose = require("mongoose");
const supertest = require("supertest");
const app = require("../../server");
const UserDao = require("../../server/data/UserDao");
const { createToken } = require("../../server/util/token");
const users = new UserDao();
const request = supertest(app);
const endpoint = "/api/users";
describe(`Test ${endpoint} endpoints`, () => {
const tokens = {};
beforeAll(async () => {
await mongoose.connect(global.__MONGO_URI__);
tokens.admin = await createToken({ role: "ADMIN" });
tokens.invalid = tokens.admin
.split("")
.sort(function () {
return 0.5 - Math.random();
})
.join("");
tokens.client = await createToken({ role: "CLIENT" });
tokens.expiredAdmin = await createToken({ role: "ADMIN" }, -1);
});
describe(`Test GET ${endpoint}`, () => {
const samples = [];
beforeAll(async () => {
samples[0] = await users.create({
username: faker.internet.userName(),
password: faker.internet.password(),
role: "CLIENT",
});
samples[1] = await users.create({
username: faker.internet.userName(),
password: faker.internet.password(),
role: "CLIENT",
});
samples[2] = await users.create({
username: faker.internet.userName(),
password: faker.internet.password(),
role: "ADMIN",
});
});
test("Return 403 for missing token", async () => {
const response = await request.get(endpoint);
expect(response.status).toBe(403);
});
test("Return 403 for invalid token", async () => {
const response = await request
.get(endpoint)
.set("Authorization", `Bearer ${tokens.invalid}`);
expect(response.status).toBe(403);
});
test("Return 403 for unauthorized token", async () => {
const response = await request
.get(endpoint)
.set("Authorization", `Bearer ${tokens.client}`);
expect(response.status).toBe(403);
});
test("Return 403 for expired token", async () => {
const response = await request
.get(endpoint)
.set("Authorization", `Bearer ${tokens.expiredAdmin}`);
expect(response.status).toBe(403);
});
test("Return 200 and list of users for successful request", async () => {
const response = await request
.get(endpoint)
.set("Authorization", `Bearer ${tokens.admin}`);
expect(response.status).toBe(200);
expect(response.body.data.length).toBe(samples.length);
});
describe(`Test GET ${endpoint} with query parameter`, () => {
test("Return 400 when both username and role query parameters are provided", async () => {
const username = samples[1].username;
const role = samples[1].role;
const response = await request
.get(`${endpoint}?username=${username}&role=${role}`)
.set("Authorization", `Bearer ${tokens.admin}`);
expect(response.status).toBe(400);
});
test("Return 200 and list of users for a given role", async () => {
const role = "ADMIN";
const response = await request
.get(`${endpoint}?role=${role}`)
.set("Authorization", `Bearer ${tokens.admin}`);
const expected = samples.filter((s) => s.role === role).length;
expect(response.status).toBe(200);
expect(response.body.data.length).toBe(expected);
});
test("Return 200 and empty list for non-existing role", async () => {
const role = "non-existing-role";
const response = await request
.get(`${endpoint}?role=${role}`)
.set("Authorization", `Bearer ${tokens.admin}`);
const expected = samples.filter((s) => s.role === role).length;
expect(response.status).toBe(200);
expect(response.body.data.length).toBe(expected);
});
test("Return 200 and a user for a given username", async () => {
const username = samples[1].username;
const response = await request
.get(`${endpoint}?username=${username}`)
.set("Authorization", `Bearer ${tokens.admin}`);
const expected = samples.filter((s) => s.username === username);
expect(response.status).toBe(200);
expect(response.body.data).toStrictEqual(expected);
});
test("Return 200 and empty list fon non-existing username", async () => {
const username = "non-existing-username";
const response = await request
.get(`${endpoint}?username=${username}`)
.set("Authorization", `Bearer ${tokens.admin}`);
const expected = samples.filter((s) => s.username === username);
expect(response.status).toBe(200);
expect(response.body.data).toStrictEqual(expected);
});
});
afterAll(async () => {
for (const sample of samples) {
await users.delete(sample._id);
}
});
});
describe(`Test GET ${endpoint}/:id`, () => {
let user;
let userToken;
beforeAll(async () => {
user = await users.create({
username: faker.internet.userName(),
password: faker.internet.password(),
role: "CLIENT",
});
userToken = await createToken(user);
});
test("Return 404 for an invalid id", async () => {
const id = mongoose.Types.ObjectId().toString();
const response = await request
.get(`${endpoint}/${id}`)
.set("Authorization", `Bearer ${tokens.admin}`);
expect(response.status).toBe(404);
});
test("Return 403 for missing token", async () => {
const id = user._id;
const response = await request.get(`${endpoint}/${id}`);
expect(response.status).toBe(403);
});
test("Return 403 for invalid token", async () => {
const id = user._id;
const response = await request
.get(`${endpoint}/${id}`)
.set("Authorization", `Bearer ${tokens.invalid}`);
expect(response.status).toBe(403);
});
test("Return 403 for unauthorized token", async () => {
const id = user._id;
const response = await request
.get(`${endpoint}/${id}`)
.set("Authorization", `Bearer ${tokens.client}`);
expect(response.status).toBe(403);
});
test("Return 403 for expired token", async () => {
const id = user._id;
const response = await request
.get(`${endpoint}/${id}`)
.set("Authorization", `Bearer ${tokens.expiredAdmin}`);
expect(response.status).toBe(403);
});
test("Return 200 and the user for a given id", async () => {
const id = user._id;
const response = await request
.get(`${endpoint}/${id}`)
.set("Authorization", `Bearer ${tokens.admin}`);
expect(response.status).toBe(200);
expect(response.body.data).toStrictEqual(user);
});
afterAll(async () => {
await users.delete(user._id);
});
});
describe(`Test POST ${endpoint}`, () => {
let user;
let existingUser;
beforeAll(async () => {
existingUser = await users.create({
username: "existing-user-post",
password: "existing-user-post",
role: "ADMIN",
});
user = {
username: "test-user-post",
password: "test-user-post",
role: "CLIENT",
};
});
test("Return 500 when username is already in-use", async () => {
const response = await request
.post(endpoint)
.send({
username: "existing-user-post",
password: "existing-user-post",
role: "ADMIN",
})
.set("Authorization", `Bearer ${tokens.admin}`);
expect(response.status).toBe(500);
});
test("Return 403 for missing token", async () => {
const response = await request.post(endpoint).send(user);
expect(response.status).toBe(403);
});
test("Return 403 for invalid token", async () => {
const response = await request
.post(endpoint)
.send(user)
.set("Authorization", `Bearer ${tokens.invalid}`);
expect(response.status).toBe(403);
});
test("Return 403 for unauthorized token", async () => {
const response = await request
.post(endpoint)
.send(user)
.set("Authorization", `Bearer ${tokens.client}`);
expect(response.status).toBe(403);
});
test("Return 403 for expired token", async () => {
const response = await request
.post(endpoint)
.send(user)
.set("Authorization", `Bearer ${tokens.expiredAdmin}`);
expect(response.status).toBe(403);
});
test("Return 400 for missing payload", async () => {
const response = await request
.post(endpoint)
.set("Authorization", `Bearer ${tokens.admin}`);
expect(response.status).toBe(400);
});
test("Return 400 for missing username", async () => {
const response = await request
.post(endpoint)
.send({
password: "test-user-post",
role: "CLIENT",
})
.set("Authorization", `Bearer ${tokens.admin}`);
expect(response.status).toBe(400);
});
test("Return 400 for missing password", async () => {
const response = await request
.post(endpoint)
.send({
username: "test-user-post",
role: "CLIENT",
})
.set("Authorization", `Bearer ${tokens.admin}`);
expect(response.status).toBe(400);
});
test("Return 400 for missing role", async () => {
const response = await request
.post(endpoint)
.send({
username: "test-user-post",
password: "test-user-post",
})
.set("Authorization", `Bearer ${tokens.admin}`);
expect(response.status).toBe(400);
});
test("Return 400 for invalid role", async () => {
const response = await request
.post(endpoint)
.send({
username: "test-user-post",
password: "test-user-post",
role: "SOME_UNSUPPORTED_ROLE",
})
.set("Authorization", `Bearer ${tokens.admin}`);
expect(response.status).toBe(400);
});
test("Return 201 and the user for successful request", async () => {
const response = await request
.post(endpoint)
.send(user)
.set("Authorization", `Bearer ${tokens.admin}`);
expect(response.status).toBe(201);
expect(response.body.data.username).toBe(user.username);
expect(response.body.data.role).toBe(user.role);
user._id = response.body.data._id;
});
afterAll(async () => {
await users.delete(existingUser._id);
await users.delete(user._id);
});
});
describe(`Test PUT ${endpoint}/:id`, () => {
let user;
let userToken;
beforeAll(async () => {
user = await users.create({
username: "test-user-put",
password: "test-user-put",
role: "CLIENT",
});
userToken = await createToken(user);
});
test("Return 404 for invalid ID", async () => {
const id = mongoose.Types.ObjectId().toString();
const response = await request
.put(`${endpoint}/${id}`)
.send({
role: "ADMIN",
})
.set("Authorization", `Bearer ${tokens.admin}`);
expect(response.status).toBe(404);
});
test("Return 403 for missing token", async () => {
const response = await request.put(`${endpoint}/${user._id}`).send({
role: "ADMIN",
});
expect(response.status).toBe(403);
});
test("Return 403 for invalid token", async () => {
const response = await request
.put(`${endpoint}/${user._id}`)
.send({
role: "ADMIN",
})
.set("Authorization", `Bearer ${tokens.invalid}`);
expect(response.status).toBe(403);
});
test("Return 403 for unauthorized token", async () => {
const response = await request
.put(`${endpoint}/${user._id}`)
.send({
role: "ADMIN",
})
.set("Authorization", `Bearer ${tokens.client}`);
expect(response.status).toBe(403);
});
test("Return 403 for expired token", async () => {
const response = await request
.put(`${endpoint}/${user._id}`)
.send({
role: "ADMIN",
})
.set("Authorization", `Bearer ${tokens.expiredAdmin}`);
expect(response.status).toBe(403);
});
test("Return 400 for missing payload", async () => {
const response = await request
.put(`${endpoint}/${user._id}`)
.set("Authorization", `Bearer ${tokens.admin}`);
expect(response.status).toBe(400);
});
test("Return 200 and updated user for successful request", async () => {
const response = await request
.put(`${endpoint}/${user._id}`)
.send({
role: "ADMIN",
})
.set("Authorization", `Bearer ${tokens.admin}`);
expect(response.status).toBe(200);
expect(response.body.data.role).toBe("ADMIN");
});
afterAll(async () => {
await users.delete(user._id);
});
});
describe(`Test DELETE ${endpoint}/:id`, () => {
const samples = [];
beforeAll(async () => {
samples[0] = await users.create({
username: faker.internet.userName(),
password: faker.internet.password(),
role: "CLIENT",
});
samples[1] = await users.create({
username: faker.internet.userName(),
password: faker.internet.password(),
role: "CLIENT",
});
});
test("Return 404 for invalid ID", async () => {
const id = mongoose.Types.ObjectId().toString();
const response = await request
.delete(`${endpoint}/${id}`)
.set("Authorization", `Bearer ${tokens.admin}`);
expect(response.status).toBe(404);
});
test("Return 403 for missing token", async () => {
const response = await request.delete(`${endpoint}/${samples[0]._id}`);
expect(response.status).toBe(403);
});
test("Return 403 for invalid token", async () => {
const response = await request
.delete(`${endpoint}/${samples[0]._id}`)
.set("Authorization", `Bearer ${tokens.invalid}`);
expect(response.status).toBe(403);
});
test("Return 403 for unauthorized token", async () => {
const response = await request
.delete(`${endpoint}/${samples[0]._id}`)
.set("Authorization", `Bearer ${tokens.client}`);
expect(response.status).toBe(403);
});
test("Return 403 for expired token", async () => {
const response = await request
.delete(`${endpoint}/${samples[0]._id}`)
.set("Authorization", `Bearer ${tokens.expiredAdmin}`);
expect(response.status).toBe(403);
});
test("Return 200 and deleted user for successful request", async () => {
const response = await request
.delete(`${endpoint}/${samples[1]._id}`)
.set("Authorization", `Bearer ${tokens.admin}`);
expect(response.status).toBe(200);
expect(response.body.data).toStrictEqual(samples[1]);
});
});
afterAll(async () => {
await mongoose.connection.db.dropDatabase();
await mongoose.connection.close();
});
});
Save the file and run the tests. Notice about the dozen of the tests fail!