Set up automated testing

This commit is contained in:
Savanni D'Gerinel 2025-02-13 22:58:04 -05:00
parent e9f89e1bdb
commit dca9c3c39e
7 changed files with 7020 additions and 3037 deletions

View File

@ -1,6 +1,10 @@
version: '3'
version: "3"
tasks:
fmt:
cmds:
- npm run fmt
dev:
cmds:
# - cd ../visions-types && task build

View File

@ -1,28 +1,29 @@
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'
import js from "@eslint/js";
import globals from "globals";
import reactHooks from "eslint-plugin-react-hooks";
import reactRefresh from "eslint-plugin-react-refresh";
import tseslint from "typescript-eslint";
import eslintConfigPrettier from "eslint-config-prettier";
export default tseslint.config(
{ ignores: ['dist'] },
{ ignores: ["dist"] },
{
extends: [js.configs.recommended, ...tseslint.configs.recommended],
files: ['**/*.{ts,tsx}'],
extends: [js.configs.recommended, ...tseslint.configs.recommended, eslintConfigPrettier],
files: ["**/*.{ts,tsx}"],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
plugins: {
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
"react-hooks": reactHooks,
"react-refresh": reactRefresh,
},
rules: {
...reactHooks.configs.recommended.rules,
'react-refresh/only-export-components': [
'warn',
"react-refresh/only-export-components": [
"warn",
{ allowConstantExport: true },
],
},
},
)
);

View File

@ -0,0 +1,7 @@
/** @type {import('ts-jest').JestConfigWithTsJest} **/
export default {
testEnvironment: "node",
transform: {
"^.+.tsx?$": ["ts-jest",{}],
},
};

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,9 @@
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview"
"fmt": "prettier -w src",
"preview": "vite preview",
"test": "jest"
},
"dependencies": {
"react": "^19.0.0",
@ -15,15 +17,25 @@
},
"devDependencies": {
"@eslint/js": "^9.19.0",
"@types/jest": "^29.5.14",
"@types/react": "^19.0.8",
"@types/react-dom": "^19.0.3",
"@vitejs/plugin-react": "^4.3.4",
"eslint": "^9.19.0",
"eslint-plugin-react-hooks": "^5.0.0",
"eslint-plugin-react-refresh": "^0.4.18",
"eslint-prettier-config": "^1.0.1",
"globals": "^15.14.0",
"jest": "^29.7.0",
"prettier": "^3.5.1",
"ts-jest": "^29.2.5",
"typescript": "~5.7.2",
"typescript-eslint": "^8.22.0",
"vite": "^6.1.0"
},
"prettier": {
"singleQuote": true,
"semi": false,
"tabWidth": 4
}
}

View File

@ -0,0 +1,53 @@
import { Client, ReqResponse, SessionId } from "./client";
class MockClient implements Client {
users: { [_: string]: string }
constructor() {
this.users = { 'vakarian': 'aoeu', 'shephard': 'aoeu' }
}
async auth(username: string, password: string): Promise<ReqResponse<SessionId>> {
if (this.users[username] == password) {
if (username == 'shephard') {
return { type: 'password-reset' }
}
return { type: "ok", content: "auth-successful" }
} else {
return { type: "error", content: 401 }
}
}
}
describe("what happens in an authentication", () => {
it("handles a successful response", async () => {
let client = new MockClient()
let response = await client.auth("vakarian", "aoeu")
expect(response).toEqual({ type: "ok", content: "auth-successful" })
})
it("handles an authentication failure", async () => {
let client = new MockClient();
{
let response = await client.auth("vakarian", "")
expect(response).toEqual({ type: "error", content: 401 });
}
{
let response = await client.auth("grunt", "")
expect(response).toEqual({ type: "error", content: 401 });
}
})
it("handles a password-reset condition", async () => {
let client = new MockClient();
{
let response = await client.auth("shephard", "aoeu")
expect(response).toEqual({ type: "password-reset" });
}
{
let response = await client.auth("shephard", "")
expect(response).toEqual({ type: "error", content: 401 });
}
})
})

11
visions/ui/src/client.ts Normal file
View File

@ -0,0 +1,11 @@
export type UserId = string;
export type SessionId = string;
export type ReqResponse<A> = { type: "ok", content: A } | { type: "password-reset" } | { type: "error", content: number }
export interface Client {
auth: (username: string, password: string) => Promise<ReqResponse<SessionId>>
// createUser: (sessionId: SessionId, username: string) => Promise<ReqResponse<UserId>>
// deleteUser: (sessionId: SessionId, userId: string) => Promise<ReqResponse<void>>
}