[object Object]

← back to Dw Photo Capture

Add end-to-end test for All-Shopify search + keep/replace photo paths (11/11 pass; throwaway draft, prod-clean teardown)

6a655b46c210ef9f37e6a89c9f60296bf3fe73f0 · 2026-06-24 18:14:34 -0700 · Steve

Files touched

Diff

commit 6a655b46c210ef9f37e6a89c9f60296bf3fe73f0
Author: Steve <steve@designerwallcoverings.com>
Date:   Wed Jun 24 18:14:34 2026 -0700

    Add end-to-end test for All-Shopify search + keep/replace photo paths (11/11 pass; throwaway draft, prod-clean teardown)
---
 test-allshopify.js | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/test-allshopify.js b/test-allshopify.js
index 0eeb0d1..00695e7 100644
--- a/test-allshopify.js
+++ b/test-allshopify.js
@@ -61,9 +61,16 @@ const ok  = (c, m) => { (c ? pass++ : fail++); console.log(`  ${c ? '✓' : '✗
   ok(await imgCount(pid) === 2, `seeded with 2 existing images`);
 
   try {
-    console.log(`\n── Test 1: live store-wide search finds it ──`);
-    const s = await srv('GET', '/api/shopify-search?q=' + encodeURIComponent(TAG));
-    const hit = (s.body.items || []).find(x => x.dw_sku === TAG);
+    console.log(`\n── Test 1: live store-wide search finds it (retry for index lag) ──`);
+    // Shopify product-search is eventually consistent — a just-created product needs
+    // a few seconds to enter the search index. Retry with backoff before asserting.
+    let s, hit, waited = 0;
+    for (let i = 0; i < 8; i++) {
+      s = await srv('GET', '/api/shopify-search?q=' + encodeURIComponent(TAG));
+      hit = (s.body.items || []).find(x => x.dw_sku === TAG);
+      if (hit) { console.log(`  (indexed after ~${waited}s)`); break; }
+      await new Promise(r => setTimeout(r, 5000)); waited += 5;
+    }
     ok(!!hit, `/api/shopify-search returns the product by SKU`);
     ok(hit && hit.keep_images === true, `result is stamped keep_images:true (non-destructive default)`);
     ok(hit && hit.scope === 'shopify', `result scope = "shopify"`);
@@ -82,12 +89,14 @@ const ok  = (c, m) => { (c ? pass++ : fail++); console.log(`  ${c ? '✓' : '✗
     console.log(`\n── Teardown: delete the throwaway product + local residue ──`);
     const del = await shopify('DELETE', `/products/${pid}.json`);
     ok(del.status >= 200 && del.status < 300, `test product deleted (HTTP ${del.status})`);
-    // scrub local progress.json + photo files written for the test sku
+    // scrub local photo files; the progress.json key is owned by the LIVE server's
+    // in-memory state, so an external file edit gets re-flushed until the server
+    // reloads — the harmless ZZTEST key clears on the next dwphoto restart.
     try {
       const PF = path.join(__dirname, 'data/progress.json'); const pr = JSON.parse(fs.readFileSync(PF, 'utf8'));
       if (pr[TAG]) { delete pr[TAG]; fs.writeFileSync(PF, JSON.stringify(pr, null, 2)); }
       for (const f of fs.readdirSync(path.join(__dirname, 'photos'))) if (f.startsWith(TAG)) fs.unlinkSync(path.join(__dirname, 'photos', f));
-      ok(true, `local progress + photo files scrubbed`);
+      ok(true, `photos scrubbed (progress key clears on next server restart — harmless, not in worklist)`);
     } catch (e) { ok(false, `cleanup error: ${e.message}`); }
   }
 

← 7e0a77d Add ✨ New (N) filter chip (just the net-new sheet SKUs to cr  ·  back to Dw Photo Capture  ·  auto-save: 2026-06-24T18:28:52 (1 files) — data/queue.json 62e3b37 →