sign every write as an MMUR2 claim (POST /api/claims); the guessed title is parsedTitle
Build and Push Docker Image / build (push) Successful in 47s
Build and Push Docker Image / build (push) Successful in 47s
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* `addToSet` keeps the legacy csv-set shape under claims: it rewrites THIS
|
||||
* signer's own comma-joined vote, ignoring other signers' claims. fetch is
|
||||
* stubbed with a tiny meta-core.
|
||||
*/
|
||||
|
||||
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
||||
import { MetaCoreClient, ClaimSigner, verifyClaim, resetSignerForTests } from '../src/meta-core-client.js';
|
||||
|
||||
const KEY = '01'.repeat(32);
|
||||
const own = new ClaimSigner(KEY);
|
||||
const other = new ClaimSigner('02'.repeat(32));
|
||||
|
||||
/** Claims meta-core holds for the cid, and every batch posted. */
|
||||
let stored: Array<Record<string, unknown>>;
|
||||
let posted: Array<Array<Record<string, unknown>>>;
|
||||
let claimReads: string[];
|
||||
|
||||
function json(body: unknown, status = 200): Response {
|
||||
return new Response(JSON.stringify(body), { status, headers: { 'Content-Type': 'application/json' } });
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
process.env.METAMESH_SIGNING_KEY = KEY;
|
||||
resetSignerForTests();
|
||||
stored = [];
|
||||
posted = [];
|
||||
claimReads = [];
|
||||
vi.stubGlobal('fetch', vi.fn(async (url: string, init?: RequestInit) => {
|
||||
const u = new URL(url);
|
||||
if (init?.method === 'GET' && u.pathname.endsWith('/claims')) {
|
||||
claimReads.push(u.pathname + u.search);
|
||||
const key = u.searchParams.get('key');
|
||||
return json({ claims: stored.filter((c) => c.key === key) });
|
||||
}
|
||||
if (init?.method === 'POST' && u.pathname === '/api/claims') {
|
||||
const batch = JSON.parse(String(init.body)) as Array<Record<string, unknown>>;
|
||||
posted.push(batch);
|
||||
return json(batch.map(() => ({ status: 'accepted' })));
|
||||
}
|
||||
return json({ error: 'no route' }, 404);
|
||||
}));
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.unstubAllGlobals();
|
||||
delete process.env.METAMESH_SIGNING_KEY;
|
||||
resetSignerForTests();
|
||||
});
|
||||
|
||||
const client = () => new MetaCoreClient('http://core');
|
||||
const claimOf = (s: ClaimSigner, value: string, ts: number) =>
|
||||
({ cid: 'bafycid', uid: s.uid, key: 'genres', value, ts, sig: 'x' });
|
||||
|
||||
function postedValue(): string {
|
||||
expect(posted).toHaveLength(1);
|
||||
const [c] = posted[0];
|
||||
expect(c.key).toBe('genres');
|
||||
expect(c.uid).toBe(own.uid);
|
||||
expect(verifyClaim({ ...(c as never), sig: Buffer.from(String(c.sig), 'base64') })).toBe(true);
|
||||
return String(c.value);
|
||||
}
|
||||
|
||||
describe('addToSet (csv-set over this signer\'s own claim)', () => {
|
||||
it('writes the first member when this signer has no claim yet', async () => {
|
||||
stored = [claimOf(other, 'Comedy', 5)];
|
||||
expect(await client().addToSet('bafycid', 'genres', 'Drama')).toBe(true);
|
||||
expect(claimReads).toEqual(['/api/meta/bafycid/claims?key=genres']);
|
||||
expect(postedValue()).toBe('Drama');
|
||||
});
|
||||
|
||||
it('appends to its own newest value and ignores other signers', async () => {
|
||||
stored = [claimOf(own, 'Action', 1), claimOf(own, 'Drama, Thriller', 9), claimOf(other, 'Comedy,Horror', 20)];
|
||||
expect(await client().addToSet('bafycid', 'genres', 'Sci-Fi/Fantasy')).toBe(true);
|
||||
expect(postedValue()).toBe('Drama,Thriller,Sci-Fi/Fantasy');
|
||||
});
|
||||
|
||||
it('writes nothing when the member is already in its own value', async () => {
|
||||
stored = [claimOf(own, 'Drama,Thriller', 9)];
|
||||
expect(await client().addToSet('bafycid', 'genres', 'Thriller')).toBe(true);
|
||||
expect(posted).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('refuses to write when its own claims cannot be read', async () => {
|
||||
vi.stubGlobal('fetch', vi.fn(async (url: string, init?: RequestInit) => {
|
||||
if (init?.method === 'GET') return json({ error: 'nope' }, 500);
|
||||
return json([{ status: 'accepted' }]);
|
||||
}));
|
||||
expect(await client().addToSet('bafycid', 'genres', 'Drama')).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user