mirror of
https://github.com/OHTU-German-learning-website/OHTU-German-learning-website.git
synced 2026-10-12 19:13:51 +03:00
clarifying comments on test logic (#348)
This commit is contained in:
@@ -3,7 +3,6 @@ import { SignJWT, jwtVerify } from "jose";
|
||||
import { cookies } from "next/headers";
|
||||
import { getConfig, isTest } from "../../backend/config";
|
||||
import { AUTH_COOKIE_NAME } from "@/shared/const";
|
||||
import { TestFactory } from "../test/testfactory";
|
||||
|
||||
const { sessionSecret, sessionTTL } = getConfig();
|
||||
const encodedKey = new TextEncoder().encode(sessionSecret);
|
||||
|
||||
@@ -5,12 +5,15 @@ import { exec as execCB } from "child_process";
|
||||
import util from "util";
|
||||
import { dbURL } from "../db";
|
||||
import { logger } from "../logging";
|
||||
import { getConfig } from "../config";
|
||||
|
||||
// Basically a JS implementation of the pgmigrate CLI
|
||||
|
||||
// Tuns execCB into a promise
|
||||
const exec = util.promisify(execCB);
|
||||
|
||||
export async function runMigrations() {
|
||||
const config = await Config.get();
|
||||
const conf = config.db;
|
||||
const conf = getConfig().db;
|
||||
|
||||
const migrator = new Migrator();
|
||||
await migrator.migrate(conf, true);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { NextRequest } from "next/server";
|
||||
import { getConfig } from "@/backend/config";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
|
||||
const requestWithUser = (user, sessionId, ...params) => {
|
||||
const headers = new Headers();
|
||||
headers.append("X-Session-Id", sessionId);
|
||||
@@ -9,6 +10,9 @@ const requestWithUser = (user, sessionId, ...params) => {
|
||||
return req;
|
||||
};
|
||||
|
||||
// Helper function for tests that returns get, post, put and mockParams functions
|
||||
// These functions return a NextRequest object with the user and sessionId set
|
||||
// It allows you to easily test nextJS handlers with a proper request object
|
||||
export function useTestRequest(user) {
|
||||
const config = getConfig();
|
||||
const sessionId = uuidv4();
|
||||
|
||||
@@ -3,12 +3,15 @@ import { Migrator } from "./migrator";
|
||||
import { beforeEach, afterEach, afterAll } from "vitest";
|
||||
import { DB } from "../db";
|
||||
import { Pool } from "pg";
|
||||
import { vi } from "vitest";
|
||||
import { createHash, randomBytes } from "crypto";
|
||||
import { logger } from "../logging";
|
||||
const TestUser = "pgtdbuser";
|
||||
const TestPassword = "pgtdbpass";
|
||||
|
||||
// useTestDatabase is called at the start of each test suite to set up the test database.
|
||||
// It includes beforeEach and afterEach hooks to set up and tear down the test database.
|
||||
// This ensures that each test is isolated from the others.
|
||||
|
||||
export function useTestDatabase({
|
||||
conf = getConfig().db,
|
||||
migrator = new Migrator(),
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
import { isTest } from "../config";
|
||||
import { fa, faker } from "@faker-js/faker";
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { createHash } from "node:crypto";
|
||||
import { DB } from "../db";
|
||||
|
||||
// The testfactory makes it easier to create test data for tests.
|
||||
// Each database table should have a modelFactory function, with some default values.
|
||||
// It should also hanlde FKs by creating child models (with default values) if needed.
|
||||
// This is useful because it makes it easier to create test data and it ensures that the test data is created in a consistent way.
|
||||
// If the schema of a a table changes, you don't have 50 sql statements to update in your test suite.
|
||||
|
||||
/**
|
||||
* @description Factory function to create a model for a given table.
|
||||
* @param {string} tableName - The name of the table for which the model is being created.
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
# Hooks Documentation
|
||||
|
||||
These are some simple request hooks that help with making network requests to API routes.
|
||||
|
||||
They are very simple, no caching etc. I highly recommend you refactor gradesa to use a proper fetching library like react-query. The first team was pretty inexperienced with JS so we used this to limit the amount of new stuff we had to learn.
|
||||
|
||||
## useQuery
|
||||
|
||||
`useQuery` is a data fetching hook for making GET requests to the API with built-in error handling, loading states, and retries.
|
||||
|
||||
### Features
|
||||
|
||||
- Automatic GET requests with query string parameter handling
|
||||
- Loading state management
|
||||
- Basic error handling
|
||||
- Automatic retries with exponential backoff
|
||||
- Request cancellation on component unmount
|
||||
- very simplistic Session ID tracking
|
||||
|
||||
### Usage
|
||||
|
||||
```jsx
|
||||
import useQuery from "@/shared/hooks/useQuery";
|
||||
|
||||
function MyComponent() {
|
||||
const { data, error, isLoading, refetch } = useQuery(
|
||||
"/endpoint",
|
||||
{
|
||||
param1: "value1",
|
||||
param2: "value2",
|
||||
},
|
||||
{
|
||||
enabled: true,
|
||||
refetchBackoffMax: 10000,
|
||||
refetchBackoff: 1000,
|
||||
refetchBackoffExponent: 1.5,
|
||||
refetchBackoffMaxAttempts: 3,
|
||||
}
|
||||
);
|
||||
|
||||
if (isLoading) return <div>Loading...</div>;
|
||||
if (error) return <div>Error: {error.message}</div>;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<button onClick={refetch}>Refresh Data</button>
|
||||
{/* Render data */}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
- `url` (string): The API endpoint to fetch data from
|
||||
- `params` (object, optional): Query parameters to send with the request
|
||||
- `config` (object, optional): Configuration options:
|
||||
- `enabled` (boolean): Whether the query should automatically run (default: `true`)
|
||||
- `refetchBackoff` (number): Initial backoff time in ms (default: `1000`)
|
||||
- `refetchBackoffMax` (number): Maximum backoff time in ms (default: `10000`)
|
||||
- `refetchBackoffExponent` (number): Backoff exponential factor (default: `1.5`)
|
||||
- `refetchBackoffMaxAttempts` (number): Maximum retry attempts (default: `3`)
|
||||
|
||||
### Return Values
|
||||
|
||||
- `data`: The response data (null until loaded)
|
||||
- `error`: Any error that occurred during fetching (null if no error)
|
||||
- `isLoading`: Boolean indicating if the request is in progress
|
||||
- `refetch`: Function to manually trigger the request again
|
||||
|
||||
## useRequest
|
||||
|
||||
`useRequest` is a flexible hook for making non-GET HTTP requests (POST, PUT, DELETE, etc.) to the API.
|
||||
|
||||
### Features
|
||||
|
||||
- Support for all HTTP methods
|
||||
- Customizable request configuration
|
||||
- Error handling
|
||||
- Session ID tracking
|
||||
|
||||
### Usage
|
||||
|
||||
```jsx
|
||||
import { useRequest } from "@/shared/hooks/useRequest";
|
||||
|
||||
function MyComponent() {
|
||||
const makeRequest = useRequest();
|
||||
|
||||
const handleSubmit = async (formData) => {
|
||||
try {
|
||||
const response = await makeRequest("/endpoint", formData, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Custom-Header": "value",
|
||||
},
|
||||
});
|
||||
|
||||
// Handle successful response
|
||||
console.log(response.data);
|
||||
} catch (error) {
|
||||
// Handle error
|
||||
console.error(error.message);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={handleSubmit}>
|
||||
{/* Form inputs */}
|
||||
<button type="submit">Submit</button>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
- The hook returns a `makeRequest` function that accepts:
|
||||
- `url` (string): The API endpoint
|
||||
- `body` (object, optional): The request body/payload
|
||||
- `config` (object, optional): Axios request configuration
|
||||
- `method` (string): HTTP method (default: 'POST')
|
||||
- `headers` (object): Custom request headers
|
||||
- Any other valid Axios request options
|
||||
|
||||
### Return Values
|
||||
|
||||
- The function returns a Promise that resolves to the Axios response object
|
||||
Reference in New Issue
Block a user