directus

Форк
0
/
schema.test.ts 
189 строк · 5.1 Кб
1
import type { Diff } from 'deep-diff';
2
import type { Knex } from 'knex';
3
import knex from 'knex';
4
import { createTracker, MockClient, Tracker } from 'knex-mock-client';
5
import { afterEach, beforeAll, describe, expect, it, vi } from 'vitest';
6
import { ForbiddenError } from '@directus/errors';
7
import type { Collection } from '../types/collection.js';
8
import type { Snapshot, SnapshotDiffWithHash } from '../types/snapshot.js';
9
import { applyDiff } from '../utils/apply-diff.js';
10
import { getSnapshot } from '../utils/get-snapshot.js';
11
import { SchemaService } from './schema.js';
12

13
vi.mock('directus/version', () => ({ version: '0.0.0' }));
14

15
vi.mock('../../src/database/index.js', () => {
16
	return { __esModule: true, default: vi.fn(), getDatabaseClient: vi.fn().mockReturnValue('postgres') };
17
});
18

19
vi.mock('../utils/get-snapshot.js', () => ({
20
	getSnapshot: vi.fn(),
21
}));
22

23
vi.mock('../utils/apply-diff.js', () => ({
24
	applyDiff: vi.fn(),
25
}));
26

27
class Client_PG extends MockClient {}
28

29
let db: Knex;
30
let tracker: Tracker;
31

32
const testSnapshot = {
33
	directus: '0.0.0',
34
	version: 1,
35
	vendor: 'postgres',
36
	collections: [],
37
	fields: [],
38
	relations: [],
39
} satisfies Snapshot;
40

41
const testCollectionDiff = {
42
	collection: 'test',
43
	diff: [
44
		{
45
			kind: 'N',
46
			rhs: {
47
				collection: 'test',
48
				meta: {
49
					accountability: 'all',
50
					collection: 'test',
51
					group: null,
52
					hidden: false,
53
					icon: null,
54
					item_duplication_fields: null,
55
					note: null,
56
					singleton: false,
57
					translations: {},
58
				},
59
				schema: { name: 'test' },
60
			},
61
		},
62
	] satisfies Diff<Collection>[],
63
};
64

65
beforeAll(() => {
66
	db = knex.default({ client: Client_PG });
67
	tracker = createTracker(db);
68
});
69

70
afterEach(() => {
71
	tracker.reset();
72
	vi.clearAllMocks();
73
});
74

75
describe('Services / Schema', () => {
76
	describe('snapshot', () => {
77
		it('should throw ForbiddenError for non-admin user', async () => {
78
			vi.mocked(getSnapshot).mockResolvedValueOnce(testSnapshot);
79

80
			const service = new SchemaService({ knex: db, accountability: { role: 'test', admin: false } });
81

82
			expect(service.snapshot()).rejects.toThrowError(ForbiddenError);
83
		});
84

85
		it('should return snapshot for admin user', async () => {
86
			vi.mocked(getSnapshot).mockResolvedValueOnce(testSnapshot);
87

88
			const service = new SchemaService({ knex: db, accountability: { role: 'admin', admin: true } });
89

90
			expect(service.snapshot()).resolves.toEqual(testSnapshot);
91
		});
92
	});
93

94
	describe('apply', () => {
95
		const snapshotDiffWithHash = {
96
			hash: '813b3cdf7013310fafde7813b7d5e6bd4eb1e73f',
97
			diff: {
98
				collections: [testCollectionDiff],
99
				fields: [],
100
				relations: [],
101
			},
102
		} satisfies SnapshotDiffWithHash;
103

104
		it('should throw ForbiddenError for non-admin user', async () => {
105
			vi.mocked(getSnapshot).mockResolvedValueOnce(testSnapshot);
106

107
			const service = new SchemaService({ knex: db, accountability: { role: 'test', admin: false } });
108

109
			expect(service.apply(snapshotDiffWithHash)).rejects.toThrowError(ForbiddenError);
110
			expect(vi.mocked(applyDiff)).not.toHaveBeenCalledOnce();
111
		});
112

113
		it('should apply for admin user', async () => {
114
			vi.mocked(getSnapshot).mockResolvedValueOnce(testSnapshot);
115

116
			const service = new SchemaService({ knex: db, accountability: { role: 'admin', admin: true } });
117

118
			await service.apply(snapshotDiffWithHash);
119

120
			expect(vi.mocked(applyDiff)).toHaveBeenCalledOnce();
121
		});
122
	});
123

124
	describe('diff', () => {
125
		const snapshotToApply = {
126
			directus: '0.0.0',
127
			version: 1,
128
			vendor: 'postgres',
129
			collections: [
130
				{
131
					collection: 'test',
132
					meta: {
133
						accountability: 'all',
134
						collection: 'test',
135
						group: null,
136
						hidden: false,
137
						icon: null,
138
						item_duplication_fields: null,
139
						note: null,
140
						singleton: false,
141
						translations: {},
142
					},
143
					schema: {
144
						name: 'test',
145
					},
146
				},
147
			],
148
			fields: [],
149
			relations: [],
150
		} satisfies Snapshot;
151

152
		it('should throw ForbiddenError for non-admin user', async () => {
153
			const service = new SchemaService({ knex: db, accountability: { role: 'test', admin: false } });
154

155
			expect(service.diff(snapshotToApply, { currentSnapshot: testSnapshot, force: true })).rejects.toThrowError(
156
				ForbiddenError,
157
			);
158
		});
159

160
		it('should return diff for admin user', async () => {
161
			const service = new SchemaService({ knex: db, accountability: { role: 'admin', admin: true } });
162

163
			expect(service.diff(snapshotToApply, { currentSnapshot: testSnapshot, force: true })).resolves.toEqual({
164
				collections: [testCollectionDiff],
165
				fields: [],
166
				relations: [],
167
			});
168
		});
169

170
		it('should return null for empty diff', async () => {
171
			const service = new SchemaService({ knex: db, accountability: { role: 'admin', admin: true } });
172

173
			expect(service.diff(testSnapshot, { currentSnapshot: testSnapshot, force: true })).resolves.toBeNull();
174
		});
175
	});
176

177
	describe('getHashedSnapshot', () => {
178
		it('should return snapshot for admin user', async () => {
179
			const service = new SchemaService({ knex: db, accountability: { role: 'admin', admin: true } });
180

181
			expect(service.getHashedSnapshot(testSnapshot)).toEqual(
182
				expect.objectContaining({
183
					...testSnapshot,
184
					hash: expect.any(String),
185
				}),
186
			);
187
		});
188
	});
189
});
190

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.