Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
PORT = 9000
13 changes: 13 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"env": {
"node": true,
"commonjs": true,
"es2021": true,
"jest": true
},
"extends": "eslint:recommended",
"parserOptions": {
"ecmaVersion": "latest"
},
"rules": {}
}
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
node_modules/

.env

dist/

build/

*.log

.DS_Store

32 changes: 16 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
# Server Testing Module Project
<!-- # Server Testing Module Project

## Instructions

### Minimum Viable Product

For this project you will create a RESTful API using Node and Express, containing endpoints to perform some CRUD operations on a resource of your choosing. Two or three endpoints are enough. Data should be persisted in a SQLite database.
- For this project you will create a RESTful API using Node and Express, containing endpoints to perform some CRUD operations on a resource of your choosing. Two or three endpoints are enough. Data should be persisted in a SQLite database.

## Requirements

- Write a minimum of ten tests using supertest.
[ ] Write a minimum of ten tests using supertest.

## Checklist

Here is a checklist of tasks to help you put your project together:

- Generate a `.gitignore` file.
- Install express, knex@0.95.15, sqlite3 as plain dependencies.
- Alternatively install express, knex, @vscode/sqlite3 as plain dependencies.
- Install jest, eslint, nodemon, supertest, cross-env as dev-dependencies.
- Configure jest and eslint using `npx <libname> --init`.
- Create a `knexfile.js` with "development" and "testing" configurations.
- Create a `db-config.js` file that selects the correct configuration using the value of `process.env.NODE_ENV`.
- Create migration and seed files.
- Put together "start", "server", "rollback", "migrate" and "seed" scripts in your `package.json`.
- Create a "test" script in your `package.json` using cross-env to inject a `NODE_ENV` of "testing".
- Create a basic express application with a few database access functions and a few endpoints.
- Test your endpoints manually using Postman, HTTPie or similar.
- Test your endpoints with supertest.
[x] Generate a `.gitignore` file.
[x] Install express, knex@0.95.15, sqlite3 as plain dependencies.
[x] Alternatively install express, knex, @vscode/sqlite3 as plain dependencies.
[x] Install jest, eslint, nodemon, supertest, cross-env as dev-dependencies.
[x] Configure jest and eslint using `npx <libname> --init`.
[x] Create a `knexfile.js` with "development" and "testing" configurations.
[x] Create a `db-config.js` file that selects the correct configuration using the value of `process.env.NODE_ENV`.
[x] Create migration and seed files.
[x] Put together "start", "server", "rollback", "migrate" and "seed" scripts in your `package.json`.
[x] Create a "test" script in your `package.json` using cross-env to inject a `NODE_ENV` of "testing".
[x] Create a basic express application with a few database access functions and a few endpoints.
[x] Test your endpoints manually using Postman, HTTPie or similar.
[ ] Test your endpoints with supertest. -->
46 changes: 46 additions & 0 deletions api/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
const express = require("express");

const Teams = require("./teams/teams-model.js");

const server = express();

server.use(express.json());

server.get("/", (req, res) => {
res.status(200).json({ api: "up" });
});

server.get("/teams", (req, res) => {
Teams.getAll()
.then((teams) => {
res.status(200).json(teams);
})
.catch((error) => {
res.status(500).json(error);
});
});

server.get("/teams/:id", (req, res) => {
Teams.getById(req.params.id)
.then((team) => {
if (team) {
res.status(200).json(team);
} else {
res.status(404).json({ message: "Team not found" });
}
})
.catch((error) => {
res.status(500).json(error);
});
});

server.post("/teams", async (req, res) => {
try {
const team = await Teams.insert(req.body);
res.status(201).json(team);
} catch (error) {
res.status(500).json(error);
}
});

module.exports = server;
71 changes: 71 additions & 0 deletions api/server.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
const db = require("../data/db-config.js");
const request = require("supertest");
const server = require("./server");

beforeAll(async () => {
await db.migrate.rollback();
await db.migrate.latest();
});

beforeEach(async () => {
await db.seed.run();
});

describe("[GET] /teams", () => {
test("[1] responds with 200 OK", async () => {
const res = await request(server).get("/teams");
expect(res.status).toBe(200);
});
test("[2] returns all the teams in the db", async () => {
const res = await request(server).get("/teams");
expect(res.body).toHaveLength(16);
});
test("[3] if there are no teams it returns an empty array", async () => {
await db("sec_teams").truncate();
const res = await request(server).get("/teams");
expect(res.body).toHaveLength(0);
});
});

