import { describe, it, expect } from 'vitest'; import { canEdit, isAuthorized, selectCanonical, BlogSettings, RevisionMeta } from '@/utils/wiki'; describe('wiki auth', () => { const owner = 'alice'; it('owner always allowed (auth + edit)', () => { const s: BlogSettings = { wikiEnabled: false }; expect(isAuthorized(owner, s, owner)).toBe(true); expect(canEdit(owner, s, owner)).toBe(true); }); it('wiki disabled: only owner allowed', () => { const s: BlogSettings = { wikiEnabled: false }; expect(isAuthorized('bob', s, owner)).toBe(false); expect(canEdit('bob', s, owner)).toBe(false); }); it('blacklist blocks even with whitelist', () => { const s: BlogSettings = { wikiEnabled: true, editorWhitelist: ['bob'], editorBlacklist: ['bob'], }; expect(isAuthorized('bob', s, owner)).toBe(false); expect(canEdit('bob', s, owner)).toBe(false); }); it('whitelist gates when non-empty', () => { const s: BlogSettings = { wikiEnabled: true, editorWhitelist: ['bob'] }; expect(isAuthorized('bob', s, owner)).toBe(true); expect(isAuthorized('carol', s, owner)).toBe(false); }); it('global allow when whitelist empty', () => { const s: BlogSettings = { wikiEnabled: true }; expect(isAuthorized('bob', s, owner)).toBe(true); expect(canEdit('carol', s, owner)).toBe(true); }); }); describe('wiki canonical selection', () => { const owner = 'alice'; const settings: BlogSettings = { wikiEnabled: true }; const revs: RevisionMeta[] = [ { id: 'q-blog-a-post-1-1', originPostId: 'q-blog-a-post-1-0', lineageBlogId: 'q-blog-a', authorName: 'bob', updatedAt: '2025-08-20T10:00:00Z', published: true, }, { id: 'q-blog-a-post-1-2', originPostId: 'q-blog-a-post-1-0', lineageBlogId: 'q-blog-a', authorName: 'carol', updatedAt: '2025-08-21T09:00:00Z', published: true, }, { id: 'q-blog-a-post-1-3', originPostId: 'q-blog-a-post-1-0', lineageBlogId: 'q-blog-a', authorName: owner, updatedAt: '2025-08-21T09:00:00Z', // tie with carol; owner should win published: true, }, { id: 'q-blog-a-post-1-4', originPostId: 'q-blog-a-post-1-0', lineageBlogId: 'q-blog-a', authorName: 'dave', updatedAt: '2025-08-19T00:00:00Z', published: false, // hidden }, ]; it('picks newest; owner wins tie; filters unpublished', () => { const sel = selectCanonical(revs, settings, owner, { expectedLineageBlogId: 'q-blog-a' }); expect(sel?.id).toBe('q-blog-a-post-1-3'); }); it('blacklist does not override owner precedence', () => { const sel = selectCanonical(revs, { wikiEnabled: true, editorBlacklist: [owner] }, owner, { expectedLineageBlogId: 'q-blog-a', }); // Owner always allowed even if listed expect(sel?.id).toBe('q-blog-a-post-1-3'); }); it('respects whitelist', () => { const sel = selectCanonical(revs, { wikiEnabled: true, editorWhitelist: ['bob'] }, owner, { expectedLineageBlogId: 'q-blog-a', }); // only bob + owner allowed; bob newer than bob? owner at same time but owner wins tie → owner expect(sel?.id).toBe('q-blog-a-post-1-3'); }); });