research-enrichment.test.mjs 2.5 KB

12345678910111213141516171819202122232425262728293031323334
  1. import test from 'node:test';
  2. import assert from 'node:assert/strict';
  3. import {checkPublication,unwrap,needsProductEnrichment,checkHistoricalPlan} from '../scripts/lib/research-enrichment.mjs';
  4. const receipt={archiveSha256:'a'.repeat(64)};
  5. const result=()=>({ok:true,applied:true,allRowsVerified:true,archiveSha256:receipt.archiveSha256,dataset:'research',businessRowsChanged:0,
  6. sourceArchivePreserved:true,delta:{changed:{},mergeReview:{conflictRecords:0}}});
  7. test('a successful HTTP wrapper cannot hide an unverified publication',()=>{
  8. assert.equal(unwrap({body:{result:{ok:false,error:'REJECTED'}}}).ok,false);
  9. assert.throws(()=>checkPublication({...result(),allRowsVerified:false},receipt),/PUBLICATION_NOT_VERIFIED/);
  10. assert.throws(()=>checkPublication({...result(),archiveSha256:'b'.repeat(64)},receipt),/PUBLICATION_NOT_VERIFIED/);
  11. });
  12. test('research enrichment rejects business writes and unexpected field changes',()=>{
  13. assert.doesNotThrow(()=>checkPublication(result(),receipt));
  14. assert.throws(()=>checkPublication({...result(),businessRowsChanged:1},receipt),/PUBLICATION_NOT_VERIFIED/);
  15. assert.throws(()=>checkPublication({...result(),delta:{changed:{reviews:1}}},receipt),/UNEXPECTED_CHANGES/);
  16. assert.throws(()=>checkPublication({...result(),delta:{mergeReview:{conflictRecords:1}}},receipt),/UNEXPECTED_CHANGES/);
  17. });
  18. test('publishing historical specifications cannot hide still-missing reviews',()=>{
  19. const product={missingReviews:true,missingVerifiedSpec:true,missingPrice:false};
  20. assert.equal(needsProductEnrichment(product,{specs:1,reviews:0,prices:0}),true);
  21. assert.equal(needsProductEnrichment(product,{specs:1,reviews:10,prices:0}),false);
  22. assert.equal(needsProductEnrichment({...product,missingPrice:true},{specs:1,reviews:10,prices:0}),true);
  23. assert.equal(needsProductEnrichment(product,undefined),true);
  24. });
  25. test('historical archive publication rejects count drift, overwritten facts and new products',()=>{
  26. const receipt={expectedProductionAddedSpecs:160,expectedProductionAddedReviews:0};
  27. const plan={ok:true,mergePlan:{ok:true,dataset:'research',businessRowsChanged:0,delta:{added:{specs:160},changed:{},mergeReview:{conflictRecords:0}}}};
  28. assert.doesNotThrow(()=>checkHistoricalPlan(plan,receipt));
  29. for(const delta of [{added:{specs:320}},{added:{specs:160,products:1}},{added:{specs:160,prices:1}},
  30. {added:{specs:160},changed:{products:1}},{added:{specs:160},mergeReview:{conflictRecords:1}}]){
  31. assert.throws(()=>checkHistoricalPlan({...plan,mergePlan:{...plan.mergePlan,delta}},receipt),/REQUIRES_REVIEW/);
  32. }
  33. });