@drax/settings-back 0.11.3
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/controller/SettingController.js +89 -0
- package/dist/factory/SettingServiceFactory.js +24 -0
- package/dist/index.js +8 -0
- package/dist/interfaces/ISettingRepository.js +1 -0
- package/dist/model/SettingsModel.js +28 -0
- package/dist/permissions/SettingPermissions.js +8 -0
- package/dist/repository/mongo/SettingMongoRepository.js +13 -0
- package/dist/repository/sqlite/SettingSqliteRepository.js +113 -0
- package/dist/routes/SettingRoutes.js +10 -0
- package/dist/schemas/SettingSchema.js +7 -0
- package/dist/services/SettingService.js +95 -0
- package/package.json +66 -0
- package/src/controller/SettingController.ts +92 -0
- package/src/factory/SettingServiceFactory.ts +32 -0
- package/src/index.ts +24 -0
- package/src/interfaces/ISettingRepository.ts +6 -0
- package/src/model/SettingsModel.ts +46 -0
- package/src/permissions/SettingPermissions.ts +9 -0
- package/src/repository/mongo/SettingMongoRepository.ts +23 -0
- package/src/repository/sqlite/SettingSqliteRepository.ts +176 -0
- package/src/routes/SettingRoutes.ts +17 -0
- package/src/schemas/SettingSchema.ts +11 -0
- package/src/services/SettingService.ts +111 -0
- package/test/repository/mongo/MongoInMemory.ts +43 -0
- package/test/repository/mongo/SettingMongoRepository.test.ts +180 -0
- package/test/repository/sqlite/SettingSqliteRepository.test.ts +175 -0
- package/test/services/SettingService.test.ts +319 -0
- package/test.db +0 -0
- package/tsconfig.json +16 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/types/controller/SettingController.d.ts +15 -0
- package/types/controller/SettingController.d.ts.map +1 -0
- package/types/factory/SettingServiceFactory.d.ts +4 -0
- package/types/factory/SettingServiceFactory.d.ts.map +1 -0
- package/types/index.d.ts +11 -0
- package/types/index.d.ts.map +1 -0
- package/types/interfaces/ISettingRepository.d.ts +6 -0
- package/types/interfaces/ISettingRepository.d.ts.map +1 -0
- package/types/model/SettingsModel.d.ts +19 -0
- package/types/model/SettingsModel.d.ts.map +1 -0
- package/types/permissions/SettingPermissions.d.ts +8 -0
- package/types/permissions/SettingPermissions.d.ts.map +1 -0
- package/types/repository/mongo/SettingMongoRepository.d.ts +9 -0
- package/types/repository/mongo/SettingMongoRepository.d.ts.map +1 -0
- package/types/repository/sqlite/SettingSqliteRepository.d.ts +22 -0
- package/types/repository/sqlite/SettingSqliteRepository.d.ts.map +1 -0
- package/types/routes/SettingRoutes.d.ts +4 -0
- package/types/routes/SettingRoutes.d.ts.map +1 -0
- package/types/schemas/SettingSchema.d.ts +10 -0
- package/types/schemas/SettingSchema.d.ts.map +1 -0
- package/types/services/SettingService.d.ts +23 -0
- package/types/services/SettingService.d.ts.map +1 -0
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import {describe, beforeAll, it, vi, expect} from "vitest"
|
|
2
|
+
import {SettingSqliteRepository} from "../../../src/repository/sqlite/SettingSqliteRepository.js";
|
|
3
|
+
import {ISetting, ISettingBase} from "@drax/settings-share";
|
|
4
|
+
import {AbstractSqliteRepository} from "@drax/crud-back";
|
|
5
|
+
|
|
6
|
+
describe('SettingSqliteRepository', () => {
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
beforeAll(async () => {
|
|
11
|
+
const repository = new SettingSqliteRepository("test.db", false)
|
|
12
|
+
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
// it('should verify that SettingSqliteRepository is an instance of AbstractSqliteRepository', () => {
|
|
18
|
+
// // Arrange
|
|
19
|
+
// const repository = new SettingSqliteRepository("test.db", false);
|
|
20
|
+
//
|
|
21
|
+
// // Assert
|
|
22
|
+
// expect(repository).toBeInstanceOf(AbstractSqliteRepository);
|
|
23
|
+
// });
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
it('should correctly handle adding a new setting to the repository', async () => {
|
|
28
|
+
// Arrange
|
|
29
|
+
const repository = new SettingSqliteRepository("test.db", false);
|
|
30
|
+
const newSetting: ISettingBase = {
|
|
31
|
+
key: 'newKey',
|
|
32
|
+
value: 'newValue',
|
|
33
|
+
label: 'New Key Label',
|
|
34
|
+
group: 'Default Group',
|
|
35
|
+
type: 'string',
|
|
36
|
+
options: []
|
|
37
|
+
};
|
|
38
|
+
const expectedSetting = {id: '2', ...newSetting};
|
|
39
|
+
|
|
40
|
+
// Mock the create method of the repository
|
|
41
|
+
vi.spyOn(repository, 'create').mockResolvedValue(expectedSetting);
|
|
42
|
+
|
|
43
|
+
// Act
|
|
44
|
+
const createdSetting = await repository.create(newSetting);
|
|
45
|
+
|
|
46
|
+
// Assert
|
|
47
|
+
expect(createdSetting).toEqual(expectedSetting);
|
|
48
|
+
expect(repository.create).toHaveBeenCalledWith(newSetting);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('should correctly handle updating an existing setting in the repository', async () => {
|
|
52
|
+
// Arrange
|
|
53
|
+
const repository = new SettingSqliteRepository("test.db", false);
|
|
54
|
+
const existingSettingId = '1';
|
|
55
|
+
const updatedData: ISettingBase = {
|
|
56
|
+
key: 'existingKey',
|
|
57
|
+
value: 'updatedValue',
|
|
58
|
+
label: 'Updated Key Label',
|
|
59
|
+
group: 'Default Group',
|
|
60
|
+
type: 'string',
|
|
61
|
+
options: []
|
|
62
|
+
};
|
|
63
|
+
const expectedUpdatedSetting: ISetting = {
|
|
64
|
+
id: existingSettingId,
|
|
65
|
+
...updatedData
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// Mock the update method of the repository
|
|
69
|
+
vi.spyOn(repository, 'update').mockResolvedValue(expectedUpdatedSetting);
|
|
70
|
+
|
|
71
|
+
// Act
|
|
72
|
+
const updatedSetting = await repository.update(existingSettingId, updatedData);
|
|
73
|
+
|
|
74
|
+
// Assert
|
|
75
|
+
expect(updatedSetting).toEqual(expectedUpdatedSetting);
|
|
76
|
+
expect(repository.update).toHaveBeenCalledWith(existingSettingId, updatedData);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
it('should correctly handle searching for a setting by _id', async () => {
|
|
81
|
+
// Arrange
|
|
82
|
+
const repository = new SettingSqliteRepository("test.db", false);
|
|
83
|
+
const settingId = '1';
|
|
84
|
+
const expectedSetting: ISetting = {
|
|
85
|
+
id: settingId,
|
|
86
|
+
key: 'existingKey',
|
|
87
|
+
value: 'existingValue',
|
|
88
|
+
label: 'Existing Key Label',
|
|
89
|
+
group: 'Default Group',
|
|
90
|
+
type: 'string',
|
|
91
|
+
options: []
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
// Mock the findById method of the repository
|
|
95
|
+
vi.spyOn(repository, 'findById').mockResolvedValue(expectedSetting);
|
|
96
|
+
|
|
97
|
+
// Act
|
|
98
|
+
const foundSetting = await repository.findById(settingId);
|
|
99
|
+
|
|
100
|
+
// Assert
|
|
101
|
+
expect(foundSetting).toEqual(expectedSetting);
|
|
102
|
+
expect(repository.findById).toHaveBeenCalledWith(settingId);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
it('should correctly handle searching for a setting by key', async () => {
|
|
107
|
+
// Arrange
|
|
108
|
+
const repository = new SettingSqliteRepository("test.db", false);
|
|
109
|
+
const searchKey = 'sampleKey';
|
|
110
|
+
const expectedSettings: ISetting[] = [{
|
|
111
|
+
id: '1',
|
|
112
|
+
key: 'sampleKey',
|
|
113
|
+
value: 'sampleValue',
|
|
114
|
+
label: 'Sample Setting Label',
|
|
115
|
+
group: 'Sample Group',
|
|
116
|
+
type: 'string',
|
|
117
|
+
options: []
|
|
118
|
+
}];
|
|
119
|
+
|
|
120
|
+
// Mock the search method of the repository
|
|
121
|
+
vi.spyOn(repository, 'search').mockResolvedValue(expectedSettings);
|
|
122
|
+
|
|
123
|
+
// Act
|
|
124
|
+
const foundSettings = await repository.search(searchKey);
|
|
125
|
+
|
|
126
|
+
// Assert
|
|
127
|
+
expect(foundSettings).toEqual(expectedSettings);
|
|
128
|
+
expect(repository.search).toHaveBeenCalledWith(searchKey);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
it('should correctly handle deleting a setting from the repository', async () => {
|
|
134
|
+
// Arrange
|
|
135
|
+
const repository = new SettingSqliteRepository("test.db", false);
|
|
136
|
+
const settingId = '1';
|
|
137
|
+
const expectedDeletionResult = true;
|
|
138
|
+
|
|
139
|
+
// Mock the delete method of the repository
|
|
140
|
+
vi.spyOn(repository, 'delete').mockResolvedValue(expectedDeletionResult);
|
|
141
|
+
|
|
142
|
+
// Act
|
|
143
|
+
const deletionResult = await repository.delete(settingId);
|
|
144
|
+
|
|
145
|
+
// Assert
|
|
146
|
+
expect(deletionResult).toBe(expectedDeletionResult);
|
|
147
|
+
expect(repository.delete).toHaveBeenCalledWith(settingId);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
it('should correctly handle retrieving all settings from the repository', async () => {
|
|
152
|
+
// Arrange
|
|
153
|
+
const repository = new SettingSqliteRepository("test.db", false);
|
|
154
|
+
const expectedSettings: ISetting[] = [{
|
|
155
|
+
id: '1',
|
|
156
|
+
key: 'existingKey',
|
|
157
|
+
value: 'existingValue',
|
|
158
|
+
label: 'Existing Key Label',
|
|
159
|
+
group: 'Default Group',
|
|
160
|
+
type: 'string',
|
|
161
|
+
options: []
|
|
162
|
+
}];
|
|
163
|
+
|
|
164
|
+
// Mock the fetchAll method of the repository
|
|
165
|
+
vi.spyOn(repository, 'fetchAll').mockResolvedValue(expectedSettings);
|
|
166
|
+
|
|
167
|
+
// Act
|
|
168
|
+
const allSettings = await repository.fetchAll();
|
|
169
|
+
|
|
170
|
+
// Assert
|
|
171
|
+
expect(allSettings).toEqual(expectedSettings);
|
|
172
|
+
expect(repository.fetchAll).toHaveBeenCalled();
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
})
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
import {describe, beforeEach, it, vi, expect} from "vitest"
|
|
2
|
+
import {SettingService} from '../../src/services/SettingService';
|
|
3
|
+
import {ISettingRepository} from '../../src/interfaces/ISettingRepository';
|
|
4
|
+
import {ISetting, ISettingBase} from '@drax/settings-share';
|
|
5
|
+
import {IDraxPaginateResult} from "@drax/crud-share";
|
|
6
|
+
|
|
7
|
+
// Mock implementation of ISettingRepository
|
|
8
|
+
class MockSettingRepository implements ISettingRepository {
|
|
9
|
+
async findOneBy(field: string, value: string): Promise<ISetting | undefined> {
|
|
10
|
+
if (field === 'key' && value === 'existingKey') {
|
|
11
|
+
return {
|
|
12
|
+
id: '1',
|
|
13
|
+
key: 'existingKey',
|
|
14
|
+
value: 'existingValue',
|
|
15
|
+
label: 'Existing Key Label',
|
|
16
|
+
group: 'Default Group',
|
|
17
|
+
type: 'string',
|
|
18
|
+
options: []
|
|
19
|
+
} as ISetting;
|
|
20
|
+
}
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async fetchAll(): Promise<ISetting[]> {
|
|
25
|
+
return [{
|
|
26
|
+
id: '1',
|
|
27
|
+
key: 'existingKey',
|
|
28
|
+
value: 'existingValue',
|
|
29
|
+
label: 'Existing Key Label', // Add missing properties
|
|
30
|
+
group: 'Default Group',
|
|
31
|
+
type: 'string',
|
|
32
|
+
options: []
|
|
33
|
+
}];
|
|
34
|
+
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async create(data: ISettingBase): Promise<ISetting> {
|
|
38
|
+
return {id: '2', ...data} as ISetting;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async update(id: string, data: ISettingBase): Promise<ISetting> {
|
|
42
|
+
return {id, ...data} as ISetting;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async updatePartial(id: string, data: Partial<ISettingBase>): Promise<ISetting | undefined> {
|
|
46
|
+
return {id, ...data} as ISetting;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async paginate(): Promise<IDraxPaginateResult<ISetting>> {
|
|
50
|
+
return { page: 1, limit: 5, total: 1, items: [
|
|
51
|
+
{
|
|
52
|
+
id: '1',
|
|
53
|
+
key: 'existingKey',
|
|
54
|
+
value: 'existingValue',
|
|
55
|
+
label: 'Existing Key Label',
|
|
56
|
+
group: 'Default Group',
|
|
57
|
+
type: 'string',
|
|
58
|
+
options: []
|
|
59
|
+
}
|
|
60
|
+
] };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async delete(id: string): Promise<boolean> {
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function sleep(ms: number) {
|
|
69
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
describe('SettingService', () => {
|
|
73
|
+
let settingService: SettingService;
|
|
74
|
+
let mockRepository: MockSettingRepository;
|
|
75
|
+
|
|
76
|
+
beforeEach(() => {
|
|
77
|
+
mockRepository = new MockSettingRepository();
|
|
78
|
+
settingService = new SettingService(mockRepository);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('should successfully create a setting when valid data is provided', async () => {
|
|
82
|
+
// Arrange
|
|
83
|
+
const validData: ISettingBase = {
|
|
84
|
+
key: 'newKey',
|
|
85
|
+
value: 'newValue',
|
|
86
|
+
label: 'New Key Label',
|
|
87
|
+
group: 'Default Group',
|
|
88
|
+
type: 'string',
|
|
89
|
+
options: []
|
|
90
|
+
};
|
|
91
|
+
const expectedSetting = {id: '2', ...validData};
|
|
92
|
+
|
|
93
|
+
// Act
|
|
94
|
+
const createdSetting = await settingService.create(validData);
|
|
95
|
+
|
|
96
|
+
// Assert
|
|
97
|
+
expect(createdSetting).toEqual(expectedSetting);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('should throw a validation error when creating a setting with invalid data', async () => {
|
|
101
|
+
// Arrange
|
|
102
|
+
const invalidData: ISettingBase = {
|
|
103
|
+
key: '',
|
|
104
|
+
value: 'someValue',
|
|
105
|
+
label: 'Invalid Label',
|
|
106
|
+
group: 'Invalid Group',
|
|
107
|
+
type: 'string',
|
|
108
|
+
options: []
|
|
109
|
+
}; // Assuming an empty key is invalid
|
|
110
|
+
|
|
111
|
+
// Act & Assert
|
|
112
|
+
await expect(settingService.create(invalidData)).rejects.toThrowError();
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('should update an existing setting when valid data is provided', async () => {
|
|
116
|
+
// Arrange
|
|
117
|
+
const existingSetting = {id: '1', key: 'existingKey', value: 'existingValue'};
|
|
118
|
+
const updatedData: ISettingBase = {
|
|
119
|
+
key: 'existingKey',
|
|
120
|
+
value: 'updatedValue',
|
|
121
|
+
label: 'Existing Key Label',
|
|
122
|
+
group: 'Default Group',
|
|
123
|
+
type: 'string',
|
|
124
|
+
options: []
|
|
125
|
+
};
|
|
126
|
+
const expectedUpdatedSetting: ISetting = {
|
|
127
|
+
id: '1',
|
|
128
|
+
key: 'existingKey',
|
|
129
|
+
value: 'updatedValue',
|
|
130
|
+
label: 'Existing Key Label',
|
|
131
|
+
group: 'Default Group',
|
|
132
|
+
type: 'string',
|
|
133
|
+
options: []
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
// Mock the repository's update method
|
|
137
|
+
vi.spyOn(mockRepository, 'update').mockResolvedValue(expectedUpdatedSetting);
|
|
138
|
+
|
|
139
|
+
// Act
|
|
140
|
+
const updatedSetting = await settingService.update(existingSetting.id, updatedData);
|
|
141
|
+
|
|
142
|
+
// Assert
|
|
143
|
+
expect(updatedSetting).toEqual(expectedUpdatedSetting);
|
|
144
|
+
expect(mockRepository.update).toHaveBeenCalledWith(existingSetting.id, updatedData);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('should cache a setting after fetching it by cache method and only call findByKey once', async () => {
|
|
148
|
+
// Arrange
|
|
149
|
+
const key = 'existingKey';
|
|
150
|
+
const expectedSetting: ISetting = {
|
|
151
|
+
id: '1',
|
|
152
|
+
key: 'existingKey',
|
|
153
|
+
value: 'existingValue',
|
|
154
|
+
label: 'Existing Key Label',
|
|
155
|
+
group: 'Default Group',
|
|
156
|
+
type: 'string',
|
|
157
|
+
options: []
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
// Mock the repository's findOneBy method
|
|
161
|
+
const findOneBySpy = vi.spyOn(mockRepository, 'findOneBy').mockResolvedValue(expectedSetting);
|
|
162
|
+
|
|
163
|
+
// Act
|
|
164
|
+
const firstFetch = await settingService.cache(key);
|
|
165
|
+
sleep(100)
|
|
166
|
+
const secondFetch = await settingService.cache(key);
|
|
167
|
+
|
|
168
|
+
// Assert
|
|
169
|
+
expect(firstFetch).toEqual(expectedSetting);
|
|
170
|
+
expect(secondFetch).toEqual(expectedSetting);
|
|
171
|
+
expect(findOneBySpy).toHaveBeenCalledTimes(1);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it('should return all settings when fetchAll is called', async () => {
|
|
175
|
+
// Arrange
|
|
176
|
+
const expectedSettings = [{
|
|
177
|
+
id: '1',
|
|
178
|
+
key: 'existingKey',
|
|
179
|
+
value: 'existingValue',
|
|
180
|
+
label: 'Existing Key Label',
|
|
181
|
+
group: 'Default Group',
|
|
182
|
+
type: 'string',
|
|
183
|
+
options: []
|
|
184
|
+
}];
|
|
185
|
+
|
|
186
|
+
// Act
|
|
187
|
+
const settings = await settingService.fetchAll();
|
|
188
|
+
|
|
189
|
+
// Assert
|
|
190
|
+
expect(settings).toEqual(expectedSettings);
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
it('should update the value of a setting when a valid ID and value are provided', async () => {
|
|
194
|
+
// Arrange
|
|
195
|
+
const settingId = '1';
|
|
196
|
+
const newValue = 'newUpdatedValue';
|
|
197
|
+
const expectedUpdatedSetting: ISetting = {
|
|
198
|
+
id: settingId,
|
|
199
|
+
key: 'existingKey',
|
|
200
|
+
value: newValue,
|
|
201
|
+
label: 'Existing Key Label',
|
|
202
|
+
group: 'Default Group',
|
|
203
|
+
type: 'string',
|
|
204
|
+
options: []
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
// Mock the repository's updatePartial method
|
|
208
|
+
vi.spyOn(mockRepository, 'updatePartial').mockResolvedValue(expectedUpdatedSetting);
|
|
209
|
+
|
|
210
|
+
// Act
|
|
211
|
+
const updatedSetting = await settingService.updateValue(settingId, newValue);
|
|
212
|
+
|
|
213
|
+
// Assert
|
|
214
|
+
expect(updatedSetting).toEqual(expectedUpdatedSetting);
|
|
215
|
+
expect(mockRepository.updatePartial).toHaveBeenCalledWith(settingId, {value: newValue});
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
it('should create a new setting if it does not exist when createOrUpdate is called', async () => {
|
|
219
|
+
// Arrange
|
|
220
|
+
const newSettingData: ISettingBase = {
|
|
221
|
+
key: 'newKey',
|
|
222
|
+
value: 'newValue',
|
|
223
|
+
label: 'New Key Label',
|
|
224
|
+
group: 'Default Group',
|
|
225
|
+
type: 'string',
|
|
226
|
+
options: []
|
|
227
|
+
};
|
|
228
|
+
const expectedNewSetting: ISetting = {
|
|
229
|
+
id: '2',
|
|
230
|
+
key: 'newKey',
|
|
231
|
+
value: 'newValue',
|
|
232
|
+
label: 'New Key Label',
|
|
233
|
+
group: 'Default Group',
|
|
234
|
+
type: 'string',
|
|
235
|
+
options: []
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
// Mock the repository's findOneBy and create methods
|
|
239
|
+
vi.spyOn(mockRepository, 'findOneBy').mockResolvedValue(undefined);
|
|
240
|
+
vi.spyOn(mockRepository, 'create').mockResolvedValue(expectedNewSetting);
|
|
241
|
+
|
|
242
|
+
// Act
|
|
243
|
+
const result = await settingService.createOrUpdate(newSettingData);
|
|
244
|
+
|
|
245
|
+
// Assert
|
|
246
|
+
expect(mockRepository.findOneBy).toHaveBeenCalledWith('key', newSettingData.key);
|
|
247
|
+
expect(mockRepository.create).toHaveBeenCalledWith(newSettingData);
|
|
248
|
+
expect(result).toEqual(expectedNewSetting);
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
it('should update an existing setting if it exists when createOrUpdate is called', async () => {
|
|
252
|
+
// Arrange
|
|
253
|
+
const existingSetting: ISetting = {
|
|
254
|
+
id: '1',
|
|
255
|
+
key: 'existingKey',
|
|
256
|
+
value: 'oldValue',
|
|
257
|
+
label: 'Existing Key Label',
|
|
258
|
+
group: 'Default Group',
|
|
259
|
+
type: 'string',
|
|
260
|
+
options: []
|
|
261
|
+
};
|
|
262
|
+
const updatedData: ISettingBase = {
|
|
263
|
+
key: 'existingKey',
|
|
264
|
+
value: 'newValue',
|
|
265
|
+
label: 'Existing Key Label',
|
|
266
|
+
group: 'Default Group',
|
|
267
|
+
type: 'string',
|
|
268
|
+
options: []
|
|
269
|
+
};
|
|
270
|
+
const expectedUpdatedSetting: ISetting = {
|
|
271
|
+
id: '1',
|
|
272
|
+
key: 'existingKey',
|
|
273
|
+
value: 'oldValue',
|
|
274
|
+
label: 'Existing Key Label',
|
|
275
|
+
group: 'Default Group',
|
|
276
|
+
type: 'string',
|
|
277
|
+
options: []
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
// Mock the repository's findOneBy and update methods
|
|
281
|
+
vi.spyOn(mockRepository, 'findOneBy').mockResolvedValue(existingSetting);
|
|
282
|
+
vi.spyOn(mockRepository, 'updatePartial').mockResolvedValue(expectedUpdatedSetting);
|
|
283
|
+
|
|
284
|
+
// Act
|
|
285
|
+
const result = await settingService.createOrUpdate(updatedData);
|
|
286
|
+
|
|
287
|
+
// Assert
|
|
288
|
+
expect(mockRepository.findOneBy).toHaveBeenCalledWith('key', updatedData.key);
|
|
289
|
+
expect(mockRepository.updatePartial).toHaveBeenCalledWith(existingSetting.id, updatedData);
|
|
290
|
+
expect(result).toEqual(expectedUpdatedSetting);
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
it('should return undefined when trying to find a setting by a non-existent key', async () => {
|
|
294
|
+
// Arrange
|
|
295
|
+
const nonExistentKey = 'nonExistentKey';
|
|
296
|
+
|
|
297
|
+
// Act
|
|
298
|
+
const result = await settingService.findByKey(nonExistentKey);
|
|
299
|
+
|
|
300
|
+
// Assert
|
|
301
|
+
expect(result).toBeUndefined();
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
it('should throw a validation error when updating a setting with invalid data', async () => {
|
|
305
|
+
// Arrange
|
|
306
|
+
const invalidData: ISettingBase = {
|
|
307
|
+
key: '',
|
|
308
|
+
value: 'someValue',
|
|
309
|
+
label: '',
|
|
310
|
+
group: '',
|
|
311
|
+
type: 'string',
|
|
312
|
+
options: []
|
|
313
|
+
}; // Assuming an empty key is invalid
|
|
314
|
+
const settingId = '1'; // Example setting ID
|
|
315
|
+
|
|
316
|
+
// Act & Assert
|
|
317
|
+
await expect(settingService.update(settingId, invalidData)).rejects.toThrowError();
|
|
318
|
+
});
|
|
319
|
+
});
|
package/test.db
ADDED
|
Binary file
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../../tsconfig.base.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"rootDir": "src",
|
|
5
|
+
"outDir": "dist",
|
|
6
|
+
"declarationDir": "types"
|
|
7
|
+
},
|
|
8
|
+
"exclude": ["types", "test", "dist","node_modules","tmp"],
|
|
9
|
+
"ts-node": {
|
|
10
|
+
"esm": true
|
|
11
|
+
},
|
|
12
|
+
"tsc-alias": {
|
|
13
|
+
"resolveFullPaths": true,
|
|
14
|
+
"verbose": false
|
|
15
|
+
}
|
|
16
|
+
}
|