diff --git a/tests/live/iam.test.ts b/tests/live/iam.test.ts index 90e4573c..385e6535 100644 --- a/tests/live/iam.test.ts +++ b/tests/live/iam.test.ts @@ -8,10 +8,10 @@ import { import { allAppRoles, AppRoles } from "../../src/common/roles.js"; import { getBaseEndpoint } from "./utils.js"; import { environmentConfig, genericConfig } from "../../src/common/config.js"; - +const token = await createJwt(); const baseEndpoint = getBaseEndpoint(); + test("getting groups", { timeout: 10000 }, async () => { - const token = await createJwt(); const response = await fetch(`${baseEndpoint}/api/v1/iam/groups`, { method: "GET", headers: { @@ -35,7 +35,6 @@ test("getting groups", { timeout: 10000 }, async () => { }); test("getting members of a group", async () => { - const token = await createJwt(); const response = await fetch( `${baseEndpoint}/api/v1/iam/groups/ff25ec56-6a33-420d-bdb0-51d8a3920e46`, { @@ -59,7 +58,6 @@ test("getting members of a group", async () => { }); test("inviting users to tenant", { timeout: 60000 }, async () => { - const token = await createJwt(); const response = await fetch(`${baseEndpoint}/api/v1/iam/inviteUsers`, { method: "POST", headers: { @@ -79,7 +77,6 @@ test("inviting users to tenant", { timeout: 60000 }, async () => { }); test("getting group roles", async () => { - const token = await createJwt(); const response = await fetch(`${baseEndpoint}/api/v1/iam/groups/0/roles`, { method: "GET", headers: { diff --git a/tests/live/linkry.test.ts b/tests/live/linkry.test.ts index 90aff0db..66324706 100644 --- a/tests/live/linkry.test.ts +++ b/tests/live/linkry.test.ts @@ -1,8 +1,17 @@ import { describe, expect, test } from "vitest"; -import { getBaseEndpoint, makeRandomString } from "./utils.js"; +import { + createJwt, + getBaseEndpoint, + makeRandomString, + sleep, +} from "./utils.js"; +import { randomUUID } from "node:crypto"; const baseEndpoint = getBaseEndpoint("go"); +const coreBaseEndpoint = getBaseEndpoint("core"); const baseEndpointInfra = getBaseEndpoint("infra.go"); +const token = await createJwt(); +const linkId = `live-${randomUUID()}`; describe("Linkry live tests", async () => { test("Linkry health check", async () => { @@ -24,3 +33,80 @@ describe("Linkry live tests", async () => { expect(response.url).toBe("https://www.acm.illinois.edu/404"); }); }); + +describe("Linkry normal link lifecycle", { sequential: true }, async () => { + test("Create a short link", async () => { + const response = await fetch(`${coreBaseEndpoint}/api/v1/linkry/redir`, { + method: "POST", + headers: { + Authorization: `Bearer ${token}`, + "Content-Type": "application/json", + }, + body: JSON.stringify({ + slug: linkId, + access: [], + redirect: "https://www.google.com/", + }), + }); + expect(response.status).toBe(201); + // Make sure link propogates + await sleep(1000); + const redirResponse = await fetch(`${baseEndpoint}/${linkId}`); + expect(redirResponse.status).toBe(200); + expect(redirResponse.redirected).toBe(true); + expect(redirResponse.url).toBe("https://www.google.com/"); + }); + test("Delete a short link", async () => { + let response; + response = await fetch( + `${coreBaseEndpoint}/api/v1/linkry/redir/${linkId}`, + { + method: "DELETE", + headers: { + Authorization: `Bearer ${token}`, + }, + }, + ); + expect(response.status).toBe(204); + }); +}); + +describe("Linkry org link lifecycle", { sequential: true }, async () => { + test("Create a short link", async () => { + const response = await fetch( + `${coreBaseEndpoint}/api/v1/linkry/orgs/C01/redir`, + { + method: "POST", + headers: { + Authorization: `Bearer ${token}`, + "Content-Type": "application/json", + }, + body: JSON.stringify({ + slug: linkId, + access: [], + redirect: "https://www.google.com/", + }), + }, + ); + expect(response.status).toBe(201); + // Make sure link propogates + await sleep(1000); + const redirResponse = await fetch(`${baseEndpointInfra}/${linkId}`); + expect(redirResponse.status).toBe(200); + expect(redirResponse.redirected).toBe(true); + expect(redirResponse.url).toBe("https://www.google.com/"); + }); + test("Delete a short link", async () => { + let response; + response = await fetch( + `${coreBaseEndpoint}/api/v1/linkry/orgs/C01/redir/${linkId}`, + { + method: "DELETE", + headers: { + Authorization: `Bearer ${token}`, + }, + }, + ); + expect(response.status).toBe(204); + }); +}); diff --git a/tests/live/logging.test.ts b/tests/live/logging.test.ts new file mode 100644 index 00000000..9970248c --- /dev/null +++ b/tests/live/logging.test.ts @@ -0,0 +1,23 @@ +import { describe, expect, test } from "vitest"; +import { createJwt, getBaseEndpoint } from "./utils.js"; + +const baseEndpoint = getBaseEndpoint(); +const token = await createJwt(); + +describe("Audit log get tests", async () => { + test("Getting the audit log succeeds", async () => { + const oneHourAgo = new Date(Date.now() - 60 * 60 * 1000).getTime(); + const now = new Date().getTime(); + + const path = `${baseEndpoint}/api/v1/logs/iam/?start=${oneHourAgo}&end=${now}`; + const response = await fetch(path, { + method: "GET", + headers: { + Authorization: `Bearer ${token}`, + }, + }); + expect(response.status).toEqual(200); + const body = await response.json(); + expect(Array.isArray(body)).toBe(true); + }); +}); diff --git a/tests/live/membership.test.ts b/tests/live/membership.test.ts index fb22304e..d43f171f 100644 --- a/tests/live/membership.test.ts +++ b/tests/live/membership.test.ts @@ -1,6 +1,5 @@ import { expect, test, describe } from "vitest"; import { createJwt, getBaseEndpoint } from "./utils.js"; -import { randomUUID } from "node:crypto"; const baseEndpoint = getBaseEndpoint(); const token = await createJwt(); @@ -234,76 +233,91 @@ describe("Membership API basic checks", async () => { ); }); -test("External Membership List lifecycle test", async () => { +describe("External Membership List lifecycle", { sequential: true }, () => { const unixTimestampSeconds = Math.floor(Date.now() / 1000); const listId = `livetest-${unixTimestampSeconds}`; - let response = await fetch( - `${baseEndpoint}/api/v1/membership/externalList/${listId}`, - { - method: "PATCH", - headers: { - authorization: `Bearer ${token}`, - "content-type": "application/json", + + test("should create list and add initial member", async () => { + const response = await fetch( + `${baseEndpoint}/api/v1/membership/externalList/${listId}`, + { + method: "PATCH", + headers: { + authorization: `Bearer ${token}`, + "content-type": "application/json", + }, + body: JSON.stringify({ + add: ["acmtest2"], + remove: [], + }), }, - body: JSON.stringify({ - add: ["acmtest2"], - remove: [], - }), - }, - ); - expect(response.status).toBe(201); - response = await fetch( - `${baseEndpoint}/api/v1/membership/externalList/${listId}`, - { - method: "GET", - headers: { - authorization: `Bearer ${token}`, - "content-type": "application/json", + ); + expect(response.status).toBe(201); + }); + + test("should retrieve list with initial member", async () => { + const response = await fetch( + `${baseEndpoint}/api/v1/membership/externalList/${listId}`, + { + method: "GET", + headers: { + authorization: `Bearer ${token}`, + "content-type": "application/json", + }, }, - }, - ); - let responseJson = await response.json(); - expect(responseJson).toStrictEqual(["acmtest2"]); - response = await fetch( - `${baseEndpoint}/api/v1/membership/externalList/${listId}`, - { - method: "PATCH", - headers: { - authorization: `Bearer ${token}`, - "content-type": "application/json", + ); + const responseJson = await response.json(); + expect(responseJson).toStrictEqual(["acmtest2"]); + }); + + test("should add new member and remove existing member", async () => { + const response = await fetch( + `${baseEndpoint}/api/v1/membership/externalList/${listId}`, + { + method: "PATCH", + headers: { + authorization: `Bearer ${token}`, + "content-type": "application/json", + }, + body: JSON.stringify({ + add: ["acmtest3"], + remove: ["acmtest2"], + }), }, - body: JSON.stringify({ - add: ["acmtest3"], - remove: ["acmtest2"], - }), - }, - ); - expect(response.status).toEqual(201); - response = await fetch( - `${baseEndpoint}/api/v1/membership/externalList/${listId}`, - { - method: "GET", - headers: { - authorization: `Bearer ${token}`, - "content-type": "application/json", + ); + expect(response.status).toEqual(201); + }); + + test("should retrieve list with updated member", async () => { + const response = await fetch( + `${baseEndpoint}/api/v1/membership/externalList/${listId}`, + { + method: "GET", + headers: { + authorization: `Bearer ${token}`, + "content-type": "application/json", + }, }, - }, - ); - responseJson = await response.json(); - expect(responseJson).toStrictEqual(["acmtest3"]); - response = await fetch( - `${baseEndpoint}/api/v1/membership/externalList/${listId}`, - { - method: "PATCH", - headers: { - authorization: `Bearer ${token}`, - "content-type": "application/json", + ); + const responseJson = await response.json(); + expect(responseJson).toStrictEqual(["acmtest3"]); + }); + + test("should remove final member", async () => { + const response = await fetch( + `${baseEndpoint}/api/v1/membership/externalList/${listId}`, + { + method: "PATCH", + headers: { + authorization: `Bearer ${token}`, + "content-type": "application/json", + }, + body: JSON.stringify({ + remove: ["acmtest3"], + add: [], + }), }, - body: JSON.stringify({ - remove: ["acmtest3"], - add: [], - }), - }, - ); - expect(response.status).toEqual(201); + ); + expect(response.status).toEqual(201); + }); }); diff --git a/tests/live/utils.ts b/tests/live/utils.ts index 9a3688b6..d763e0d2 100644 --- a/tests/live/utils.ts +++ b/tests/live/utils.ts @@ -97,3 +97,7 @@ export function makeRandomString(length: number) { } return result; } + +export function sleep(ms: number): Promise { + return new Promise((resolve) => setTimeout(resolve, ms)); +}