describe("[GET] /teams/:id", () => {
test("[4] responds with 200 OK", async () => {
const id = 1;
const res = await request(server).get(`/teams/${id}`);
expect(res.status).toBe(200);
});
test("[5] returns a team by id from the db", async () => {
const id = 1;
const res = await request(server).get(`/teams/${id}`);
expect(res.body).toMatchObject({
id: 1,
school_name: "Alabama",
mascot: "Crimson Tide",
});
});
test("[6] if the team does not exist it returns a 404", async () => {
const id = 999;
const res = await request(server).get(`/teams/${id}`);
expect(res.status).toBe(404);
});
});

describe("[POST] /teams", () => {
const team = { school_name: "Wisconsin", mascot: "Badgers" };
test("[7] responds with 201 CREATED", async () => {
const res = await request(server).post("/teams").send(team);
expect(res.status).toBe(201);
});
test("[8] returns the newly created team", async () => {
const res = await request(server).post("/teams").send(team);
expect(res.body).toMatchObject(team);
});
test("[9] adds a team to the database", async () => {
await request(server).post("/teams").send(team);
const teams = await db("sec_teams");
expect(teams).toHaveLength(17);
});
test("[10] ensures that the body is required", async () => {
const res = await request(server).post("/teams").send({});
expect(res.status).toBe(500);
});
});
23 changes: 23 additions & 0 deletions api/teams/teams-model.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const db = require("../../data/db-config.js");

module.exports = {
insert,
getAll,
getById,
};

function getAll() {
return db("sec_teams");
}

function getById(id) {
return db("sec_teams").where("id", id).first();
}

async function insert(team) {
return await db("sec_teams")
.insert(team)
.then(([id]) => {
return db("sec_teams").where("id", id).first();
});
}
Empty file added api/teams/teams-model.test.js
Empty file.
7 changes: 7 additions & 0 deletions data/db-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const knex = require("knex");

const config = require("../knexfile.js");

const environment = process.env.NODE_ENV || "development";

module.exports = knex(config[environment]);
19 changes: 19 additions & 0 deletions data/migrations/20231219223242_first-migration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.up = function (knex) {
return knex.schema.createTable("sec_teams", (tbl) => {
tbl.increments();
tbl.string("school_name", 128).notNullable();
tbl.string("mascot", 128).notNullable();
});
};

/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.down = function (knex) {
return knex.schema.dropTableIfExists("sec_teams");
};
Binary file added data/secteams.db3
Binary file not shown.
30 changes: 30 additions & 0 deletions data/seeds/data.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* @param { import("knex").Knex } knex
* @returns { Promise<void> }
*/
exports.seed = async function (knex) {
// Deletes ALL existing entries
await knex("sec_teams").del();
await knex("sec_teams").insert([
{ id: 1, school_name: "Alabama", mascot: "Crimson Tide" },
{ id: 2, school_name: "Arkansas", mascot: "Razorbacks" },
{ id: 3, school_name: "Auburn", mascot: "Tigers" },
{ id: 4, school_name: "Florida", mascot: "Gators" },
{ id: 5, school_name: "Georgia", mascot: "Bulldogs" },
{ id: 6, school_name: "Kentucky", mascot: "Wildcats" },
{ id: 7, school_name: "LSU", mascot: "Tigers" },
{ id: 8, school_name: "Ole Miss", mascot: "Rebels" },
{ id: 9, school_name: "Mississippi State", mascot: "Bulldogs" },
{
id: 10,
school_name: "South Carolina",
mascot: "Gamecocks",
},
{ id: 11, school_name: "Tennessee", mascot: "Volunteers" },
{ id: 12, school_name: "Texas A&M", mascot: "Aggies" },
{ id: 13, school_name: "Vanderbilt", mascot: "Commodores" },
{ id: 14, school_name: "Missouri", mascot: "Tigers" },
{ id: 15, school_name: "Oklahoma", mascot: "Sooners" },
{ id: 16, school_name: "Texas", mascot: "Longhorns" },
]);
};
Binary file added data/test.db3
Binary file not shown.
6 changes: 6 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
require("dotenv").config();

const server = require("./api/server.js");

const port = process.env.PORT || 9000;
server.listen(port, () => console.log(`\n** Running on port ${port} **\n`));
Loading