aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorElizabeth Hunt <me@liz.coffee>2025-12-15 00:58:43 -0800
committerElizabeth Hunt <me@liz.coffee>2025-12-15 00:58:43 -0800
commit2e41f030f02a336c2e9866d3d56b0494da5a622e (patch)
tree226d7fe0f2e0d5af847c31d97c1ab9664d1b7e33 /test
parent9c9f35734e795e3c2cea21384349b655d7ffa164 (diff)
downloadposthook-2e41f030f02a336c2e9866d3d56b0494da5a622e.tar.gz
posthook-2e41f030f02a336c2e9866d3d56b0494da5a622e.zip
Remove admin route in favor of a simpler toml format
Diffstat (limited to 'test')
-rw-r--r--test/storage.test.ts67
1 files changed, 40 insertions, 27 deletions
diff --git a/test/storage.test.ts b/test/storage.test.ts
index 200c81a..985ba48 100644
--- a/test/storage.test.ts
+++ b/test/storage.test.ts
@@ -1,6 +1,6 @@
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
-import { mkdtemp, readFile, rm } from 'fs/promises';
+import { mkdtemp, readFile, rm, writeFile } from 'fs/promises';
import { tmpdir } from 'os';
import { join } from 'path';
@@ -9,56 +9,69 @@ import { ContentType, type RouteConfig } from '../src/types/index.js';
describe('Storage', () => {
let dataDir: string;
+ let configPath: string;
beforeEach(async () => {
dataDir = await mkdtemp(join(tmpdir(), 'posthook-test-'));
+ configPath = join(dataDir, 'routes.toml');
});
afterEach(async () => {
await rm(dataDir, { recursive: true, force: true });
});
- it('persists routes to routes.json and loads them on init', async () => {
+ it('loads routes from routes.toml on init', async () => {
const route: RouteConfig = {
name: 'route1',
contentType: ContentType.JSON,
hcaptchaProtected: false,
};
- const storage1 = new Storage(dataDir);
- expect((await storage1.init()).left().present()).toBe(false);
- expect((await storage1.registerRoute(route)).left().present()).toBe(false);
+ // Create a TOML config file
+ const toml = `
+[[route]]
+name = "route1"
+contentType = "json"
+hcaptchaProtected = false
+`;
+ await writeFile(configPath, toml);
- const storage2 = new Storage(dataDir);
- expect((await storage2.init()).left().present()).toBe(false);
- expect(storage2.getRoute('route1')).toEqual(route);
- expect(storage2.listRoutes()).toEqual([route]);
+ const storage = new Storage(dataDir, configPath);
+ expect((await storage.init()).left().present()).toBe(false);
+ expect(storage.getRoute('route1')).toEqual(route);
+ expect(storage.listRoutes()).toEqual([route]);
});
- it('rejects unsafe route names', async () => {
- const storage = new Storage(dataDir);
- expect((await storage.init()).left().present()).toBe(false);
+ it('returns undefined for unsafe route names', async () => {
+ const toml = `
+[[route]]
+name = "safe-route"
+contentType = "json"
+hcaptchaProtected = false
+`;
+ await writeFile(configPath, toml);
- const result = await storage.registerRoute({
- name: '../bad',
- contentType: ContentType.JSON,
- hcaptchaProtected: false,
- });
+ const storage = new Storage(dataDir, configPath);
+ expect((await storage.init()).left().present()).toBe(false);
- expect(result.left().present()).toBe(true);
- expect(result.left().get().message).toBe('Invalid route name');
+ // getRoute should reject unsafe names
+ expect(storage.getRoute('../bad')).toBeUndefined();
+ expect(storage.getRoute('.')).toBeUndefined();
+ expect(storage.getRoute('..')).toBeUndefined();
+ expect(storage.getRoute('path/with/slash')).toBeUndefined();
});
it('stores a request and sanitizes uploaded filenames', async () => {
- const route: RouteConfig = {
- name: 'route1',
- contentType: ContentType.JSON,
- hcaptchaProtected: false,
- };
-
- const storage = new Storage(dataDir);
+ const toml = `
+[[route]]
+name = "route1"
+contentType = "json"
+hcaptchaProtected = false
+`;
+ await writeFile(configPath, toml);
+
+ const storage = new Storage(dataDir, configPath);
expect((await storage.init()).left().present()).toBe(false);
- expect((await storage.registerRoute(route)).left().present()).toBe(false);
const upload = {
fieldName: 'file',