@stonecrop/casl-middleware 0.12.8 → 0.13.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/index.js +3 -0
- package/dist/middleware/ability.js +139 -0
- package/dist/middleware/graphql.js +120 -0
- package/dist/middleware/introspection.js +169 -0
- package/dist/middleware/jwt.js +291 -0
- package/dist/middleware/postgraphile.js +80 -0
- package/dist/middleware/yoga.js +32 -0
- package/dist/src/tsdoc-metadata.json +11 -0
- package/dist/tests/ability.test.d.ts +2 -0
- package/dist/tests/ability.test.d.ts.map +1 -0
- package/dist/tests/ability.test.js +402 -0
- package/dist/tests/helpers/test-utils.d.ts +46 -0
- package/dist/tests/helpers/test-utils.d.ts.map +1 -0
- package/dist/tests/helpers/test-utils.js +92 -0
- package/dist/tests/introspection.test.d.ts +2 -0
- package/dist/tests/introspection.test.d.ts.map +1 -0
- package/dist/tests/introspection.test.js +368 -0
- package/dist/tests/jwt.test.d.ts +2 -0
- package/dist/tests/jwt.test.d.ts.map +1 -0
- package/dist/tests/jwt.test.js +700 -0
- package/dist/tests/middleware.test.d.ts +2 -0
- package/dist/tests/middleware.test.d.ts.map +1 -0
- package/dist/tests/middleware.test.js +184 -0
- package/dist/tests/postgraphile-plugin.test.d.ts +2 -0
- package/dist/tests/postgraphile-plugin.test.d.ts.map +1 -0
- package/dist/tests/postgraphile-plugin.test.js +56 -0
- package/dist/tests/setup.d.ts +2 -0
- package/dist/tests/setup.d.ts.map +1 -0
- package/dist/tests/setup.js +11 -0
- package/dist/tests/types.test.d.ts +2 -0
- package/dist/tests/types.test.d.ts.map +1 -0
- package/dist/tests/types.test.js +143 -0
- package/dist/tests/user-roles.test.d.ts +2 -0
- package/dist/tests/user-roles.test.d.ts.map +1 -0
- package/dist/tests/user-roles.test.js +157 -0
- package/dist/tests/yoga-plugin.test.d.ts +2 -0
- package/dist/tests/yoga-plugin.test.d.ts.map +1 -0
- package/dist/tests/yoga-plugin.test.js +125 -0
- package/dist/types/index.js +0 -0
- package/package.json +1 -1
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
+
import { yogaCaslPlugin, createYogaPlugin } from '../src/middleware/yoga';
|
|
3
|
+
describe('Yoga CASL Plugin', () => {
|
|
4
|
+
it('should be a valid Yoga plugin', () => {
|
|
5
|
+
expect(yogaCaslPlugin).toBeDefined();
|
|
6
|
+
expect(typeof yogaCaslPlugin).toBe('object');
|
|
7
|
+
expect(yogaCaslPlugin).toHaveProperty('onContextBuilding');
|
|
8
|
+
});
|
|
9
|
+
it('should extend context with ability and user', async () => {
|
|
10
|
+
const mockContext = {};
|
|
11
|
+
const extendContext = vi.fn(extension => {
|
|
12
|
+
Object.assign(mockContext, extension);
|
|
13
|
+
});
|
|
14
|
+
const contextParams = {
|
|
15
|
+
context: mockContext,
|
|
16
|
+
extendContext,
|
|
17
|
+
};
|
|
18
|
+
// Execute the plugin
|
|
19
|
+
await yogaCaslPlugin.onContextBuilding(contextParams);
|
|
20
|
+
expect(extendContext).toHaveBeenCalled();
|
|
21
|
+
expect(extendContext).toHaveBeenCalledWith(expect.objectContaining({
|
|
22
|
+
ability: expect.any(Object),
|
|
23
|
+
user: expect.objectContaining({
|
|
24
|
+
id: '1',
|
|
25
|
+
roles: ['editor'],
|
|
26
|
+
}),
|
|
27
|
+
}));
|
|
28
|
+
});
|
|
29
|
+
it('should create ability with editor permissions', async () => {
|
|
30
|
+
const mockContext = {};
|
|
31
|
+
let extendedData = {};
|
|
32
|
+
const extendContext = vi.fn(extension => {
|
|
33
|
+
extendedData = extension;
|
|
34
|
+
});
|
|
35
|
+
const contextParams = {
|
|
36
|
+
context: mockContext,
|
|
37
|
+
extendContext,
|
|
38
|
+
};
|
|
39
|
+
await yogaCaslPlugin.onContextBuilding(contextParams);
|
|
40
|
+
// Check that the ability was created with editor permissions
|
|
41
|
+
expect(extendedData.ability).toBeDefined();
|
|
42
|
+
expect(extendedData.user.roles).toContain('editor');
|
|
43
|
+
// The ability should have the permissions we expect for an editor
|
|
44
|
+
const ability = extendedData.ability;
|
|
45
|
+
expect(ability.can('read', 'Query')).toBe(true);
|
|
46
|
+
});
|
|
47
|
+
describe('createYogaPlugin', () => {
|
|
48
|
+
it('should create a plugin with default options', () => {
|
|
49
|
+
const plugin = createYogaPlugin();
|
|
50
|
+
expect(plugin).toBeDefined();
|
|
51
|
+
expect(plugin).toHaveProperty('onExecute');
|
|
52
|
+
expect(typeof plugin.onExecute).toBe('function');
|
|
53
|
+
});
|
|
54
|
+
it('should create a plugin with custom options', () => {
|
|
55
|
+
const customBuilder = async () => {
|
|
56
|
+
const { defaultAbilityBuilder } = await import('../src/middleware/ability');
|
|
57
|
+
return defaultAbilityBuilder();
|
|
58
|
+
};
|
|
59
|
+
const plugin = createYogaPlugin({
|
|
60
|
+
abilityBuilder: customBuilder,
|
|
61
|
+
});
|
|
62
|
+
expect(plugin).toBeDefined();
|
|
63
|
+
expect(plugin).toHaveProperty('onExecute');
|
|
64
|
+
});
|
|
65
|
+
it('should log message when onExecute is called', async () => {
|
|
66
|
+
const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
|
|
67
|
+
const plugin = createYogaPlugin();
|
|
68
|
+
const mockArgs = {
|
|
69
|
+
args: {
|
|
70
|
+
schema: {},
|
|
71
|
+
document: {},
|
|
72
|
+
contextValue: {},
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
await plugin.onExecute(mockArgs);
|
|
76
|
+
expect(consoleSpy).toHaveBeenCalledWith('Yoga plugin not yet implemented');
|
|
77
|
+
consoleSpy.mockRestore();
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
describe('yogaCaslPlugin edge cases', () => {
|
|
81
|
+
it('should handle missing onContextBuilding gracefully', async () => {
|
|
82
|
+
// Test that the plugin has the expected property
|
|
83
|
+
expect(yogaCaslPlugin.onContextBuilding).toBeDefined();
|
|
84
|
+
});
|
|
85
|
+
it('should extend context even with empty initial context', async () => {
|
|
86
|
+
let extendedData = {};
|
|
87
|
+
const extendContext = vi.fn(extension => {
|
|
88
|
+
extendedData = extension;
|
|
89
|
+
});
|
|
90
|
+
const contextParams = {
|
|
91
|
+
context: {},
|
|
92
|
+
extendContext,
|
|
93
|
+
};
|
|
94
|
+
await yogaCaslPlugin.onContextBuilding(contextParams);
|
|
95
|
+
expect(extendContext).toHaveBeenCalled();
|
|
96
|
+
expect(extendedData).toHaveProperty('ability');
|
|
97
|
+
expect(extendedData).toHaveProperty('user');
|
|
98
|
+
});
|
|
99
|
+
it('should create ability with default permissions', async () => {
|
|
100
|
+
let extendedData = {};
|
|
101
|
+
const extendContext = vi.fn(extension => {
|
|
102
|
+
extendedData = extension;
|
|
103
|
+
});
|
|
104
|
+
const contextParams = {
|
|
105
|
+
context: {},
|
|
106
|
+
extendContext,
|
|
107
|
+
};
|
|
108
|
+
await yogaCaslPlugin.onContextBuilding(contextParams);
|
|
109
|
+
const ability = extendedData.ability;
|
|
110
|
+
// Default ability should have Query read access
|
|
111
|
+
expect(ability.can('read', 'Query')).toBe(true);
|
|
112
|
+
});
|
|
113
|
+
it('should handle context extension errors', async () => {
|
|
114
|
+
const extendContext = vi.fn(() => {
|
|
115
|
+
throw new Error('Extension failed');
|
|
116
|
+
});
|
|
117
|
+
const contextParams = {
|
|
118
|
+
context: {},
|
|
119
|
+
extendContext,
|
|
120
|
+
};
|
|
121
|
+
// Should not throw, but let the error propagate
|
|
122
|
+
await expect(yogaCaslPlugin.onContextBuilding(contextParams)).rejects.toThrow('Extension failed');
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
});
|
|
File without changes
|