bep40 commited on
Commit
efd2db0
·
verified ·
1 Parent(s): ebd3bee

test: pin the share-URL routing rule so avatarimg can never return to /share/p/

Browse files
Files changed (1) hide show
  1. scripts/test-avatar-interiors.mjs +71 -1
scripts/test-avatar-interiors.mjs CHANGED
@@ -5,10 +5,18 @@
5
  * still renders, it just renders at the wrong size or without the ring, and
6
  * nothing throws. These assert the geometry and the ordering, not just "no
7
  * crash".
 
 
 
 
 
 
 
8
  */
9
  import assert from 'node:assert/strict';
10
  import { mergeResults } from '../src/merge.js';
11
  import { foldText, searchAvatarInteriors } from '../src/avatar-interiors.js';
 
12
 
13
  let passed = 0, failed = 0;
14
  const test = (name, fn) => {
@@ -56,6 +64,68 @@ test('a query too short to be meaningful is rejected', () => {
56
  assert.equal(searchAvatarInteriors('a', items).length, 0);
57
  });
58
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  console.log('\nfeatured tiles');
60
  // ──────────────────────────────────────────────────────────────────────────
61
 
@@ -214,4 +284,4 @@ test('fewer than ten new photographs still all ring', () => {
214
  });
215
 
216
  console.log(`\n${passed} passed, ${failed} failed`);
217
- process.exit(failed ? 1 : 0);
 
5
  * still renders, it just renders at the wrong size or without the ring, and
6
  * nothing throws. These assert the geometry and the ordering, not just "no
7
  * crash".
8
+ *
9
+ * The share-URL block is here for the same reason, and it is deliberately
10
+ * Node-only. The browser copy of this rule lives in dist/assets/share-fix.js as
11
+ * a string regex, because it has to run against the served bundle before a
12
+ * rebuild; the routing decision itself lives in src/assets.js. These tests pin
13
+ * the src/ half so the two cannot drift apart silently, and the browser half is
14
+ * asserted separately in scripts/test-neon-ui.mjs.
15
  */
16
  import assert from 'node:assert/strict';
17
  import { mergeResults } from '../src/merge.js';
18
  import { foldText, searchAvatarInteriors } from '../src/avatar-interiors.js';
19
+ import { shareURL } from '../src/assets.js';
20
 
21
  let passed = 0, failed = 0;
22
  const test = (name, fn) => {
 
64
  assert.equal(searchAvatarInteriors('a', items).length, 0);
65
  });
66
 
67
+ console.log('\nshare URLs');
68
+ // ──────────────────────────────────────────────────────────────────────────
69
+
70
+ const STUDIO = 'https://bep40-vai-avatar.hf.space';
71
+ const broken = 'https://bep40-vai-avatar.hf.space/share/p/avatarimg%3Ab68dc779370dc70e';
72
+ const fixed = `${STUDIO}/share/i/b68dc779370dc70e`;
73
+
74
+ test('the reported broken URL is now the interior route', () => {
75
+ // The exact address from the report. `avatarimg:` is a namespace for
76
+ // de-duplication, not a catalogue identity, so /share/p/ resolved to nothing
77
+ // and vai-avatar answered "Not Found" for every interior photograph.
78
+ assert.equal(shareURL({ avatarImageId: 'b68dc779370dc70e', sku: 'avatarimg:b68dc779370dc70e' }), fixed);
79
+ });
80
+
81
+ test('the bug is reproducible against the old logic', () => {
82
+ // Pins what the fix is fixing, so the assertion above cannot pass for an
83
+ // unrelated reason. Without the avatarImageId branch, `sku` wins and the link
84
+ // is the dead one -- byte-identical to the reported URL.
85
+ const photo = { sku: 'avatarimg:b68dc779370dc70e' };
86
+ const oldRoute = `${STUDIO}/share/p/${encodeURIComponent(photo.sku)}`;
87
+ assert.equal(oldRoute, broken, 'the reported URL must be what the old routing produced');
88
+ assert.notEqual(shareURL(photo), oldRoute, 'shareURL still routes an avatarimg sku to /share/p/');
89
+ });
90
+
91
+ test('an interior is routed even when it has lost avatarImageId', () => {
92
+ // merge.js rewrites `id` into a namespaced tile key, so a record can arrive
93
+ // carrying the sku but not the original field. The prefix is unwrapped rather
94
+ // than treated as an identity, which is what this fallback exists for.
95
+ assert.equal(shareURL({ sku: 'avatarimg:b68dc779370dc70e' }), fixed);
96
+ });
97
+
98
+ test('an empty avatarimg prefix yields no share URL at all', () => {
99
+ // /share/i/ with nothing after it is its own 404. Returning null lets the
100
+ // caller omit the button rather than render a dead link.
101
+ assert.equal(shareURL({ sku: 'avatarimg:' }), null);
102
+ assert.equal(shareURL({ avatarImageId: ' ' }), null);
103
+ });
104
+
105
+ test('a real product still routes to /share/p/', () => {
106
+ // The fix must not disturb the route that works. A product keeps its slug, and
107
+ // /share/p/ resolves all three identity forms.
108
+ assert.equal(shareURL({ sku: 'MH800TC' }), `${STUDIO}/share/p/MH800TC`);
109
+ assert.equal(
110
+ shareURL({ sku: 'MH800TC', slug: 'mh800tc-malloca-may-hut-mui-gan-tu-am-tu-80cm' }),
111
+ `${STUDIO}/share/p/mh800tc-malloca-may-hut-mui-gan-tu-am-tu-80cm`,
112
+ 'the slug must still win over the sku',
113
+ );
114
+ });
115
+
116
+ test('a baked interior without a sku keeps its own route', () => {
117
+ // No sku at all: the id branch is what answers, and it must not be captured by
118
+ // the avatarimg fallback.
119
+ assert.equal(shareURL({ id: 'a1b2c3d4e5' }), `${STUDIO}/share/i/a1b2c3d4e5`);
120
+ });
121
+
122
+ test('a record with nothing to share returns null', () => {
123
+ assert.equal(shareURL(null), null);
124
+ assert.equal(shareURL(undefined), null);
125
+ assert.equal(shareURL({}), null);
126
+ assert.equal(shareURL('nope'), null);
127
+ });
128
+
129
  console.log('\nfeatured tiles');
130
  // ──────────────────────────────────────────────────────────────────────────
131
 
 
284
  });
285
 
286
  console.log(`\n${passed} passed, ${failed} failed`);
287
+ process.exit(failed ? 1 : 0);