test: add full playwright ui regression coverage
Some checks failed
docker-images / build-and-push (admin, admin, termi-astro-admin, admin/Dockerfile) (push) Successful in 52s
docker-images / build-and-push (backend, backend, termi-astro-backend, backend/Dockerfile) (push) Failing after 13s
docker-images / build-and-push (frontend, frontend, termi-astro-frontend, frontend/Dockerfile) (push) Successful in 32s
ui-regression / playwright-regression (push) Failing after 14m24s
Some checks failed
docker-images / build-and-push (admin, admin, termi-astro-admin, admin/Dockerfile) (push) Successful in 52s
docker-images / build-and-push (backend, backend, termi-astro-backend, backend/Dockerfile) (push) Failing after 13s
docker-images / build-and-push (frontend, frontend, termi-astro-frontend, frontend/Dockerfile) (push) Successful in 32s
ui-regression / playwright-regression (push) Failing after 14m24s
This commit is contained in:
92
frontend/src/lib/reviews.ts
Normal file
92
frontend/src/lib/reviews.ts
Normal file
@@ -0,0 +1,92 @@
|
||||
import type { Review } from './api/client';
|
||||
|
||||
export type ReviewStatus = 'completed' | 'in-progress' | 'dropped';
|
||||
|
||||
export type ParsedReview = Omit<Review, 'tags'> & {
|
||||
tags: string[];
|
||||
normalizedStatus: ReviewStatus;
|
||||
coverIsImage: boolean;
|
||||
coverUrl: string | null;
|
||||
linkUrl: string | null;
|
||||
externalLink: boolean;
|
||||
};
|
||||
|
||||
const reviewCoverCatalog: Record<string, string> = {
|
||||
'《漫长的季节》': '/review-covers/the-long-season.svg',
|
||||
'《十三邀》': '/review-covers/thirteen-invites.svg',
|
||||
'《黑神话:悟空》': '/review-covers/black-myth-wukong.svg',
|
||||
'《置身事内》': '/review-covers/placed-within.svg',
|
||||
'《宇宙探索编辑部》': '/review-covers/journey-to-the-west-editorial.svg',
|
||||
'《疲惫生活中的英雄梦想》': '/review-covers/hero-dreams-in-tired-life.svg',
|
||||
};
|
||||
|
||||
export function normalizeReviewStatus(status: string | null | undefined): ReviewStatus {
|
||||
const normalized = String(status || '').trim().toLowerCase();
|
||||
|
||||
if (normalized === 'published' || normalized === 'completed' || normalized === 'done') {
|
||||
return 'completed';
|
||||
}
|
||||
|
||||
if (
|
||||
normalized === 'draft' ||
|
||||
normalized === 'in-progress' ||
|
||||
normalized === 'watching' ||
|
||||
normalized === 'reading' ||
|
||||
normalized === 'listening'
|
||||
) {
|
||||
return 'in-progress';
|
||||
}
|
||||
|
||||
if (normalized === 'dropped' || normalized === 'abandoned') {
|
||||
return 'dropped';
|
||||
}
|
||||
|
||||
return 'completed';
|
||||
}
|
||||
|
||||
export function parseReviewTags(value: string | null | undefined): string[] {
|
||||
if (!value) {
|
||||
return [];
|
||||
}
|
||||
|
||||
try {
|
||||
const parsed = JSON.parse(value);
|
||||
return Array.isArray(parsed) ? parsed.filter((item): item is string => typeof item === 'string') : [];
|
||||
} catch {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
export function isImageCover(cover: string | null | undefined) {
|
||||
const normalized = String(cover || '').trim();
|
||||
return /^(https?:)?\/\//.test(normalized) || normalized.startsWith('/');
|
||||
}
|
||||
|
||||
export function resolveReviewCover(review: Pick<Review, 'cover' | 'title'>) {
|
||||
if (isImageCover(review.cover)) {
|
||||
return String(review.cover).trim();
|
||||
}
|
||||
|
||||
return reviewCoverCatalog[review.title] || null;
|
||||
}
|
||||
|
||||
export function normalizeLinkUrl(value: string | null | undefined) {
|
||||
const trimmed = String(value || '').trim();
|
||||
return trimmed ? trimmed : null;
|
||||
}
|
||||
|
||||
export function isExternalLink(value: string | null | undefined) {
|
||||
return /^(https?:)?\/\//.test(String(value || '').trim());
|
||||
}
|
||||
|
||||
export function parseReview(review: Review): ParsedReview {
|
||||
return {
|
||||
...review,
|
||||
tags: parseReviewTags(review.tags),
|
||||
normalizedStatus: normalizeReviewStatus(review.status),
|
||||
coverIsImage: isImageCover(review.cover),
|
||||
coverUrl: resolveReviewCover(review),
|
||||
linkUrl: normalizeLinkUrl(review.link_url),
|
||||
externalLink: isExternalLink(review.link_url),
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user