* docs: prepare Vendoo 1.41.2 git-ignore boundary hotfix * fix: track native source modules with root-anchored runtime ignores
47 lines
4.1 KiB
JavaScript
47 lines
4.1 KiB
JavaScript
import { mkdtempSync, writeFileSync, existsSync, rmSync } from 'node:fs';
|
|
import { tmpdir } from 'node:os';
|
|
import { join } from 'node:path';
|
|
import { ListingsService } from '../app/modules/listings/service.mjs';
|
|
import { InventoryService } from '../app/modules/inventory/service.mjs';
|
|
import { MediaService } from '../app/modules/media/service.mjs';
|
|
|
|
const failures=[]; const assert=(c,m)=>{if(!c)failures.push(m)}; const expectThrow=(fn,code,m)=>{try{fn();failures.push(m)}catch(e){if(code&&e.code!==code)failures.push(`${m} (${e.code||e.message})`)}};
|
|
let listings=[{id:1,title:'Aktiv',deleted_at:null,tags:[],photos:[]},{id:2,title:'Papierkorb',deleted_at:'2026-01-01',tags:[],photos:[]}];
|
|
const listRepo={
|
|
create(data){const row={id:3,...data,tags:data.tags||[],photos:data.photos||[]};listings.push(row);return row;},
|
|
get(id){return listings.find(x=>x.id===Number(id))||null;}, list(){return listings.filter(x=>!x.deleted_at);},
|
|
update(id,data){const row=this.get(id);Object.assign(row,data);return row;}, softDelete(id){this.get(id).deleted_at='now';},
|
|
restore(id){this.get(id).deleted_at=null;}, listDeleted(){return listings.filter(x=>x.deleted_at);},
|
|
permanentDelete(id){listings=listings.filter(x=>x.id!==Number(id));}, trashCount(){return this.listDeleted().length;},
|
|
duplicate(id){const row=this.get(id);return row?this.create({...row,id:undefined,title:`${row.title} (Kopie)`,deleted_at:null}):null;},
|
|
};
|
|
const ls=new ListingsService(listRepo);
|
|
expectThrow(()=>ls.validateCreate({platform:'ebay'}),'LISTING_INPUT_INVALID','Titelpflicht wurde nicht erzwungen');
|
|
expectThrow(()=>ls.validateCreate({title:'OK',hacker:true}),'LISTING_INPUT_INVALID','Unbekanntes Listingfeld wurde akzeptiert');
|
|
const cleaned=ls.validateCreate({title:'Test',description_html:'<script>alert(1)</script><p>Text</p>',tags:['a','b']});
|
|
assert(!cleaned.description_html.includes('<script'),'HTML-Sanitizer ließ Script durch');
|
|
expectThrow(()=>ls.permanentDelete(1),'LISTING_TRASH_NOT_FOUND','Aktiver Artikel konnte endgültig gelöscht werden');
|
|
assert(ls.permanentDelete(2).ok && !listRepo.get(2),'Papierkorbartikel wurde nicht endgültig gelöscht');
|
|
|
|
const inv=new InventoryService({locations(){return[]},unassigned(){return[]},byLocation(){return[]},bulkUpdateLocation(ids){return ids.length}});
|
|
expectThrow(()=>inv.validateBulk({ids:[1],location:'A',extra:true}),'INVENTORY_INPUT_INVALID','Unbekanntes Lagerfeld wurde akzeptiert');
|
|
expectThrow(()=>inv.validateBulk({ids:Array.from({length:501},(_,i)=>i+1),location:'A'}),'INVENTORY_BATCH_TOO_LARGE','Bulk-Limit wurde nicht erzwungen');
|
|
assert(inv.bulk({ids:[1,1,2],location:'Regal A'}).updated===2,'IDs wurden nicht dedupliziert');
|
|
|
|
const dir=mkdtempSync(join(tmpdir(),'vendoo-media-'));
|
|
try{
|
|
writeFileSync(join(dir,'free.jpg'),'x'); writeFileSync(join(dir,'used.jpg'),'x');
|
|
const removed=[];
|
|
const mediaRepo={list(){return[]},setFavorite(p,f){return{ok:true,image_path:p,favorite:f}},referenced(){return new Set(['used.jpg'])},removeRecords(paths){removed.push(...paths)}};
|
|
const media=new MediaService({uploadRoot:dir,sharp:null,repository:mediaRepo});
|
|
expectThrow(()=>media.validateDelete({image_paths:['../secret']}),'MEDIA_PATH_INVALID','Traversal-Pfad wurde akzeptiert');
|
|
expectThrow(()=>media.validateDelete({image_paths:['free.jpg'],extra:true}),null,'Unbekanntes Medienfeld wurde akzeptiert');
|
|
const result=media.delete({image_paths:['free.jpg','used.jpg']});
|
|
assert(result.deleted===1 && result.protected.includes('used.jpg'),'Referenzschutz liefert falsches Ergebnis');
|
|
assert(!existsSync(join(dir,'free.jpg')) && existsSync(join(dir,'used.jpg')),'Referenzschutz löschte falsche Datei');
|
|
assert(removed.length===1 && removed[0]==='free.jpg','Medienrecords wurden falsch bereinigt');
|
|
} finally { rmSync(dir,{recursive:true,force:true}); }
|
|
|
|
if(failures.length){console.error(`Catalog-Service-Regression 1.41.0 fehlgeschlagen (${failures.length}):`);failures.forEach(x=>console.error(`- ${x}`));process.exit(1)}
|
|
console.log('Catalog-Service-Regression 1.41.0 erfolgreich: Listing-Allowlist, HTML-Sanitizing, Papierkorbgrenze, Inventory-Bulk-Limit, Pfadschutz und Medienreferenzen geprüft.');
|