@bongos/core 1.19.904 → 1.19.906

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -58,6 +58,17 @@ function makeEl(id) {
58
58
  }
59
59
 
60
60
  // `count` builders, each distinct enough that a filter lens has something to bite.
61
+ // The REAL role vocabulary, for the same reason this file runs the real kit rather than a
62
+ // stub: a stub of roleLabel() would agree with a roleLabel() that was wrong. dom-utils.js
63
+ // is pure enough to run against two small objects (tests/collab_page.mjs does the same).
64
+ function realRoleLabel() {
65
+ const src = read('modules/hall-ui/public/dom-utils.js');
66
+ const win = { location: { search: '', hash: '', pathname: '/' }, addEventListener() {}, localStorage: null };
67
+ const doc = { addEventListener() {}, querySelector: () => null, querySelectorAll: () => [], documentElement: { dataset: {} } };
68
+ new Function('window', 'document', src)(win, doc);
69
+ return win.OTB.roleLabel;
70
+ }
71
+
61
72
  function buildersFor(count) {
62
73
  return Array.from({ length: count }, (_, i) => ({
63
74
  github_id: 1000 + i,
@@ -105,7 +116,6 @@ function harness({ count }) {
105
116
  // task 1003936 — the role axis vocabulary (dom-utils OTB.role*). PRESENT for
106
117
  // the same reason categoryChip is: an undefined helper throws mid-render.
107
118
  roleAxisLabel: () => 'Role',
108
- roleLabel: (d) => (!d ? '' : d === 'unclassified' ? 'No role yet' : d === 'ui' ? 'UI' : d.charAt(0).toUpperCase() + d.slice(1)),
109
119
  roleOptions: () => [{ value: '', label: '— any —' }, { value: 'engineer', label: 'Engineer' }, { value: 'artist', label: 'Artist' }],
110
120
  roleIsUnset: (d) => !d || d === 'unclassified',
111
121
  ROLE_UNSET: 'unclassified',
@@ -116,6 +126,13 @@ function harness({ count }) {
116
126
  fmtCompact: (n) => String(Number(n) || 0),
117
127
  fmtDate: (iso) => String(iso ?? '').slice(0, 10),
118
128
  rankLabel: (r) => String(r ?? ''),
129
+ // The REAL one, replacing a hand-written reimplementation that used to sit here.
130
+ // Two reasons it had to go, and the second is the point of this file: it was a
131
+ // duplicate object key once the real helper arrived (no-dupe-keys, the later
132
+ // definition silently winning), and a stub that restates roleLabel's own logic
133
+ // can drift from it and the test would never notice — which is the argument this
134
+ // file already makes for running the real kit.
135
+ roleLabel: realRoleLabel(),
119
136
  toast() {},
120
137
  },
121
138
  };
@@ -162,6 +179,32 @@ await test('the page asks for exactly the ceiling, and asks for it ONCE', async
162
179
  assert.equal(limit, CEILING, `the page must ask for the route ceiling (${CEILING})`);
163
180
  });
164
181
 
182
+ // --- task 1004040 (artist review of 1003936): the Directory speaks the role --------
183
+
184
+ await test('the role vocabulary a Directory chip renders through says the word, not the column', () => {
185
+ // The 1003936 grade named this as a nit — craftsHtml() rendering the raw discipline
186
+ // instead of routing it through roleLabel() — and a nit is advisory, so it survived two
187
+ // more rounds. What a reader saw: lowercase 'engineer', 'ui' where the house writes
188
+ // 'UI', and, for a builder who has set no role, the database's own 'unclassified' —
189
+ // the example V2 names, in the exact place it names it ("a filter option and a row tag").
190
+ //
191
+ // The BEHAVIOUR is executed: this is the shipped roleLabel, not a stub of it.
192
+ const roleLabel = realRoleLabel();
193
+ assert.equal(roleLabel('engineer'), 'Engineer');
194
+ assert.equal(roleLabel('ui'), 'UI', 'the acronym keeps its case');
195
+ assert.equal(roleLabel('unclassified'), 'No role yet', 'a sentence a person would say');
196
+
197
+ // The CALL SITE is read, because it cannot be executed here: the harness's document
198
+ // fake returns a fresh detached node from querySelector(), so the kit fills a <tbody>
199
+ // that never reaches the markup this file can see. Observing a rendered row would mean
200
+ // deepening that fake, which is a change to a shared harness and not an artist review's
201
+ // business. Named in the session log rather than left as a silent gap.
202
+ const src = read('modules/hall-ui/public/people.js');
203
+ assert.match(src, /esc\(roleLabel\(d\)\)/, 'the chip routes through the role vocabulary');
204
+ assert.doesNotMatch(src, /'<span class="fact-chip">' \+ esc\(String\(d\)\)/,
205
+ 'the raw column must not be rendered as a chip');
206
+ });
207
+
165
208
  await test('a SHORT directory is not hedged — the exact count is the honest one', async () => {
166
209
  const h = harness({ count: 3 });
167
210
  await tick(); await tick();