119 lines
9.7 KiB
JavaScript
119 lines
9.7 KiB
JavaScript
import {test,expect} from '@playwright/test';
|
||
|
||
async function fixture(page){
|
||
await page.route('**/index.html',r=>r.fulfill({contentType:'text/html',body:'<!doctype html><html><head><script src="/core/company-branding.js"></script></head><body><header><div class="brand"></div></header></body></html>'}));
|
||
await page.goto('/index.html');
|
||
}
|
||
async function logo(page,color='#146b3d'){
|
||
return page.evaluate(async color=>{
|
||
const c=document.createElement('canvas');c.width=48;c.height=24;const x=c.getContext('2d');x.fillStyle=color;x.fillRect(8,4,32,16);
|
||
const blob=await new Promise(r=>c.toBlob(r,'image/png'));
|
||
return window.CateriumBranding.saveLogo(new File([blob],'logo.png',{type:'image/png'}));
|
||
},color);
|
||
}
|
||
|
||
test('company logo preserves transparency, persists and clears without changing product brand',async({page})=>{
|
||
await fixture(page);const data=await logo(page);
|
||
await page.evaluate(()=>window.CateriumBranding.saveName('Кухня <Гости> & Ко'));
|
||
const result=await page.evaluate(async()=>{
|
||
const b=window.CateriumBranding,img=new Image();img.src=b.documentImage();await img.decode();const c=document.createElement('canvas');c.width=48;c.height=24;const x=c.getContext('2d');x.drawImage(img,0,0);
|
||
return {name:b.documentName(),escaped:b.nameHTML(),alpha:x.getImageData(0,0,1,1).data[3],body:document.querySelector('header').textContent};
|
||
});
|
||
expect(result).toEqual({name:'Кухня <Гости> & Ко',escaped:'Кухня <Гости> & Ко',alpha:0,body:'Caterium'});
|
||
await page.reload();expect(await page.evaluate(()=>window.CateriumBranding.documentLogo())).toBe(data);
|
||
await page.evaluate(()=>{localStorage.setItem('sunCompanyProfileV1',JSON.stringify({logo:window.CateriumBranding.documentLogo()}));window.CateriumBranding.clearLogo()});
|
||
expect(await page.evaluate(()=>window.CateriumBranding.documentLogo())).toBe('');
|
||
expect(await page.evaluate(async()=>{const i=new Image();i.src=window.CateriumBranding.documentImage();await i.decode();return i.naturalWidth})).toBe(1);
|
||
});
|
||
|
||
test('exclusive sidebar is server assigned, resets on account changes and ignores stale replies',async({page})=>{
|
||
await fixture(page);
|
||
await page.evaluate(async()=>{
|
||
window.__user='owner';window.__calls=[];
|
||
window.SunCloudV2={getSession:()=>window.__user?{user:{id:window.__user}}:null,getClient:()=>({rpc:async name=>{window.__calls.push(name);return {data:{variant:window.__user==='owner'?'solnce':'caterium'}}}})};
|
||
await window.CateriumBranding.refreshSidebar();
|
||
});
|
||
await expect(page.locator('header .brand')).toHaveText('Солнце Кейтеринг');
|
||
await logo(page);await page.evaluate(()=>window.CateriumBranding.saveName('Другой бренд документов'));
|
||
await expect(page.locator('header .brand')).toHaveText('Солнце Кейтеринг');
|
||
await page.evaluate(async()=>{window.__user='employee';await window.CateriumBranding.refreshSidebar()});
|
||
await expect(page.locator('header .brand')).toHaveText('Caterium');
|
||
await page.evaluate(async()=>{
|
||
window.__user='owner';window.SunCloudV2.getClient=()=>({rpc:()=>new Promise(r=>window.__reply=r)});
|
||
const pending=window.CateriumBranding.refreshSidebar();window.__user=null;window.CateriumBranding.resetSidebar();window.__reply({data:{variant:'solnce'}});await pending;
|
||
});
|
||
await expect(page.locator('header .brand')).toHaveText('Caterium');
|
||
});
|
||
|
||
test('document branding follows workspace storage without leaking the previous company',async({page})=>{
|
||
await fixture(page);const first=await logo(page);
|
||
await page.evaluate(()=>window.CateriumBranding.saveName('Компания А'));
|
||
const saved=await page.evaluate(()=>({...localStorage}));
|
||
await page.evaluate(()=>{localStorage.clear();localStorage.setItem('sunCompanyProfileV1',JSON.stringify({name:'Компания Б'}));window.dispatchEvent(new Event('sun:cloud-state-applied'))});
|
||
expect(await page.evaluate(()=>window.CateriumBranding.identity())).toMatchObject({name:'Компания Б',logo:''});
|
||
const second=await logo(page,'#801599');expect(second).not.toBe(first);
|
||
await page.evaluate(saved=>{localStorage.clear();for(const [k,v] of Object.entries(saved))localStorage.setItem(k,v);window.dispatchEvent(new Event('sun:cloud-state-applied'))},saved);
|
||
expect(await page.evaluate(()=>window.CateriumBranding.identity())).toMatchObject({name:'Компания А',logo:first});
|
||
});
|
||
|
||
test('every classic and signature PDF uses the supplied company logo and no legacy company text',async({page})=>{
|
||
test.setTimeout(60000);await fixture(page);
|
||
for(const module of ['classic-offer-pdf-v1767.js','signature-offer-pdf-v18.js'])await page.addScriptTag({url:'/core/'+module});
|
||
const data=await logo(page);
|
||
const result=await page.evaluate(async data=>{
|
||
const texts=[],images=[],proto=CanvasRenderingContext2D.prototype,fill=proto.fillText,draw=proto.drawImage;
|
||
proto.fillText=function(t,...a){texts.push(String(t));return fill.call(this,t,...a)};
|
||
proto.drawImage=function(i,...a){images.push(i.src);return draw.call(this,i,...a)};
|
||
const b={brandName:'Компания Лист',brandCity:'Казань',logo:data,client:'Анна',event:'Обед',items:[],pricing:{total:15000},guests:10};
|
||
const counts=[];
|
||
try{for(const api of [window.SunClassicOfferPDFV1767,window.SunSignatureOfferPDFV18])for(const id of api.CLASSIC_IDS||api.SIGNATURE_IDS){const before=images.length;await api.renderCover({...b,offerTemplateId:id},id);counts.push({id,logo:images.slice(before).includes(data)})}}finally{proto.fillText=fill;proto.drawImage=draw}
|
||
return {counts,legacy:texts.filter(t=>/солнц|SUN \/ CATERING|САНКТ-ПЕТЕРБУРГ/i.test(t))};
|
||
},data);
|
||
expect(result.counts).toHaveLength(18);expect(result.counts.filter(x=>!x.logo)).toEqual([]);expect(result.legacy).toEqual([]);
|
||
});
|
||
|
||
test('real order blank, receipt and preparation share uploaded company identity',async({page})=>{
|
||
await page.goto('/index.html',{waitUntil:'domcontentloaded'});
|
||
await page.waitForFunction(()=>Boolean(window.sunShowOrderBlankV5));
|
||
const data=await logo(page);
|
||
await page.evaluate(()=>window.CateriumBranding.saveName('Компания <Лист>'));
|
||
const result=await page.evaluate(()=>{
|
||
const out=[];for(const fn of ['sunShowOrderBlankV5','sunShowConfiguredReceipt','openPreview']){
|
||
window[fn]();const root=document.querySelector('#preview .dialog');out.push({fn,text:root.textContent,logos:[...root.querySelectorAll('.sun-doc-brand img,.prep-doc-brand img')].map(x=>x.src),unsafe:!!root.querySelector('лист')});
|
||
}return out;
|
||
});
|
||
for(const row of result){expect(row.text).toContain('Компания <Лист>');expect(row.text).not.toMatch(/Солнце|Моя компания/);expect(row.logos).toEqual([data]);expect(row.unsafe).toBe(false)}
|
||
await page.evaluate(()=>document.querySelector('header nav button[data-nav-label="Настройки"]').click());
|
||
await expect(page.locator('#sunPdfBrandCard')).toHaveAttribute('data-settings-tab','documents');
|
||
await page.locator('#sunPdfBrandLogoFile').setInputFiles({name:'company.png',mimeType:'image/png',buffer:Buffer.from(data.split(',')[1],'base64')});
|
||
await expect.poll(()=>page.evaluate(()=>window.CateriumBranding.documentLogo())).toBe(data);
|
||
});
|
||
|
||
test('catalog, route sheet and full PDF pages retain the company brand',async({page})=>{
|
||
test.setTimeout(60000);
|
||
await page.goto('/index.html',{waitUntil:'domcontentloaded'});
|
||
await page.waitForFunction(()=>Boolean(window.sunClientOfferDebugPdfPages));
|
||
const data=await logo(page);
|
||
const result=await page.evaluate(async data=>{
|
||
const brand=window.CateriumBranding;brand.saveName('Лист');window.print=()=>{};
|
||
boxes.push({id:'brand-catalog-fixture',name:'Бокс компании Лист',price:1200,category:0,photo:'',ingredients:[],composition:[]});
|
||
const texts=[],images=[],proto=CanvasRenderingContext2D.prototype,fill=proto.fillText,draw=proto.drawImage;
|
||
proto.fillText=function(t,...a){texts.push(String(t));return fill.call(this,t,...a)};
|
||
proto.drawImage=function(i,...a){images.push(i.src);return draw.call(this,i,...a)};
|
||
const allIds=[...window.SunClassicOfferPDFV1767.CLASSIC_IDS,...window.SunClassicOfferPDFV1767.ARCHIVE_IDS,...window.SunSignatureOfferPDFV18.SIGNATURE_IDS],counts=[];
|
||
try{
|
||
for(const id of allIds){const pages=await window.sunClientOfferDebugPdfPages({offerTemplateId:id,brandName:'Лист',brandCity:'Казань',logo:data,event:'Обед',items:[],pricing:{total:1000},guests:10});counts.push(pages.length)}
|
||
await window.sunCatalogDebugPdfPages(0,1);
|
||
}finally{proto.fillText=fill;proto.drawImage=draw}
|
||
await window.sunPrintLiveCatalog();
|
||
const catalog=document.querySelector('#sunLiveCatalogPrintRoot');const catalogOK=catalog.textContent.includes('ЛИСТ')&&[...catalog.querySelectorAll('.sun-live-catalog-logo')].every(i=>i.src===data);
|
||
window.sunOpenRoutes();await document.getElementById('routePrint').onclick();
|
||
const route=document.querySelector('#preview .dialog');
|
||
const html=window.sunClientOfferDebugHtml({brandName:'Лист',brandCity:'Казань',logo:'',items:[],pricing:{},event:'Обед'});
|
||
return {counts,catalogOK,routeName:route.querySelector('.sun-custom-brand')?.textContent,routeLogo:route.querySelector('.sun-custom-brand img')?.src,logoDrawn:images.includes(data),legacy:texts.filter(t=>/солнц|SUN \/ CATERING|САНКТ-ПЕТЕРБУРГ/i.test(t)),neutralHeader:html.includes('<strong>Лист</strong>')};
|
||
},data);
|
||
expect(result.counts).toHaveLength(21);expect(result.counts.every(n=>n>0)).toBe(true);
|
||
expect(result.catalogOK).toBe(true);expect(result.routeName).toContain('Лист');expect(result.routeLogo).toBe(data);
|
||
expect(result.logoDrawn).toBe(true);expect(result.legacy).toEqual([]);expect(result.neutralHeader).toBe(true);
|
||
});
|