@eventcatalog/core 4.11.0 → 4.11.1
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.
- package/dist/analytics/analytics.cjs +1 -1
- package/dist/analytics/analytics.js +2 -2
- package/dist/analytics/log-build.cjs +1 -1
- package/dist/analytics/log-build.js +3 -3
- package/dist/astro-output.cjs +60 -1
- package/dist/astro-output.js +1 -1
- package/dist/{chunk-U52FCZQ6.js → chunk-2YJRF4ZX.js} +1 -1
- package/dist/chunk-634NFV5U.js +75 -0
- package/dist/{chunk-SW7SJZIX.js → chunk-AXDNSGAN.js} +1 -1
- package/dist/chunk-DHH5U5PF.js +53 -0
- package/dist/{chunk-H3324DNT.js → chunk-DSCIWCX2.js} +1 -1
- package/dist/chunk-FWXEV4LF.js +19 -0
- package/dist/{chunk-XJOKK5ZO.js → chunk-GZVDXCYF.js} +1 -1
- package/dist/{chunk-W4LDIMUI.js → chunk-RYNPEIHQ.js} +1 -1
- package/dist/{chunk-DWC5GRFX.js → chunk-YYVW4DCO.js} +1 -1
- package/dist/constants.cjs +1 -1
- package/dist/constants.js +1 -1
- package/dist/copy-core.cjs +88 -0
- package/dist/copy-core.d.cts +4 -0
- package/dist/copy-core.d.ts +4 -0
- package/dist/copy-core.js +8 -0
- package/dist/eventcatalog.cjs +234 -115
- package/dist/eventcatalog.js +36 -30
- package/dist/federation/federate.js +3 -3
- package/dist/federation/source-provider.js +2 -2
- package/dist/generate.cjs +1 -1
- package/dist/generate.js +3 -3
- package/dist/update-check.cjs +44 -0
- package/dist/update-check.d.cts +18 -0
- package/dist/update-check.d.ts +18 -0
- package/dist/update-check.js +8 -0
- package/dist/utils/cli-logger.cjs +1 -1
- package/dist/utils/cli-logger.js +2 -2
- package/eventcatalog/astro.config.mjs +6 -0
- package/eventcatalog/src/plugins/empty-collection-warning.d.ts +21 -0
- package/eventcatalog/src/plugins/empty-collection-warning.mjs +107 -0
- package/eventcatalog/src/plugins/quiet-empty-collections-logger.mjs +11 -0
- package/eventcatalog/src/utils/collections/channels.ts +12 -4
- package/eventcatalog/src/utils/node-graphs/message-node-graph.ts +17 -15
- package/package.json +2 -1
- package/dist/chunk-RDYYZQYU.js +0 -18
- package/eventcatalog/src/components/EnvironmentDropdown.test.ts +0 -64
- package/eventcatalog/src/components/Grids/message-link.spec.ts +0 -59
- package/eventcatalog/src/components/MDX/CodeGroup/code-group.spec.tsx +0 -89
- package/eventcatalog/src/components/MDX/Columns/columns.spec.tsx +0 -66
- package/eventcatalog/src/components/MDX/CustomProperties/custom-properties.spec.ts +0 -38
- package/eventcatalog/src/components/MDX/SchemaViewer/schema-viewer-utils.spec.ts +0 -116
- package/eventcatalog/src/components/SchemaExplorer/JSONSchemaViewer.test.tsx +0 -114
- package/eventcatalog/src/components/SchemaExplorer/ProtobufSchemaViewer.test.tsx +0 -91
- package/eventcatalog/src/components/SchemaExplorer/SchemaViewerHover.test.tsx +0 -33
- package/eventcatalog/src/components/SchemaExplorer/protobuf-validation.test.ts +0 -84
- package/eventcatalog/src/components/Search/search-utils.spec.ts +0 -173
- package/eventcatalog/src/components/SideNav/NestedSideBar/utils.spec.ts +0 -105
- package/eventcatalog/src/components/navigation-progress.spec.ts +0 -68
- package/eventcatalog/src/enterprise/directory/user-team-directory.spec.ts +0 -527
- package/eventcatalog/src/enterprise/fields/field-extractor.test.ts +0 -302
- package/eventcatalog/src/enterprise/fields/fields-db.test.ts +0 -185
- package/eventcatalog/src/stores/eventcatalog-store.spec.ts +0 -60
- package/eventcatalog/src/utils/collections/glob-loader.spec.ts +0 -87
- package/dist/{chunk-6K7XZAYI.js → chunk-A2RZR3U4.js} +3 -3
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import type { ProtobufField } from '@utils/protobuf-schema';
|
|
3
|
-
import {
|
|
4
|
-
formatProtobufOptionValue,
|
|
5
|
-
formatProtovalidateRule,
|
|
6
|
-
getCustomFieldAnnotations,
|
|
7
|
-
getProtovalidateRules,
|
|
8
|
-
isProtovalidateRequired,
|
|
9
|
-
} from './protobuf-validation';
|
|
10
|
-
|
|
11
|
-
describe('protobuf validation helpers', () => {
|
|
12
|
-
it('flattens direct and aggregate Protovalidate options', () => {
|
|
13
|
-
const field: ProtobufField = {
|
|
14
|
-
name: 'status',
|
|
15
|
-
type: 'Status',
|
|
16
|
-
options: [
|
|
17
|
-
{ name: '(buf.validate.field).required', value: true },
|
|
18
|
-
{
|
|
19
|
-
name: '(buf.validate.field).enum',
|
|
20
|
-
value: { defined_only: true, not_in: [0] },
|
|
21
|
-
},
|
|
22
|
-
],
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
expect(getProtovalidateRules(field)).toEqual([
|
|
26
|
-
{ path: 'required', value: true },
|
|
27
|
-
{ path: 'enum.defined_only', value: true },
|
|
28
|
-
{ path: 'enum.not_in', value: [0] },
|
|
29
|
-
]);
|
|
30
|
-
expect(isProtovalidateRequired(field)).toBe(true);
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
it('ignores non-Protovalidate custom options', () => {
|
|
34
|
-
const field: ProtobufField = {
|
|
35
|
-
name: 'description',
|
|
36
|
-
type: 'string',
|
|
37
|
-
options: [{ name: '(datahub.v1.gdpr_rule).string', value: true }],
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
expect(getProtovalidateRules(field)).toEqual([]);
|
|
41
|
-
expect(isProtovalidateRequired(field)).toBe(false);
|
|
42
|
-
expect(getCustomFieldAnnotations(field)).toEqual([{ name: '(datahub.v1.gdpr_rule).string', value: true }]);
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it('only treats extension options as custom annotations and formats aggregate values', () => {
|
|
46
|
-
const field: ProtobufField = {
|
|
47
|
-
name: 'description',
|
|
48
|
-
type: 'string',
|
|
49
|
-
options: [
|
|
50
|
-
{ name: 'deprecated', value: true },
|
|
51
|
-
{ name: '(buf.validate.field).string.min_len', value: 1 },
|
|
52
|
-
{ name: '(datahub.v1.classification)', value: { level: 'personal', encrypted: true } },
|
|
53
|
-
],
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
expect(getCustomFieldAnnotations(field)).toEqual([
|
|
57
|
-
{
|
|
58
|
-
name: '(datahub.v1.classification)',
|
|
59
|
-
value: { level: 'personal', encrypted: true },
|
|
60
|
-
},
|
|
61
|
-
]);
|
|
62
|
-
expect(formatProtobufOptionValue(getCustomFieldAnnotations(field)[0].value)).toBe('{"level":"personal","encrypted":true}');
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it('formats common rules for display', () => {
|
|
66
|
-
expect(formatProtovalidateRule({ path: 'string.email', value: true })).toEqual({ label: 'Format', value: 'Email' });
|
|
67
|
-
expect(formatProtovalidateRule({ path: 'uint32.gte', value: 1 })).toEqual({ label: 'Minimum', value: '1' });
|
|
68
|
-
expect(formatProtovalidateRule({ path: 'enum.defined_only', value: true })).toEqual({
|
|
69
|
-
label: 'Defined enum values only',
|
|
70
|
-
});
|
|
71
|
-
expect(formatProtovalidateRule({ path: 'enum.not_in', value: [0] })).toEqual({
|
|
72
|
-
label: 'Excluded values',
|
|
73
|
-
value: '0',
|
|
74
|
-
});
|
|
75
|
-
expect(formatProtovalidateRule({ path: 'repeated.items.string.min_len', value: 3 })).toEqual({
|
|
76
|
-
label: 'Item minimum length',
|
|
77
|
-
value: '3',
|
|
78
|
-
});
|
|
79
|
-
expect(formatProtovalidateRule({ path: 'map.values.string.max_len', value: 100 })).toEqual({
|
|
80
|
-
label: 'Value maximum length',
|
|
81
|
-
value: '100',
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
});
|
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it, beforeEach } from 'vitest';
|
|
2
|
-
import {
|
|
3
|
-
applyActiveFilter,
|
|
4
|
-
getIndexedResultRank,
|
|
5
|
-
getSearchFilters,
|
|
6
|
-
getUrlForSearchItem,
|
|
7
|
-
hasMeaningfulIndexedMatch,
|
|
8
|
-
highlightQuery,
|
|
9
|
-
mapPagefindResultsToSearchItems,
|
|
10
|
-
normalizeResultUrl,
|
|
11
|
-
} from './search-utils';
|
|
12
|
-
|
|
13
|
-
declare global {
|
|
14
|
-
interface Window {
|
|
15
|
-
__EC_TRAILING_SLASH__: boolean;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
describe('getUrlForSearchItem', () => {
|
|
20
|
-
beforeEach(() => {
|
|
21
|
-
// @ts-ignore
|
|
22
|
-
global.__EC_TRAILING_SLASH__ = false;
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it.each([
|
|
26
|
-
['container:OrdersDatabase:1.0.0', '/docs/containers/OrdersDatabase/1.0.0'],
|
|
27
|
-
['data-product:Customer360:1.0.0', '/docs/data-products/Customer360/1.0.0'],
|
|
28
|
-
['entity:Order:1.0.0', '/docs/entities/Order/1.0.0'],
|
|
29
|
-
['flow:CheckoutFlow:1.0.0', '/docs/flows/CheckoutFlow/1.0.0'],
|
|
30
|
-
])('builds a docs URL for %s', (key, expected) => {
|
|
31
|
-
expect(getUrlForSearchItem({}, key)).toBe(expected);
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it('uses the explicit node href when provided', () => {
|
|
35
|
-
expect(getUrlForSearchItem({ href: '/custom/search-result' }, 'data-product:Customer360:1.0.0')).toBe(
|
|
36
|
-
'/custom/search-result'
|
|
37
|
-
);
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it('skips aliases and unsupported keys', () => {
|
|
41
|
-
expect(getUrlForSearchItem({}, 'data-product:Customer360')).toBeNull();
|
|
42
|
-
expect(getUrlForSearchItem({}, 'list:data-products')).toBeNull();
|
|
43
|
-
expect(getUrlForSearchItem({}, 'unknown:Customer360:1.0.0')).toBeNull();
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
describe('indexed search result helpers', () => {
|
|
48
|
-
it('filters weak single-character highlighted matches for longer queries', () => {
|
|
49
|
-
expect(
|
|
50
|
-
hasMeaningfulIndexedMatch({
|
|
51
|
-
query: 'random',
|
|
52
|
-
title: 'Orders Service',
|
|
53
|
-
content: 'Order Metadata in api service server logs',
|
|
54
|
-
excerpt: 'Order Metadata in api db L -- <mark>R</mark> server',
|
|
55
|
-
})
|
|
56
|
-
).toBe(false);
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it('keeps short but meaningful marked terms', () => {
|
|
60
|
-
expect(
|
|
61
|
-
hasMeaningfulIndexedMatch({
|
|
62
|
-
query: 'db',
|
|
63
|
-
title: 'Orders Service',
|
|
64
|
-
content: 'Order Metadata in api service server logs',
|
|
65
|
-
excerpt: 'Order Metadata in api <mark>db</mark>',
|
|
66
|
-
})
|
|
67
|
-
).toBe(true);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it('keeps exact title or content matches even without marked excerpts', () => {
|
|
71
|
-
expect(
|
|
72
|
-
hasMeaningfulIndexedMatch({
|
|
73
|
-
query: 'payments',
|
|
74
|
-
title: 'Payments Database',
|
|
75
|
-
content: '',
|
|
76
|
-
excerpt: '',
|
|
77
|
-
})
|
|
78
|
-
).toBe(true);
|
|
79
|
-
|
|
80
|
-
expect(
|
|
81
|
-
hasMeaningfulIndexedMatch({
|
|
82
|
-
query: 'idempotency',
|
|
83
|
-
title: 'Payments Database',
|
|
84
|
-
content: 'Always include an idempotency key in payment creation.',
|
|
85
|
-
excerpt: '',
|
|
86
|
-
})
|
|
87
|
-
).toBe(true);
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
it('normalizes Pagefind URLs to root-relative paths', () => {
|
|
91
|
-
expect(normalizeResultUrl('docs/containers/payments-db/0.0.1')).toBe('/docs/containers/payments-db/0.0.1');
|
|
92
|
-
expect(normalizeResultUrl('/docs/containers/payments-db/0.0.1')).toBe('/docs/containers/payments-db/0.0.1');
|
|
93
|
-
expect(normalizeResultUrl('https://example.com/docs')).toBe('https://example.com/docs');
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
it('highlights title matches while escaping unsafe title text', () => {
|
|
97
|
-
expect(highlightQuery('Payment <Service>', 'payment')).toBe('<mark>Payment</mark> <Service>');
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
it('ranks title matches above id/url matches and content matches', () => {
|
|
101
|
-
const query = 'payment';
|
|
102
|
-
const contentRank = getIndexedResultRank({
|
|
103
|
-
query,
|
|
104
|
-
title: 'Orders Service',
|
|
105
|
-
url: '/docs/services/OrdersService/1.0.0',
|
|
106
|
-
content: 'Handles payment retries',
|
|
107
|
-
});
|
|
108
|
-
const urlRank = getIndexedResultRank({
|
|
109
|
-
query,
|
|
110
|
-
title: 'Orders Service',
|
|
111
|
-
url: '/docs/services/PaymentService/1.0.0',
|
|
112
|
-
content: 'Handles orders',
|
|
113
|
-
});
|
|
114
|
-
const titleRank = getIndexedResultRank({
|
|
115
|
-
query,
|
|
116
|
-
title: 'Payment Service',
|
|
117
|
-
url: '/docs/services/PaymentService/1.0.0',
|
|
118
|
-
content: 'Handles orders',
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
expect(titleRank).toBeGreaterThan(urlRank);
|
|
122
|
-
expect(urlRank).toBeGreaterThan(contentRank);
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
it('applies grouped search filters', () => {
|
|
126
|
-
const items = [{ type: 'Event' }, { type: 'Command' }, { type: 'Team' }, { type: 'User' }, { type: 'Service' }];
|
|
127
|
-
|
|
128
|
-
expect(applyActiveFilter(items, 'Message')).toEqual([{ type: 'Event' }, { type: 'Command' }]);
|
|
129
|
-
expect(applyActiveFilter(items, 'Team')).toEqual([{ type: 'Team' }, { type: 'User' }]);
|
|
130
|
-
expect(applyActiveFilter(items, 'Service')).toEqual([{ type: 'Service' }]);
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
it('builds filter metadata without encoding behavior in labels', () => {
|
|
134
|
-
expect(getSearchFilters({ items: [], query: 'missing' })).toEqual([{ id: 'all', name: 'All (0)', count: 0 }]);
|
|
135
|
-
expect(getSearchFilters({ items: [{ type: 'Event' }, { type: 'Service' }], query: 'order' })).toEqual([
|
|
136
|
-
{ id: 'all', name: 'All (2)', count: 2 },
|
|
137
|
-
{ id: 'Service', name: 'Services (1)', count: 1 },
|
|
138
|
-
{ id: 'Message', name: 'Messages (1)', count: 1 },
|
|
139
|
-
]);
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
it('maps Pagefind results into ranked search items', async () => {
|
|
143
|
-
const items = await mapPagefindResultsToSearchItems({
|
|
144
|
-
query: 'payment',
|
|
145
|
-
limit: 10,
|
|
146
|
-
results: [
|
|
147
|
-
{
|
|
148
|
-
id: 'content',
|
|
149
|
-
score: 10,
|
|
150
|
-
data: async () => ({
|
|
151
|
-
url: 'docs/services/OrdersService/1.0.0',
|
|
152
|
-
content: 'Handles payment retries',
|
|
153
|
-
excerpt: 'Handles <mark>payment</mark> retries',
|
|
154
|
-
meta: { title: 'Orders Service', type: 'Service', id: 'OrdersService' },
|
|
155
|
-
}),
|
|
156
|
-
},
|
|
157
|
-
{
|
|
158
|
-
id: 'title',
|
|
159
|
-
score: 1,
|
|
160
|
-
data: async () => ({
|
|
161
|
-
url: 'docs/services/PaymentService/1.0.0',
|
|
162
|
-
content: 'Handles orders',
|
|
163
|
-
excerpt: '<mark>Payment</mark> service',
|
|
164
|
-
meta: { title: 'Payment Service', type: 'Service', id: 'PaymentService' },
|
|
165
|
-
}),
|
|
166
|
-
},
|
|
167
|
-
],
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
expect(items.map((item) => item.id)).toEqual(['title', 'content']);
|
|
171
|
-
expect(items[0].url).toBe('/docs/services/PaymentService/1.0.0');
|
|
172
|
-
});
|
|
173
|
-
});
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import {
|
|
3
|
-
canCollapseGroup,
|
|
4
|
-
createSectionCollapsePreferences,
|
|
5
|
-
findNodeKeyByUrl,
|
|
6
|
-
getDefaultCollapsedState,
|
|
7
|
-
isGroupCollapsed,
|
|
8
|
-
toggleGroupCollapsed,
|
|
9
|
-
} from './utils';
|
|
10
|
-
|
|
11
|
-
const preferences = (expanded: string[] = [], collapsed: string[] = []) => createSectionCollapsePreferences(expanded, collapsed);
|
|
12
|
-
|
|
13
|
-
describe('sidebar group presentation', () => {
|
|
14
|
-
it('keeps root-level groups expanded', () => {
|
|
15
|
-
expect(canCollapseGroup(true)).toBe(false);
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
it('lets every group inside a resource sidebar collapse, whatever its size', () => {
|
|
19
|
-
expect(canCollapseGroup(false)).toBe(true);
|
|
20
|
-
expect(canCollapseGroup(false)).toBe(true);
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
it('keeps groups marked as non-collapsible expanded regardless of their size', () => {
|
|
24
|
-
expect(canCollapseGroup(false, false)).toBe(false);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
it('starts long lists collapsed and short ones open unless told otherwise', () => {
|
|
28
|
-
expect(getDefaultCollapsedState(5)).toBe(false);
|
|
29
|
-
expect(getDefaultCollapsedState(6)).toBe(true);
|
|
30
|
-
expect(getDefaultCollapsedState(6, false)).toBe(false);
|
|
31
|
-
expect(getDefaultCollapsedState(2, true)).toBe(true);
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it('always allows collapsing when an explicit collapsed state is set, overriding every other rule', () => {
|
|
35
|
-
expect(canCollapseGroup(false, true, true)).toBe(true);
|
|
36
|
-
expect(canCollapseGroup(false, true, false)).toBe(true);
|
|
37
|
-
expect(canCollapseGroup(true, false, true)).toBe(true);
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
describe('isGroupCollapsed', () => {
|
|
42
|
-
it('keeps groups without a caret expanded', () => {
|
|
43
|
-
expect(isGroupCollapsed(false, 'group-1', preferences())).toBe(false);
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it('collapses expandable groups by default', () => {
|
|
47
|
-
expect(isGroupCollapsed(true, 'outbound-messages', preferences())).toBe(true);
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it('uses an explicit expanded preference', () => {
|
|
51
|
-
expect(isGroupCollapsed(true, 'outbound-messages', preferences(['outbound-messages']))).toBe(false);
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it('starts expanded when the group defaults to expanded, until the user collapses it', () => {
|
|
55
|
-
expect(isGroupCollapsed(true, 'owners', preferences(), false)).toBe(false);
|
|
56
|
-
expect(isGroupCollapsed(true, 'owners', preferences([], ['owners']), false)).toBe(true);
|
|
57
|
-
});
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
describe('toggleGroupCollapsed', () => {
|
|
61
|
-
it('records the user overriding a collapsed-by-default group, then clears it on the way back', () => {
|
|
62
|
-
const opened = toggleGroupCollapsed('g', preferences());
|
|
63
|
-
expect([...opened.expanded]).toEqual(['g']);
|
|
64
|
-
expect(opened.collapsed.size).toBe(0);
|
|
65
|
-
|
|
66
|
-
const closedAgain = toggleGroupCollapsed('g', opened);
|
|
67
|
-
expect(closedAgain.expanded.size).toBe(0);
|
|
68
|
-
expect([...closedAgain.collapsed]).toEqual(['g']);
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
it('records the user overriding an expanded-by-default group', () => {
|
|
72
|
-
const closed = toggleGroupCollapsed('g', preferences(), false);
|
|
73
|
-
expect([...closed.collapsed]).toEqual(['g']);
|
|
74
|
-
expect(isGroupCollapsed(true, 'g', closed, false)).toBe(true);
|
|
75
|
-
|
|
76
|
-
const reopened = toggleGroupCollapsed('g', closed, false);
|
|
77
|
-
expect(reopened.collapsed.size).toBe(0);
|
|
78
|
-
expect([...reopened.expanded]).toEqual(['g']);
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
it('does not mutate the previous preferences', () => {
|
|
82
|
-
const before = preferences();
|
|
83
|
-
toggleGroupCollapsed('g', before);
|
|
84
|
-
expect(before.expanded.size).toBe(0);
|
|
85
|
-
expect(before.collapsed.size).toBe(0);
|
|
86
|
-
});
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
describe('findNodeKeyByUrl', () => {
|
|
90
|
-
const channelKey = 'channel:product-events:1.0.0';
|
|
91
|
-
const nodes = { [channelKey]: {} };
|
|
92
|
-
const nodeLookup = new Map([['channel:product-events', channelKey]]);
|
|
93
|
-
|
|
94
|
-
it('selects the channel sidebar for channel documentation', () => {
|
|
95
|
-
expect(findNodeKeyByUrl('/docs/channels/product-events/1.0.0', nodes, nodeLookup)).toBe(channelKey);
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
it('keeps the channel sidebar selected on the channel map', () => {
|
|
99
|
-
expect(findNodeKeyByUrl('/visualiser/channels/product-events/1.0.0', nodes, nodeLookup)).toBe(channelKey);
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
it('falls back to the available channel version', () => {
|
|
103
|
-
expect(findNodeKeyByUrl('/docs/channels/product-events/latest', nodes, nodeLookup)).toBe(channelKey);
|
|
104
|
-
});
|
|
105
|
-
});
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
// @vitest-environment jsdom
|
|
2
|
-
|
|
3
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
4
|
-
import { initializeNavigationProgress } from './navigation-progress';
|
|
5
|
-
|
|
6
|
-
const dispatchNavigationEvent = (name: string, sourceElement?: HTMLElement) => {
|
|
7
|
-
const event = new Event(name) as Event & { sourceElement?: HTMLElement };
|
|
8
|
-
event.sourceElement = sourceElement;
|
|
9
|
-
document.dispatchEvent(event);
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
describe('navigation progress', () => {
|
|
13
|
-
let cleanup: () => void;
|
|
14
|
-
|
|
15
|
-
beforeEach(() => {
|
|
16
|
-
vi.useFakeTimers();
|
|
17
|
-
document.body.innerHTML = `
|
|
18
|
-
<a id="navigation-link" href="/next">Next page</a>
|
|
19
|
-
<div id="navigation-progress" data-visible="false" aria-hidden="true"></div>
|
|
20
|
-
<span id="navigation-progress-status"></span>
|
|
21
|
-
<main id="content"></main>
|
|
22
|
-
`;
|
|
23
|
-
cleanup = initializeNavigationProgress();
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
afterEach(() => {
|
|
27
|
-
cleanup();
|
|
28
|
-
vi.useRealTimers();
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it('does not show the indicator for fast navigations', () => {
|
|
32
|
-
const link = document.getElementById('navigation-link')!;
|
|
33
|
-
|
|
34
|
-
dispatchNavigationEvent('astro:before-preparation', link);
|
|
35
|
-
vi.advanceTimersByTime(199);
|
|
36
|
-
dispatchNavigationEvent('astro:after-preparation');
|
|
37
|
-
vi.runAllTimers();
|
|
38
|
-
|
|
39
|
-
expect(document.getElementById('navigation-progress')?.dataset.visible).toBe('false');
|
|
40
|
-
expect(link.hasAttribute('aria-busy')).toBe(false);
|
|
41
|
-
expect(document.getElementById('content')?.hasAttribute('aria-busy')).toBe(false);
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it('shows accessible pending state during slow navigations', () => {
|
|
45
|
-
const link = document.getElementById('navigation-link')!;
|
|
46
|
-
|
|
47
|
-
dispatchNavigationEvent('astro:before-preparation', link);
|
|
48
|
-
expect(link.getAttribute('aria-busy')).toBe('true');
|
|
49
|
-
expect(link.dataset.navigationPending).toBe('true');
|
|
50
|
-
|
|
51
|
-
vi.advanceTimersByTime(200);
|
|
52
|
-
|
|
53
|
-
expect(document.getElementById('navigation-progress')?.dataset.visible).toBe('true');
|
|
54
|
-
expect(document.getElementById('navigation-progress')?.getAttribute('aria-hidden')).toBe('false');
|
|
55
|
-
expect(document.getElementById('content')?.getAttribute('aria-busy')).toBe('true');
|
|
56
|
-
expect(document.getElementById('navigation-progress-status')?.textContent).toBe('Loading page');
|
|
57
|
-
|
|
58
|
-
dispatchNavigationEvent('astro:after-preparation');
|
|
59
|
-
vi.advanceTimersByTime(249);
|
|
60
|
-
expect(document.getElementById('navigation-progress')?.dataset.visible).toBe('true');
|
|
61
|
-
|
|
62
|
-
vi.advanceTimersByTime(1);
|
|
63
|
-
expect(document.getElementById('navigation-progress')?.dataset.visible).toBe('false');
|
|
64
|
-
expect(link.hasAttribute('data-navigation-pending')).toBe(false);
|
|
65
|
-
expect(document.getElementById('content')?.hasAttribute('aria-busy')).toBe(false);
|
|
66
|
-
expect(document.getElementById('navigation-progress-status')?.textContent).toBe('');
|
|
67
|
-
});
|
|
68
|
-
});
|