From 4817d40c94d8b83d930b89d2df3059dc6fff97b2 Mon Sep 17 00:00:00 2001 From: Dan Gowans Date: Fri, 28 Oct 2022 09:58:55 -0400 Subject: [PATCH] user function testing --- helpers/functions.user.d.ts | 18 ++++- helpers/functions.user.js | 3 +- helpers/functions.user.ts | 22 ++++-- test/functions.d.ts | 1 + test/functions.js | 122 +++++++++++++++++++++++++++++ test/functions.ts | 149 ++++++++++++++++++++++++++++++++++++ test/version.js | 2 +- test/version.ts | 2 +- 8 files changed, 307 insertions(+), 12 deletions(-) create mode 100644 test/functions.d.ts create mode 100644 test/functions.js create mode 100644 test/functions.ts diff --git a/helpers/functions.user.d.ts b/helpers/functions.user.d.ts index 74c0606a..0a39fb1b 100644 --- a/helpers/functions.user.d.ts +++ b/helpers/functions.user.d.ts @@ -1,4 +1,14 @@ -import type { Request } from "express"; -export declare const userIsAdmin: (request: Request) => boolean; -export declare const userCanUpdate: (request: Request) => boolean; -export declare const apiKeyIsValid: (request: Request) => Promise; +import type { User } from "../types/recordTypes"; +export interface UserRequest { + session?: { + user?: User; + }; +} +export interface APIRequest { + params?: { + apiKey?: string; + }; +} +export declare const userIsAdmin: (request: UserRequest) => boolean; +export declare const userCanUpdate: (request: UserRequest) => boolean; +export declare const apiKeyIsValid: (request: APIRequest) => Promise; diff --git a/helpers/functions.user.js b/helpers/functions.user.js index c70cb5f6..2e880d27 100644 --- a/helpers/functions.user.js +++ b/helpers/functions.user.js @@ -17,7 +17,8 @@ export const userCanUpdate = (request) => { return user.userProperties.canUpdate; }; export const apiKeyIsValid = async (request) => { - const apiKey = request.params.apiKey; + var _a; + const apiKey = (_a = request.params) === null || _a === void 0 ? void 0 : _a.apiKey; if (!apiKey) { return false; } diff --git a/helpers/functions.user.ts b/helpers/functions.user.ts index a26c25c7..447adb18 100644 --- a/helpers/functions.user.ts +++ b/helpers/functions.user.ts @@ -1,9 +1,21 @@ import { getUserNameFromApiKey } from "./functions.api.js"; import * as configFunctions from "./functions.config.js"; -import type { Request } from "express"; +import type { User } from "../types/recordTypes"; -export const userIsAdmin = (request: Request): boolean => { +export interface UserRequest { + session?: { + user?: User; + } +} + +export interface APIRequest { + params?: { + apiKey?: string; + } +} + +export const userIsAdmin = (request: UserRequest): boolean => { const user = request.session?.user; if (!user) { @@ -13,7 +25,7 @@ export const userIsAdmin = (request: Request): boolean => { return user.userProperties.isAdmin; }; -export const userCanUpdate = (request: Request): boolean => { +export const userCanUpdate = (request: UserRequest): boolean => { const user = request.session?.user; if (!user) { @@ -23,8 +35,8 @@ export const userCanUpdate = (request: Request): boolean => { return user.userProperties.canUpdate; }; -export const apiKeyIsValid = async (request: Request): Promise => { - const apiKey = request.params.apiKey; +export const apiKeyIsValid = async (request: APIRequest): Promise => { + const apiKey = request.params?.apiKey; if (!apiKey) { return false; diff --git a/test/functions.d.ts b/test/functions.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/test/functions.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/test/functions.js b/test/functions.js new file mode 100644 index 00000000..5a876f33 --- /dev/null +++ b/test/functions.js @@ -0,0 +1,122 @@ +import * as assert from "assert"; +import fs from "node:fs"; +import * as userFunctions from "../helpers/functions.user.js"; +describe("functions.user", () => { + describe("unauthenticated, no user in session", () => { + const noUserRequest = { + session: {} + }; + it("can not update", () => { + assert.strictEqual(userFunctions.userCanUpdate(noUserRequest), false); + }); + it("is not admin", () => { + assert.strictEqual(userFunctions.userIsAdmin(noUserRequest), false); + }); + }); + describe("read only user, no update, no admin", () => { + const readOnlyRequest = { + session: { + user: { + userName: "*test", + userProperties: { + canUpdate: false, + isAdmin: false, + apiKey: "" + } + } + } + }; + it("can not update", () => { + assert.strictEqual(userFunctions.userCanUpdate(readOnlyRequest), false); + }); + it("is not admin", () => { + assert.strictEqual(userFunctions.userIsAdmin(readOnlyRequest), false); + }); + }); + describe("update only user, no admin", () => { + const updateOnlyRequest = { + session: { + user: { + userName: "*test", + userProperties: { + canUpdate: true, + isAdmin: false, + apiKey: "" + } + } + } + }; + it("can update", () => { + assert.strictEqual(userFunctions.userCanUpdate(updateOnlyRequest), true); + }); + it("is not admin", () => { + assert.strictEqual(userFunctions.userIsAdmin(updateOnlyRequest), false); + }); + }); + describe("admin only user, no update", () => { + const adminOnlyRequest = { + session: { + user: { + userName: "*test", + userProperties: { + canUpdate: false, + isAdmin: true, + apiKey: "" + } + } + } + }; + it("can not update", () => { + assert.strictEqual(userFunctions.userCanUpdate(adminOnlyRequest), false); + }); + it("is admin", () => { + assert.strictEqual(userFunctions.userIsAdmin(adminOnlyRequest), true); + }); + }); + describe("update admin user", () => { + const updateAdminRequest = { + session: { + user: { + userName: "*test", + userProperties: { + canUpdate: true, + isAdmin: true, + apiKey: "" + } + } + } + }; + it("can update", () => { + assert.strictEqual(userFunctions.userCanUpdate(updateAdminRequest), true); + }); + it("is admin", () => { + assert.strictEqual(userFunctions.userIsAdmin(updateAdminRequest), true); + }); + }); + describe("API key check", () => { + it("authenticates with a valid API key", async () => { + const apiKeysJSON = JSON.parse(fs.readFileSync("data/apiKeys.json", "utf8")); + const apiKey = Object.values(apiKeysJSON)[0]; + const apiRequest = { + params: { + apiKey + } + }; + assert.strictEqual(await userFunctions.apiKeyIsValid(apiRequest), true); + }); + it("fails to authenticate with an invalid API key", async () => { + const apiRequest = { + params: { + apiKey: "badKey" + } + }; + assert.strictEqual(await userFunctions.apiKeyIsValid(apiRequest), false); + }); + it("fails to authenticate with no API key", async () => { + const apiRequest = { + params: {} + }; + assert.strictEqual(await userFunctions.apiKeyIsValid(apiRequest), false); + }); + }); +}); diff --git a/test/functions.ts b/test/functions.ts new file mode 100644 index 00000000..2e377f41 --- /dev/null +++ b/test/functions.ts @@ -0,0 +1,149 @@ +import * as assert from "assert"; + +import fs from "node:fs"; + +import * as userFunctions from "../helpers/functions.user.js"; + +describe("functions.user", () => { + describe("unauthenticated, no user in session", () => { + const noUserRequest = { + session: {} + }; + + it("can not update", () => { + assert.strictEqual(userFunctions.userCanUpdate(noUserRequest), false); + }); + + it("is not admin", () => { + assert.strictEqual(userFunctions.userIsAdmin(noUserRequest), false); + }); + }); + + describe("read only user, no update, no admin", () => { + const readOnlyRequest: userFunctions.UserRequest = { + session: { + user: { + userName: "*test", + userProperties: { + canUpdate: false, + isAdmin: false, + apiKey: "" + } + } + } + }; + + it("can not update", () => { + assert.strictEqual(userFunctions.userCanUpdate(readOnlyRequest), false); + }); + + it("is not admin", () => { + assert.strictEqual(userFunctions.userIsAdmin(readOnlyRequest), false); + }); + }); + + describe("update only user, no admin", () => { + const updateOnlyRequest: userFunctions.UserRequest = { + session: { + user: { + userName: "*test", + userProperties: { + canUpdate: true, + isAdmin: false, + apiKey: "" + } + } + } + }; + + it("can update", () => { + assert.strictEqual(userFunctions.userCanUpdate(updateOnlyRequest), true); + }); + + it("is not admin", () => { + assert.strictEqual(userFunctions.userIsAdmin(updateOnlyRequest), false); + }); + }); + + describe("admin only user, no update", () => { + const adminOnlyRequest: userFunctions.UserRequest = { + session: { + user: { + userName: "*test", + userProperties: { + canUpdate: false, + isAdmin: true, + apiKey: "" + } + } + } + }; + + it("can not update", () => { + assert.strictEqual(userFunctions.userCanUpdate(adminOnlyRequest), false); + }); + + it("is admin", () => { + assert.strictEqual(userFunctions.userIsAdmin(adminOnlyRequest), true); + }); + }); + + describe("update admin user", () => { + const updateAdminRequest: userFunctions.UserRequest = { + session: { + user: { + userName: "*test", + userProperties: { + canUpdate: true, + isAdmin: true, + apiKey: "" + } + } + } + }; + + it("can update", () => { + assert.strictEqual(userFunctions.userCanUpdate(updateAdminRequest), true); + }); + + it("is admin", () => { + assert.strictEqual(userFunctions.userIsAdmin(updateAdminRequest), true); + }); + }); + + describe("API key check", () => { + it("authenticates with a valid API key", async () => { + const apiKeysJSON: { [userName: string]: string } = JSON.parse( + fs.readFileSync("data/apiKeys.json", "utf8") + ); + + const apiKey = Object.values(apiKeysJSON)[0]; + + const apiRequest: userFunctions.APIRequest = { + params: { + apiKey + } + }; + + assert.strictEqual(await userFunctions.apiKeyIsValid(apiRequest), true); + }); + + it("fails to authenticate with an invalid API key", async () => { + const apiRequest: userFunctions.APIRequest = { + params: { + apiKey: "badKey" + } + }; + + assert.strictEqual(await userFunctions.apiKeyIsValid(apiRequest), false); + }); + + it("fails to authenticate with no API key", async () => { + const apiRequest: userFunctions.APIRequest = { + params: {} + }; + + assert.strictEqual(await userFunctions.apiKeyIsValid(apiRequest), false); + }); + }); +}); diff --git a/test/version.js b/test/version.js index c75cae68..5738cd04 100644 --- a/test/version.js +++ b/test/version.js @@ -1,5 +1,5 @@ import * as assert from "assert"; -import fs from "fs"; +import fs from "node:fs"; import { version } from "../version.js"; describe("version", () => { it("has a version that matches the package.json", () => { diff --git a/test/version.ts b/test/version.ts index 9466e508..bab8e3ba 100644 --- a/test/version.ts +++ b/test/version.ts @@ -1,6 +1,6 @@ import * as assert from "assert"; -import fs from "fs"; +import fs from "node:fs"; import { version } from "../version.js";