12 lines
4.3 KiB
JavaScript
12 lines
4.3 KiB
JavaScript
const test=require('node:test');const assert=require('node:assert/strict');const fs=require('node:fs');const path=require('node:path');const ts=require('typescript');const vm=require('node:vm');const {createRequire}=require('node:module');
|
|
function load(file,mocks={}){const full=path.resolve(file);const source=ts.transpileModule(fs.readFileSync(full,'utf8'),{compilerOptions:{module:ts.ModuleKind.CommonJS,target:ts.ScriptTarget.ES2022,esModuleInterop:true}}).outputText;const module={exports:{}};const localRequire=createRequire(full);vm.runInNewContext('(function(require,module,exports){'+source+'\n})',{Response,Request,URL,AbortSignal,console})(name=>name in mocks?mocks[name]:localRequire(name),module,module.exports);return module.exports}
|
|
const contact=load('lib/meshkee/contact.ts');const session=load('lib/meshkee/session.ts');
|
|
function contactRoute(api){return load('app/api/contact/route.ts',{'../../../lib/meshkee/session':session,'../../../lib/meshkee/contact':contact,'../../../lib/meshkee/api':{tenantApi:api}})}
|
|
const request=(body,origin='https://sgemed.com')=>new Request('https://sgemed.com/api/contact',{method:'POST',headers:{host:'sgemed.com',origin,'content-type':'application/json'},body:JSON.stringify(body)});
|
|
test('contact success forwards only validated fields and returns 201',async()=>{let sent;const route=contactRoute(async(p,init)=>{sent={p,data:JSON.parse(init.body)};return {submission:{id:1}}});const response=await route.POST(request({title:'Test',name:'Test',text:'Test',cellNumber:'09125537630',extra:'ignored'}));assert.equal(response.status,201);assert.equal(sent.p,'/contact-submissions');assert.equal(sent.data.cellNumber,'+989125537630');assert.equal(sent.data.extra,undefined)});
|
|
test('invalid and cross-origin forms never reach backend',async()=>{let called=false;const route=contactRoute(async()=>{called=true});assert.equal((await route.POST(request({}))).status,400);assert.equal((await route.POST(request({},'https://other.example'))).status,403);assert.equal(called,false)});
|
|
test('upstream failure is not reported as success',async()=>{const route=contactRoute(async()=>{throw new Error('offline')});assert.equal((await route.POST(request({title:'a',name:'b',text:'c'}))).status,502)});
|
|
test('logout expires parent and host-only cookies and rejects cross-origin',async()=>{const route=load('app/api/logout/route.ts',{'../../../lib/meshkee/session':session});const response=await route.POST(request({}));assert.equal(response.status,200);const cookies=response.headers.get('set-cookie');assert.match(cookies,/Domain=.sgemed.com/i);assert.match(cookies,/meshkee_customer_access_token/);assert.match(cookies,/meshkee_customer_refresh_token/);assert.match(cookies,/Max-Age=0/);assert.equal((await route.POST(request({},'https://other.example'))).status,403)});
|
|
test('blog rich text removes executable HTML while retaining headings',()=>{const blog=load('lib/meshkee/blog.ts',{'./api':{tenantApi:()=>{},safeUrl:()=>{}}});const html=blog.articleHtml({content:'<h2>عنوان</h2><script>alert(1)</script><img src="https://example.com/a.jpg" onerror="alert(1)"><a href="javascript:alert(1)">x</a>'});assert.match(html,/<h2>عنوان<\/h2>/);assert.doesNotMatch(html,/script|onerror|javascript/)});
|
|
test('account refresh validates new token and never exposes tokens',async()=>{class ApiError extends Error{constructor(status){super();this.status=status}}const calls=[];const route=load('app/api/account/route.ts',{'next/headers':{cookies:async()=>({get:name=>({value:name.includes('refresh')?'refresh-secret':'expired-secret'})})},'../../../lib/meshkee/api':{ApiError,api:async(p,init)=>{calls.push(p);if(p==='/auth/refresh')return {accessToken:'new-secret',refreshToken:'new-refresh'};if(init.headers.Authorization==='Bearer expired-secret')throw new ApiError(401);return {user:{firstName:'نام',lastName:'کاربر',businesses:[{businessId:3,teamRole:'editor'}]}}},getTenant:async()=>({id:3})},'../../../lib/meshkee/session':session});const response=await route.GET(new Request('https://sgemed.com/api/account',{headers:{host:'sgemed.com'}}));assert.equal(response.status,200);const body=await response.text();assert.match(body,/نام/);assert.match(body,/"isAdmin":true/);assert.doesNotMatch(body,/secret|refresh/);assert.deepEqual(calls,['/auth/me','/auth/refresh','/auth/me']);assert.match(response.headers.get('set-cookie'),/HttpOnly/)});
|