diff --git a/package.json b/package.json index 17b7034..bdff9b0 100644 --- a/package.json +++ b/package.json @@ -4,18 +4,19 @@ "description": "Implementação do https://www.tabnews.com.br para o https://curso.dev", "main": "index.js", "scripts": { - "dev": "npm run services:up && npm run wait-for-postgres && npm run migration:up && next dev", + "dev": "npm run services:up && npm run services:wait:database && npm run migrations:up && next dev", + "test": "npm run services:up && concurrently -n next,jest --hide next -k -s command-jest \"next dev\" \"jest --runInBand --verbose\"", + "posttest": "npm run services:stop", + "test:watch": "jest --watchAll --runInBand --verbose", "services:up": "docker compose -f infra/compose.yaml up -d", "services:stop": "docker compose -f infra/compose.yaml stop", "services:down": "docker compose -f infra/compose.yaml down", + "services:wait:database": "node infra/scripts/wait-for-postgres.js", + "migrations:create": "node-pg-migrate -m infra/migrations create", + "migrations:up": "node-pg-migrate -m infra/migrations --envPath .env.development up", "lint:prettier:check": "prettier --check .", "lint:prettier:fix": "prettier --write .", "lint:eslint:check": "next lint --dir .", - "test": "npm run services:up && concurrently -n next,jest --hide next -k -s command-jest \"next dev\" \"jest --runInBand --verbose\"", - "test:watch": "jest --watchAll --runInBand", - "migration:create": "node-pg-migrate -m infra/migrations create", - "migration:up": "node-pg-migrate -m infra/migrations --envPath .env.development up", - "wait-for-postgres": "node infra/scripts/wait-for-postgres.js", "prepare": "husky", "commit": "cz" }, diff --git a/pages/api/v1/migrations/index.js b/pages/api/v1/migrations/index.js index 60bb65e..2b982ba 100644 --- a/pages/api/v1/migrations/index.js +++ b/pages/api/v1/migrations/index.js @@ -1,5 +1,5 @@ import migrationRunner from "node-pg-migrate"; -import { join } from "node:path"; +import { resolve } from "node:path"; import database from "infra/database.js"; export default async function migrations(request, response) { @@ -18,7 +18,7 @@ export default async function migrations(request, response) { const defaultMigrationOptions = { dbClient: dbClient, dryRun: true, - dir: join("infra", "migrations"), + dir: resolve("infra", "migrations"), direction: "up", verbose: true, migrationsTable: "pgmigrations", diff --git a/tests/integration/api/v1/migrations/get.test.js b/tests/integration/api/v1/migrations/get.test.js index 21fdc96..336c421 100644 --- a/tests/integration/api/v1/migrations/get.test.js +++ b/tests/integration/api/v1/migrations/get.test.js @@ -1,17 +1,20 @@ -import database from "infra/database.js"; import orchestrator from "tests/orchestrator.js"; beforeAll(async () => { await orchestrator.waitForAllServices(); - await database.query("drop schema public cascade; create schema public;"); + await orchestrator.clearDatabase(); }); -test("GET to /api/v1/migrations should return 200", async () => { - const response = await fetch("http://localhost:3000/api/v1/migrations"); - expect(response.status).toBe(200); +describe("GET /api/v1/migrations", () => { + describe("Anonymous user", () => { + test("Retrieving pending migrations", async () => { + const response = await fetch("http://localhost:3000/api/v1/migrations"); + expect(response.status).toBe(200); - const responseBody = await response.json(); + const responseBody = await response.json(); - expect(Array.isArray(responseBody)).toBe(true); - expect(responseBody.length).toBeGreaterThan(0); + expect(Array.isArray(responseBody)).toBe(true); + expect(responseBody.length).toBeGreaterThan(0); + }); + }); }); diff --git a/tests/integration/api/v1/migrations/post.test.js b/tests/integration/api/v1/migrations/post.test.js index e9638ac..fa2bb3d 100644 --- a/tests/integration/api/v1/migrations/post.test.js +++ b/tests/integration/api/v1/migrations/post.test.js @@ -1,29 +1,41 @@ -import database from "infra/database.js"; import orchestrator from "tests/orchestrator.js"; beforeAll(async () => { await orchestrator.waitForAllServices(); - await database.query("drop schema public cascade; create schema public;"); + await orchestrator.clearDatabase(); }); -test("POST to /api/v1/migrations should return 200", async () => { - const response1 = await fetch("http://localhost:3000/api/v1/migrations", { - method: "POST", - }); - expect(response1.status).toBe(201); - - const response1Body = await response1.json(); +describe("POST /api/v1/migrations", () => { + describe("Anonymous user", () => { + describe("Running pending migrations", () => { + test("For the first time", async () => { + const response1 = await fetch( + "http://localhost:3000/api/v1/migrations", + { + method: "POST", + } + ); + expect(response1.status).toBe(201); - expect(Array.isArray(response1Body)).toBe(true); - expect(response1Body.length).toBeGreaterThan(0); + const response1Body = await response1.json(); - const response2 = await fetch("http://localhost:3000/api/v1/migrations", { - method: "POST", - }); - expect(response2.status).toBe(200); + expect(Array.isArray(response1Body)).toBe(true); + expect(response1Body.length).toBeGreaterThan(0); + }); + test("For the second time", async () => { + const response2 = await fetch( + "http://localhost:3000/api/v1/migrations", + { + method: "POST", + } + ); + expect(response2.status).toBe(200); - const response2Body = await response2.json(); + const response2Body = await response2.json(); - expect(Array.isArray(response2Body)).toBe(true); - expect(response2Body.length).toBe(0); + expect(Array.isArray(response2Body)).toBe(true); + expect(response2Body.length).toBe(0); + }); + }); + }); }); diff --git a/tests/integration/api/v1/status/get.test.js b/tests/integration/api/v1/status/get.test.js index 8f2c1a6..9dc4fab 100644 --- a/tests/integration/api/v1/status/get.test.js +++ b/tests/integration/api/v1/status/get.test.js @@ -4,16 +4,20 @@ beforeAll(async () => { await orchestrator.waitForAllServices(); }); -test("GET to /api/v1/status should return 200", async () => { - const response = await fetch("http://localhost:3000/api/v1/status"); - expect(response.status).toBe(200); +describe("GET /api/v1/status", () => { + describe("Anonymous user", () => { + test("Retrieving current system status", async () => { + const response = await fetch("http://localhost:3000/api/v1/status"); + expect(response.status).toBe(200); - const responseBody = await response.json(); + const responseBody = await response.json(); - const parsedUpdatedAt = new Date(responseBody.updated_at).toISOString(); - expect(responseBody.updated_at).toEqual(parsedUpdatedAt); + const parsedUpdatedAt = new Date(responseBody.updated_at).toISOString(); + expect(responseBody.updated_at).toEqual(parsedUpdatedAt); - expect(responseBody.dependencies.database.version).toEqual("16.0"); - expect(responseBody.dependencies.database.max_connections).toEqual(100); - expect(responseBody.dependencies.database.opened_connections).toEqual(1); + expect(responseBody.dependencies.database.version).toEqual("16.0"); + expect(responseBody.dependencies.database.max_connections).toEqual(100); + expect(responseBody.dependencies.database.opened_connections).toEqual(1); + }); + }); }); diff --git a/tests/orchestrator.js b/tests/orchestrator.js index d408184..c48b9e7 100644 --- a/tests/orchestrator.js +++ b/tests/orchestrator.js @@ -1,4 +1,5 @@ import retry from "async-retry"; +import database from "infra/database.js"; async function waitForAllServices() { await waitForWebServer(); @@ -19,8 +20,13 @@ async function waitForAllServices() { } } +async function clearDatabase() { + await database.query("drop schema public cascade; create schema public;"); +} + const orchestrator = { waitForAllServices, + clearDatabase, }; export default orchestrator;