mirror of
https://github.com/kikootwo/ReadMeABook.git
synced 2026-06-02 20:30:10 +00:00
b1492fc32e
Introduce a per-request release blocklist to auto-block permanently failing releases and provide admin management. Changes include: - Database: add BlockedRelease model (blocked_releases) to Prisma schema with unique (requestId, releaseKey) and indexes; documented in backend database docs. - Service & utils: new blocklist.service, release-key and filter helpers for normalization and matching; processors updated to emit auto-blocks (monitor-download, organize-files, search processors, RSS). - HTTP API: add admin endpoints GET/DELETE /api/admin/blocklist, DELETE /api/admin/blocklist/[id], and GET /api/admin/blocklist/by-request/[requestId]. - Admin UI: new /admin/blocklist page and numerous React components (toolbar, filters, table, rows, pagination, skeleton, chips, date picker) with URL-driven state hook and per-row unblock UX. - Tests: add unit/integration tests for service, routes, utils, and updated processor tests. The blocklist is idempotent (upsert), filters search results before ranking (interactive search shows badges only), and admin-only APIs require auth. This commit wires docs, API, DB, frontend and tests for the new feature.
66 lines
2.0 KiB
TypeScript
66 lines
2.0 KiB
TypeScript
/**
|
|
* Component: Prisma Mock Factory
|
|
* Documentation: documentation/backend/database.md
|
|
*/
|
|
|
|
import { vi } from 'vitest';
|
|
|
|
type PrismaModelMock = {
|
|
findMany: ReturnType<typeof vi.fn>;
|
|
findFirst: ReturnType<typeof vi.fn>;
|
|
findUnique: ReturnType<typeof vi.fn>;
|
|
create: ReturnType<typeof vi.fn>;
|
|
createMany: ReturnType<typeof vi.fn>;
|
|
update: ReturnType<typeof vi.fn>;
|
|
updateMany: ReturnType<typeof vi.fn>;
|
|
upsert: ReturnType<typeof vi.fn>;
|
|
delete: ReturnType<typeof vi.fn>;
|
|
deleteMany: ReturnType<typeof vi.fn>;
|
|
count: ReturnType<typeof vi.fn>;
|
|
};
|
|
|
|
const createModelMock = (): PrismaModelMock => ({
|
|
findMany: vi.fn(),
|
|
findFirst: vi.fn(),
|
|
findUnique: vi.fn(),
|
|
create: vi.fn(() => Promise.resolve({})),
|
|
createMany: vi.fn(() => Promise.resolve({ count: 0 })),
|
|
update: vi.fn(() => Promise.resolve({})),
|
|
updateMany: vi.fn(() => Promise.resolve({})),
|
|
upsert: vi.fn(() => Promise.resolve({})),
|
|
delete: vi.fn(() => Promise.resolve({})),
|
|
deleteMany: vi.fn(() => Promise.resolve({})),
|
|
count: vi.fn(),
|
|
});
|
|
|
|
export const createPrismaMock = () => ({
|
|
configuration: createModelMock(),
|
|
user: createModelMock(),
|
|
request: createModelMock(),
|
|
audiobook: createModelMock(),
|
|
downloadHistory: createModelMock(),
|
|
plexLibrary: createModelMock(),
|
|
audibleCache: createModelMock(),
|
|
job: createModelMock(),
|
|
jobEvent: createModelMock(),
|
|
scheduledJob: createModelMock(),
|
|
bookDateConfig: createModelMock(),
|
|
bookDateRecommendation: createModelMock(),
|
|
bookDateSwipe: createModelMock(),
|
|
goodreadsShelf: createModelMock(),
|
|
bookMapping: createModelMock(),
|
|
hardcoverShelf: createModelMock(),
|
|
apiToken: createModelMock(),
|
|
work: createModelMock(),
|
|
workAsin: createModelMock(),
|
|
watchedSeries: createModelMock(),
|
|
watchedAuthor: createModelMock(),
|
|
userHomeSection: createModelMock(),
|
|
audibleCacheCategory: createModelMock(),
|
|
ignoredAudiobook: createModelMock(),
|
|
blockedRelease: createModelMock(),
|
|
$queryRaw: vi.fn(),
|
|
$transaction: vi.fn(),
|
|
$disconnect: vi.fn(),
|
|
});
|