87 lines
5.8 KiB
JavaScript
87 lines
5.8 KiB
JavaScript
// Read-only business smoke checks; POSTs only establish a guest or validate empty login input.
|
|
// Cookies stay in memory and are never printed or written to disk.
|
|
import assert from "node:assert/strict";
|
|
|
|
const base = process.env.PREVIEW_URL || "http://127.0.0.1:21021";
|
|
const publicOnly = process.env.SMOKE_PUBLIC_ONLY === "1";
|
|
const cookies = new Map();
|
|
const cookieHeader=()=>[...cookies].map(([key,value])=>`${key}=${value}`).join('; ');
|
|
async function request(path, body) {
|
|
const response = await fetch(`${base}/api/${path}`, {
|
|
method: body === undefined ? "GET" : "POST",
|
|
headers: {Cookie: cookieHeader(), ...(body === undefined ? {} : {"Content-Type":"application/json"})},
|
|
body: body === undefined ? undefined : JSON.stringify(body),
|
|
});
|
|
for (const item of response.headers.getSetCookie()) {
|
|
const [pair] = item.split(";"); const index = pair.indexOf("=");
|
|
cookies.set(pair.slice(0,index), pair.slice(index+1));
|
|
}
|
|
const envelope = await response.json();
|
|
assert.equal(response.status,200,`${path}: HTTP ${response.status}`);
|
|
assert.equal(envelope.code,200,`${path}: ${envelope.msg || envelope.tip}`);
|
|
return envelope.data;
|
|
}
|
|
|
|
const home = await request("playlet/home");
|
|
const response = await fetch(base);
|
|
const html = await response.text();
|
|
assert.equal(response.status,200);
|
|
assert.ok(!html.includes("data-must-watch-sort"),"首页筛选项应保持移除");
|
|
if (!publicOnly) {
|
|
const guest = await request("auth/guest",{});
|
|
assert.ok(guest.userId,"游客登录应返回用户 ID");
|
|
assert.equal(guest.token,undefined,"token 不应暴露给浏览器脚本");
|
|
assert.ok(cookies.has("drama_session"),"应通过 Cookie 保持会话");
|
|
console.log("PASS: HttpOnly guest session");
|
|
}
|
|
console.log("PASS: SSR homepage");
|
|
|
|
const checks = ["config/info", "config/footer/info", "navigation/header", "translation/category/list", "theme/list", "playlet/tag/options", "playlet/all/list?sortType=1&pageNum=1&pageSize=4", "playlet/hot/list?pageNum=1&pageSize=4", ...[1,2,3].map(rank=>`playlet/hot/rank/list?rankType=${rank}&pageNum=1&pageSize=4`), "playlet/topic/list?pageNum=1&pageSize=4", "applist/list?categoryId=0", "playlet/hot-like", ...(!publicOnly?["auth/getInfo", "user/center/data", "playlet/history/list?pageNum=1&pageSize=4", "playlet/collect/list?pageNum=1&pageSize=4&watchStatus=0", "playlet/bought/list?pageNum=1&pageSize=4", "coin/trans/list?page=1&pageSize=10&type=0"]:[])];
|
|
const dataByPath=new Map();
|
|
for(let offset=0;offset<checks.length;offset+=4)await Promise.all(checks.slice(offset,offset+4).map(async path=>{const data=await request(path);assert.ok(data,`${path}: missing data`);dataByPath.set(path.split('?')[0],data);console.log(`PASS: ${path.split("?")[0]}`);}));
|
|
const pages=['/shorts/','/shorts/page/2/','/rank/hot/','/rank/new/','/rank/follow/','/topics/','/apps/','/home-road/','/navigation/','/info/about-us/','/info/user-agreement/','/info/privacy-policy/','/info/help-center/','/info/2257/','/info/dmca/'];
|
|
const topic=dataByPath.get('playlet/topic/list')?.list?.[0];
|
|
if(topic){
|
|
const detail=await request(`playlet/topic/detail?id=${topic.id}&pageNum=1&pageSize=4`);
|
|
assert.equal(detail.id,topic.id);assert.equal(typeof detail.name,'string');assert.ok(Array.isArray(detail.list));
|
|
pages.push(`/topics/${topic.id}/`,`/theme/${topic.id}/`);
|
|
}
|
|
const tag=dataByPath.get('playlet/tag/options')?.list?.[0];
|
|
if(tag)pages.push(`/tag/${tag.id}/`);
|
|
const block=home.homeConfigData?.find(item=>item.status&&!item.moreUrl);
|
|
if(block)pages.push(`/config/${block.id}/`);
|
|
const first = home.homeBannerData?.[0] || home.homeConfigData?.find(block=>block.list?.length)?.list[0];
|
|
if (first) {
|
|
const search=await request("playlet/search?"+new URLSearchParams({keyword:first.playName||first.title,pageNum:"1",pageSize:"4"}));
|
|
assert.ok(Array.isArray(search.list));
|
|
pages.push('/search/'+encodeURIComponent(first.playName||first.title)+'/');
|
|
const suggestions=await request('playlet/search/suggest?'+new URLSearchParams({keyword:first.playName||first.title}));assert.ok(Array.isArray(suggestions.list));
|
|
if (!publicOnly) {
|
|
const detail=await request(`playlet/detail?id=${first.id}`);
|
|
assert.equal(detail.id,first.id);
|
|
const chapters=await request(`playlet/chapter/list?playletId=${first.id}`);
|
|
const related=await request(`playlet/guess-like/list?playletId=${first.id}&pageNum=1&pageSize=6`);assert.ok(Array.isArray(related.list));
|
|
pages.push(`/detail/${first.id}/`);
|
|
if (chapters.list?.length) {
|
|
const chapter=await request(`playlet/chapter/detail?playletId=${first.id}&chapterId=${chapters.list[0].id}`);
|
|
assert.equal(chapter.id,chapters.list[0].id);
|
|
assert.equal(typeof chapter.canWatch,"boolean");
|
|
pages.push(`/play/${first.id}/${chapter.id}/`);
|
|
}
|
|
console.log("PASS: drama detail and chapter permissions");
|
|
}
|
|
console.log("PASS: search");
|
|
}
|
|
for(let offset=0;offset<pages.length;offset+=3)await Promise.all(pages.slice(offset,offset+3).map(async path=>{
|
|
const response=await fetch(base+path,{headers:{Cookie:cookieHeader()},redirect:'manual'}),html=await response.text();
|
|
assert.equal(response.status,200,path);assert.equal(response.headers.get('location'),null,path);assert.ok(!html.includes('内容暂不可用,请稍后重试'),path);assert.ok(!html.includes('class="api-loading"'),path);
|
|
const marker=path==='/home-road/'?'return-home-directory':path.startsWith('/search/')?'data-search-results':'';
|
|
if(marker)assert.ok(html.includes(marker),path+' must contain the complete server-rendered page');
|
|
console.log(`PASS: page ${path}`);
|
|
}));
|
|
const rejected=await fetch(`${base}/api/not-allowed`);
|
|
assert.equal(rejected.status,404);
|
|
const removedLogin=await fetch(`${base}/api/auth/login`,{method:"POST",headers:{Origin:new URL(base).origin,"Sec-Fetch-Site":"same-origin","Content-Type":"application/json"},body:"{}"});
|
|
assert.equal(removedLogin.status,404);
|
|
console.log("PASS: proxy endpoint allowlist rejects removed account routes");
|