Skip to content

Commit 33caae4

Browse files
committed
Test cleanup
1 parent 1a7d87d commit 33caae4

1 file changed

Lines changed: 228 additions & 37 deletions

File tree

test/admin-bar.js

Lines changed: 228 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,36 @@ describe('Admin bar', function () {
99
// EXISTENCE
1010
/// ///
1111

12-
it('should allow a group reversing the current order', async function () {
12+
it('should respect `last` and `after` options when no groups or order specified', async function () {
13+
let apos;
14+
try {
15+
apos = await t.create({
16+
root: module,
17+
modules: {
18+
'test-natural-options': {
19+
init(self) {
20+
self.apos.adminBar.add('normal-item', 'Normal Item', null);
21+
self.apos.adminBar.add('last-item', 'Last Item', null, { last: true });
22+
self.apos.adminBar.add('after-item', 'After Item', null, { after: 'normal-item' });
23+
}
24+
}
25+
// No groups or order - let last/after work naturally
26+
}
27+
});
28+
29+
const normalIndex = apos.adminBar.items.findIndex(item => item.name === 'normal-item');
30+
const afterIndex = apos.adminBar.items.findIndex(item => item.name === 'after-item');
31+
const lastIndex = apos.adminBar.items.findIndex(item => item.name === 'last-item');
32+
33+
// When no higher-priority options, last/after should work
34+
assert(afterIndex === normalIndex + 1, 'After item should immediately follow target');
35+
assert(lastIndex === apos.adminBar.items.length - 1, 'Last item should be at the end');
36+
} finally {
37+
t.destroy(apos);
38+
}
39+
});
40+
41+
it('should create groups with proper menuLeader assignment', async function () {
1342
let apos;
1443
try {
1544
apos = await t.create({
@@ -22,65 +51,224 @@ describe('Admin bar', function () {
2251
label: 'Media',
2352
items: [
2453
'@apostrophecms/image',
25-
'@apostrophecms/image-tag',
26-
'@apostrophecms/file',
27-
'@apostrophecms/file-tag'
28-
]
29-
},
30-
{
31-
label: 'Content',
32-
items: [
33-
'@apostrophecms/file',
34-
'@apostrophecms/image'
54+
'@apostrophecms/file'
3555
]
3656
}
3757
]
3858
}
3959
}
4060
}
4161
});
62+
4263
assert(apos.modules['@apostrophecms/admin-bar']);
4364
assert(apos.adminBar);
44-
assert.strictEqual(apos.adminBar.items.length, 7);
45-
assert(apos.adminBar.items[2].name === '@apostrophecms/file');
46-
assert(apos.adminBar.items[3].name === '@apostrophecms/image');
65+
66+
const imageItem = apos.adminBar.items.find(item => item.name === '@apostrophecms/image');
67+
const fileItem = apos.adminBar.items.find(item => item.name === '@apostrophecms/file');
68+
69+
// Both items should have the same menuLeader (the first item in the group)
70+
assert(imageItem.menuLeader === '@apostrophecms/image');
71+
assert(fileItem.menuLeader === '@apostrophecms/image');
72+
73+
// Group label should be stored
74+
assert(apos.adminBar.groupLabels['@apostrophecms/image'] === 'Media');
75+
76+
// Items should be consecutive
77+
const imageIndex = apos.adminBar.items.findIndex(item => item.name === '@apostrophecms/image');
78+
const fileIndex = apos.adminBar.items.findIndex(item => item.name === '@apostrophecms/file');
79+
assert(Math.abs(imageIndex - fileIndex) === 1);
4780
} finally {
4881
t.destroy(apos);
4982
}
5083
});
5184

52-
it('should allow a group obeying the current order', async function () {
85+
it('should handle duplicates in multi-item groups correctly', async function () {
5386
let apos;
87+
const warnings = [];
88+
5489
try {
5590
apos = await t.create({
91+
root: module,
5692
modules: {
5793
'@apostrophecms/admin-bar': {
5894
options: {
5995
addGroups: [
6096
{
61-
label: 'Media',
97+
label: 'Media Group',
6298
items: [
6399
'@apostrophecms/image',
64100
'@apostrophecms/file'
65101
]
66102
},
67103
{
68-
label: 'Content',
104+
label: 'Content Group',
69105
items: [
70-
'@apostrophecms/file',
71-
'@apostrophecms/image'
106+
'@apostrophecms/file', // Duplicate!
107+
'@apostrophecms/user',
108+
'@apostrophecms/image-tag'
72109
]
73110
}
74111
]
75112
}
76113
}
77114
}
78115
});
79-
assert(apos.modules['@apostrophecms/admin-bar']);
80-
assert(apos.adminBar);
81-
assert(apos.adminBar.items.length === 7);
82-
assert(apos.adminBar.items[1].name === '@apostrophecms/file');
83-
assert(apos.adminBar.items[2].name === '@apostrophecms/image');
116+
117+
// Mock warn function
118+
const originalWarn = apos.util.warn;
119+
apos.util.warn = (...args) => {
120+
warnings.push(args.join(' '));
121+
originalWarn.apply(apos.util, args);
122+
};
123+
124+
apos.adminBar.orderItems();
125+
apos.adminBar.groupItems();
126+
apos.util.warn = originalWarn;
127+
128+
// Should warn about duplicate
129+
const duplicateWarning = warnings.find(w =>
130+
w.includes('@apostrophecms/file') && w.includes('multiple groups')
131+
);
132+
assert(duplicateWarning, 'Should warn about duplicate item');
133+
134+
// File should be in first group only
135+
const fileItem = apos.adminBar.items.find(item => item.name === '@apostrophecms/file');
136+
assert(fileItem.menuLeader === '@apostrophecms/image', 'File should be in Media Group');
137+
138+
// Second group should still exist with user as leader (since file was skipped)
139+
const userItem = apos.adminBar.items.find(item => item.name === '@apostrophecms/user');
140+
const imageTagItem = apos.adminBar.items.find(item => item.name === '@apostrophecms/image-tag');
141+
142+
if (userItem && imageTagItem) {
143+
// Both remaining items should be grouped together
144+
assert(userItem.menuLeader === '@apostrophecms/user', 'User should be leader of Content Group');
145+
assert(imageTagItem.menuLeader === '@apostrophecms/user', 'Image-tag should be in Content Group');
146+
147+
// They should be consecutive
148+
const userIndex = apos.adminBar.items.findIndex(item => item.name === '@apostrophecms/user');
149+
const imageTagIndex = apos.adminBar.items.findIndex(item => item.name === '@apostrophecms/image-tag');
150+
assert(Math.abs(userIndex - imageTagIndex) === 1, 'Content Group items should be consecutive');
151+
}
152+
153+
} finally {
154+
t.destroy(apos);
155+
}
156+
});
157+
158+
it('should handle groups in registration order without explicit order', async function () {
159+
let apos;
160+
try {
161+
apos = await t.create({
162+
root: module,
163+
modules: {
164+
'@apostrophecms/admin-bar': {
165+
options: {
166+
addGroups: [
167+
{
168+
label: 'Alpha Group',
169+
items: ['@apostrophecms/image-tag', '@apostrophecms/file-tag']
170+
},
171+
{
172+
label: 'Beta Group',
173+
items: ['@apostrophecms/image', '@apostrophecms/file']
174+
}
175+
]
176+
}
177+
}
178+
}
179+
});
180+
181+
const iTagIndex = apos.adminBar.items.findIndex(item => item.name === '@apostrophecms/image-tag');
182+
const fTagIndex = apos.adminBar.items.findIndex(item => item.name === '@apostrophecms/file-tag');
183+
const imageIndex = apos.adminBar.items.findIndex(item => item.name === '@apostrophecms/image');
184+
const fileIndex = apos.adminBar.items.findIndex(item => item.name === '@apostrophecms/file');
185+
// Alpha group should come first in registration order
186+
assert(iTagIndex < imageIndex, 'First registered group should appear first');
187+
assert(fTagIndex < imageIndex, 'First registered group should appear first');
188+
189+
// Groups should be internally ordered and contiguous
190+
191+
assert(fTagIndex === iTagIndex + 1, 'First group should be contiguous');
192+
assert(fileIndex === imageIndex + 1, 'Second group should be contiguous');
193+
} finally {
194+
t.destroy(apos);
195+
}
196+
});
197+
198+
it('should prioritize groups over individual `last` and `after` options', async function () {
199+
let apos;
200+
try {
201+
apos = await t.create({
202+
root: module,
203+
modules: {
204+
'test-precedence': {
205+
init(self) {
206+
self.apos.adminBar.add('item-a', 'Item A', null);
207+
self.apos.adminBar.add('item-b', 'Item B', null, { last: true });
208+
self.apos.adminBar.add('item-c', 'Item C', null, { after: '@apostrophecms/user' });
209+
}
210+
},
211+
'@apostrophecms/admin-bar': {
212+
options: {
213+
addGroups: [
214+
{
215+
label: 'Test Group',
216+
items: ['item-a', 'item-b', 'item-c'] // All grouped despite last/after
217+
}
218+
]
219+
}
220+
}
221+
}
222+
});
223+
224+
const itemAIndex = apos.adminBar.items.findIndex(item => item.name === 'item-a');
225+
const itemBIndex = apos.adminBar.items.findIndex(item => item.name === 'item-b');
226+
const itemCIndex = apos.adminBar.items.findIndex(item => item.name === 'item-c');
227+
228+
// All items should be grouped together, ignoring last/after
229+
assert(Math.abs(itemAIndex - itemBIndex) <= 2, 'Items should be grouped despite last option');
230+
assert(Math.abs(itemAIndex - itemCIndex) <= 2, 'Items should be grouped despite after option');
231+
assert(Math.abs(itemBIndex - itemCIndex) <= 2, 'Items should be grouped despite individual options');
232+
233+
// All should have the same menuLeader
234+
assert(apos.adminBar.items[itemAIndex].menuLeader === 'item-a');
235+
assert(apos.adminBar.items[itemBIndex].menuLeader === 'item-a');
236+
assert(apos.adminBar.items[itemCIndex].menuLeader === 'item-a');
237+
} finally {
238+
t.destroy(apos);
239+
}
240+
});
241+
242+
it('should prioritize order array over individual `last` and `after` options', async function () {
243+
let apos;
244+
try {
245+
apos = await t.create({
246+
root: module,
247+
modules: {
248+
'test-order-precedence': {
249+
init(self) {
250+
self.apos.adminBar.add('item-x', 'Item X', null, { last: true });
251+
self.apos.adminBar.add('item-y', 'Item Y', null, { after: '@apostrophecms/file' });
252+
}
253+
},
254+
'@apostrophecms/admin-bar': {
255+
options: {
256+
order: ['item-x', '@apostrophecms/user', 'item-y', '@apostrophecms/image']
257+
}
258+
}
259+
}
260+
});
261+
262+
const itemXIndex = apos.adminBar.items.findIndex(item => item.name === 'item-x');
263+
const userIndex = apos.adminBar.items.findIndex(item => item.name === '@apostrophecms/user');
264+
const itemYIndex = apos.adminBar.items.findIndex(item => item.name === 'item-y');
265+
const imageIndex = apos.adminBar.items.findIndex(item => item.name === '@apostrophecms/image');
266+
267+
// Should follow order array, ignoring last/after
268+
assert(itemXIndex === 0, 'item-x should be first per order array, not last');
269+
assert(userIndex === 1, 'user should be second per order array');
270+
assert(itemYIndex === 2, 'item-y should be third per order array, not after file');
271+
assert(imageIndex === 3, 'image should be fourth per order array');
84272
} finally {
85273
t.destroy(apos);
86274
}
@@ -226,34 +414,36 @@ describe('Admin bar', function () {
226414
}
227415
});
228416

229-
it('should override last:true when item appears in order array', async function () {
417+
it('should prioritize order array over individual `last` and `after` options', async function () {
230418
let apos;
231419
try {
232420
apos = await t.create({
233421
root: module,
234422
modules: {
235-
'@apostrophecms/admin-bar': {
236-
options: {
237-
order: ['@apostrophecms/user', '@apostrophecms/image']
423+
'test-order-precedence': {
424+
init(self) {
425+
self.apos.adminBar.add('item-x', 'Item X', null, { last: true });
426+
self.apos.adminBar.add('item-y', 'Item Y', null, { after: '@apostrophecms/file' });
238427
}
239428
},
240-
'test-module': {
241-
init(self) {
242-
self.apos.adminBar.add('test-module', 'Test', null, { last: true });
429+
'@apostrophecms/admin-bar': {
430+
options: {
431+
order: ['item-x', '@apostrophecms/user', 'item-y', '@apostrophecms/image']
243432
}
244433
}
245434
}
246435
});
247436

437+
const itemXIndex = apos.adminBar.items.findIndex(item => item.name === 'item-x');
248438
const userIndex = apos.adminBar.items.findIndex(item => item.name === '@apostrophecms/user');
439+
const itemYIndex = apos.adminBar.items.findIndex(item => item.name === 'item-y');
249440
const imageIndex = apos.adminBar.items.findIndex(item => item.name === '@apostrophecms/image');
250-
const testIndex = apos.adminBar.items.findIndex(item => item.name === 'test-module');
251441

252-
// Even if image had last:true, it should respect order position
253-
assert(userIndex === 0);
254-
assert(imageIndex === 1);
255-
// test-module should still be last since it's not in order
256-
assert(testIndex === apos.adminBar.items.length - 1);
442+
// Should follow order array, ignoring last/after
443+
assert(itemXIndex === 0, 'item-x should be first per order array, not last');
444+
assert(userIndex === 1, 'user should be second per order array');
445+
assert(itemYIndex === 2, 'item-y should be third per order array, not after file');
446+
assert(imageIndex === 3, 'image should be fourth per order array');
257447
} finally {
258448
t.destroy(apos);
259449
}
@@ -385,4 +575,5 @@ describe('Admin bar', function () {
385575
t.destroy(apos);
386576
}
387577
});
578+
388579
});

0 commit comments

Comments
 (0)