-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Expand file tree
/
Copy pathcheck-application-graph.test.ts
More file actions
158 lines (142 loc) · 5.79 KB
/
Copy pathcheck-application-graph.test.ts
File metadata and controls
158 lines (142 loc) · 5.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
import { describe, expect, it } from 'vitest'
import {
deferredSpecifiers,
FORBIDDEN_PREFIXES,
findViolations,
GUARDED_ROOTS,
resolveSpecifier,
runtimeSpecifiers,
} from './check-application-graph'
describe('runtimeSpecifiers', () => {
it('collects import and re-export specifiers', () => {
expect(
runtimeSpecifiers(
"import { a } from '@/lib/a'\nexport { b } from '@/lib/b'\nimport '@/lib/c'\n"
)
).toEqual(['@/lib/a', '@/lib/b', '@/lib/c'])
})
/**
* The heaviest edge of all — the module is loaded purely to run — and the one
* nothing in the importing file names, so it was walked straight past.
*/
it('collects a side-effect import, in source order', () => {
expect(
runtimeSpecifiers("import '@/lib/uploads/core/setup.server'\nimport { a } from '@/lib/a'\n")
).toEqual(['@/lib/uploads/core/setup.server', '@/lib/a'])
})
it('leaves a dynamic import out of the module-evaluation set', () => {
expect(runtimeSpecifiers("const a = await import('@/lib/a')\n")).toEqual([])
})
it('ignores type-only statements, which the compiler erases', () => {
expect(
runtimeSpecifiers(
"import type { A } from '@/lib/a'\nimport type B from '@/lib/b'\nexport type { C } from '@/lib/c'\n"
)
).toEqual([])
})
it('keeps an inline type import, which still emits a runtime load', () => {
expect(runtimeSpecifiers("import { type A, b } from '@/lib/a'\n")).toEqual(['@/lib/a'])
})
})
describe('resolveSpecifier', () => {
it('resolves an @/ specifier against apps/sim', () => {
expect(resolveSpecifier('@/lib/permission-groups/capabilities', __filename)).toMatch(
/apps\/sim\/lib\/permission-groups\/capabilities\.ts$/
)
})
it('returns null for a bare package specifier', () => {
expect(resolveSpecifier('drizzle-orm', __filename)).toBeNull()
})
})
describe('the guarded roots', () => {
it('guards the universal route wrapper against the billing graph', () => {
const wrapper = GUARDED_ROOTS.find(
(guarded) => guarded.root === 'lib/core/utils/with-route-handler.ts'
)
expect(wrapper?.forbidden['lib/billing/']).toBeTruthy()
})
it('reaches no forbidden module tree at runtime', () => {
for (const guarded of GUARDED_ROOTS) {
expect({ root: guarded.root, violations: findViolations(guarded) }).toEqual({
root: guarded.root,
violations: [],
})
}
})
it('reports the shortest chain when a forbidden module is reachable', () => {
/**
* Walked from a module that legitimately imports the provider registry, so
* the walker is proven able to fail. Without this the suite above would
* still pass if `findViolations` silently stopped finding anything.
*/
const violations = findViolations({
root: 'lib/permission-groups/model-access.ts',
forbidden: FORBIDDEN_PREFIXES,
})
expect(violations).toHaveLength(1)
expect(violations[0].forbidden).toBe('providers/utils.ts')
expect(violations[0].reason).toBe(FORBIDDEN_PREFIXES['providers/'])
expect(violations[0].path).toEqual([
'lib/permission-groups/model-access.ts',
'providers/utils.ts',
])
})
})
describe('deferredSpecifiers', () => {
it('collects a dynamic import, awaited or not', () => {
expect(
deferredSpecifiers(
"const a = await import('@/lib/a')\nvoid import('@/lib/b').then(noop)\n" +
"const { c } = await import(\n '@/lib/c'\n)\n"
)
).toEqual(['@/lib/a', '@/lib/b', '@/lib/c'])
})
it('ignores a `typeof import(…)` type query, which the compiler erases', () => {
expect(deferredSpecifiers("type A = typeof import('@/lib/a')\n")).toEqual([])
})
it('leaves static forms to runtimeSpecifiers', () => {
expect(deferredSpecifiers("import { a } from '@/lib/a'\nimport '@/lib/b'\n")).toEqual([])
})
})
describe('a deferred edge into a forbidden tree', () => {
/**
* The evasion: a root that goes red on a static import is one keystroke from
* green if `await import(…)` produces no edge. On the funnel's hot path the
* deferral moves nothing — the registry loads on the first gated request
* instead of on the first import — so the edge is reported.
*/
it('is reported when a root defers the load of a forbidden module', () => {
/**
* Walked from a module that defers the block registry — `const
* { getBlockRegistry } = await import('@/blocks/registry')`. A root's own
* deferred edges are checked before its static imports, so the reported chain
* is that single deferred hop, whatever else the root reaches.
*/
const root =
'app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/copilot/components/user-input/hooks/use-mention-data.ts'
const violations = findViolations({
root,
forbidden: { 'blocks/': FORBIDDEN_PREFIXES['blocks/'] },
})
expect(violations).toHaveLength(1)
expect(violations[0].forbidden).toBe('blocks/registry.ts')
expect(violations[0].reason).toContain('deferred')
expect(violations[0].path).toEqual([root, 'blocks/registry.ts'])
})
/**
* The other half of the rule, and the reason it is not "walk dynamic imports
* like static ones": `lib/billing/core/subscription.ts` sits in the funnel's
* static graph and lazily loads `@/components/emails` on a plan-upgrade
* webhook — a template that statically imports the workflow graph. Walking
* past the deferred hop reports a module nothing loads until that webhook
* fires, which is a false alarm about what an authorization decision costs.
*/
it('is not walked through, so a deferred module’s own graph stays out', () => {
expect(
findViolations({
root: 'lib/billing/core/subscription.ts',
forbidden: { 'lib/workflows/': FORBIDDEN_PREFIXES['lib/workflows/'] },
})
).toEqual([])
})
})