import assert from "node:assert/strict"; import test from "node:test"; import { renderToStaticMarkup } from "react-dom/server"; import { DramaCard, PlayRecommendationCard, SeriesCard, } from "../src/components/catalog/Cards"; import { Pagination } from "../src/components/catalog/Pagination"; import { PromoGrid } from "../src/components/catalog/Promotions"; import { CatalogGrid, ListPage, SeriesPage, } from "../src/features/catalog/BrowsePages"; import { allListURL, array, cardTags, moreListURL, moreSeriesListURL, searchResultsURL, seriesListURL, tagPageURL, topicDetailURL, } from "../src/features/catalog/model"; const item = { id: 7, slug: "都市 剧", playName: "作品名", title: "备用标题", cover: "/static/brand/header.svg", totalEpisode: 8, updateStatus: 1, isFeatured: true, tagIds: [2], tagNames: ["爱情"], tagSlugs: ["romance"], themeIds: [3], themeNames: ["爱情", "都市"], themeSlugs: ["love", "city"], }; const ads = [ { id: 1, images: "/static/brand/header.svg", link: "https://promo.test/", title: "推荐", }, ]; test("React card variants preserve watch URLs, episode gates, badges and linked deduplicated tags", () => { const card = renderToStaticMarkup(); assert.match(card, /class="hk-drama-card hk-drama-card--list"/); assert.match( card, /href="\/drama\/都市%20剧\/"|href="\/drama\/%E9%83%BD%E5%B8%82%20%E5%89%A7\/"/, ); assert.match( card, /

连载 · 8 集<\/span>/, ); assert.doesNotMatch(card, /hk-drama-card__ep"/); assert.match(card, /hk-badge hk-badge--hot/); assert.match(card, /href="\/tags\/romance\/"/); assert.deepEqual( cardTags(item).map((tag) => tag.Name), ["爱情", "都市"], ); const recommendation = renderToStaticMarkup( , ); assert.match(recommendation, /hk-drama-card hk-drama-card--play/); assert.match(recommendation, /hk-drama-card__meta-ep" data-status="serial">连载 · 8 集, ); assert.match(video, /href="\/series\/watch\/movie\/"/); assert.match(video, /全 12 集/); assert.match(video, /动画/); }); test("React list advertising keeps independent desktop and mobile row positions and clone attribution", () => { const items = array( Array.from({ length: 25 }, (_, index) => ({ ...item, id: index + 1 })), ); const grid = renderToStaticMarkup(); assert.equal((grid.match(/class="hk-drama-card hk-drama-card--list"/g) || []).length, 25); assert.equal((grid.match(/class="hk-drama-browse-mid-promo hk-desktop-only"/g) || []).length, 2); assert.equal((grid.match(/class="hk-drama-browse-mid-promo hk-mobile-only"/g) || []).length, 4); const videoGrid = renderToStaticMarkup( , ); assert.equal( (videoGrid.match(/class="hk-series-list-promo hk-desktop-only"/g) || []).length, 1, ); assert.equal( (videoGrid.match(/class="hk-series-list-promo hk-mobile-only"/g) || []).length, 3, ); const promo = renderToStaticMarkup(); assert.equal((promo.match(/data-track-ad="external"/g) || []).length, 2); assert.equal((promo.match(/data-ad-clone="1"/g) || []).length, 1); assert.match(promo, /rel="sponsored nofollow noopener"/); }); test("React filter and pagination links preserve the source path-only canonical route contracts", () => { assert.equal(allListURL("", 0, 0, 1, 1), "/dramas/"); assert.equal( allListURL("都市", 3, 2, 3, 2), "/dramas/%E9%83%BD%E5%B8%82/2/3/page/2/", ); assert.equal(seriesListURL(2, 4, 3, 2), "/series/anime/4/3/page/2/"); assert.equal(moreListURL("featured", 1, 0, "", 0, 1), "/curated/dramas/featured/"); assert.equal( moreSeriesListURL("", 3, 1, "city", 0, 2), "/curated/series/3/1/city/page/2/", ); assert.equal(tagPageURL("romance", 1, 2, 1), "/tags/romance/sort/2/"); assert.equal( topicDetailURL("city", 1, 3, 2), "/collection/city/sort/3/page/2/", ); assert.equal(searchResultsURL("a/b"), "/search/a%2Fb/"); const html = renderToStaticMarkup( , ); assert.match(html, /hk-pagination__btn--prev hk-is-disabled/); assert.match(html, /aria-current="page"/); assert.match(html, /href="\/dramas\/all\/0\/1\/page\/2\/"/); assert.match(html, /hk-pagination__ellipsis/); assert.match(html, /共 3 页/); const list = renderToStaticMarkup( , ); assert.match(list, /href="\/dramas\/city\/2\/3\/"/); assert.match(list, /暂无短剧/); const series = renderToStaticMarkup( , ); assert.match(series, /href="\/series\/anime\/4\/1\/"/); assert.match(series, /暂无剧集/); });