-
Notifications
You must be signed in to change notification settings - Fork 104
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #483 from Hexastack/fix/settings-emit
fix: setting emit + unit tests
- Loading branch information
Showing
2 changed files
with
218 additions
and
4 deletions.
There are no files selected for viewing
186 changes: 186 additions & 0 deletions
186
api/src/setting/repositories/setting.repository.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
/* | ||
* Copyright © 2024 Hexastack. All rights reserved. | ||
* | ||
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms: | ||
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission. | ||
* 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file). | ||
*/ | ||
|
||
import { EventEmitter2 } from '@nestjs/event-emitter'; | ||
import { getModelToken, MongooseModule } from '@nestjs/mongoose'; | ||
import { Test } from '@nestjs/testing'; | ||
import { Model } from 'mongoose'; | ||
|
||
import { installSettingFixtures } from '@/utils/test/fixtures/setting'; | ||
import { | ||
closeInMongodConnection, | ||
rootMongooseTestModule, | ||
} from '@/utils/test/test'; | ||
|
||
import { Setting, SettingModel } from '../schemas/setting.schema'; | ||
import { SettingType } from '../schemas/types'; | ||
|
||
import { SettingRepository } from './setting.repository'; | ||
|
||
describe('SettingRepository', () => { | ||
let settingRepository: SettingRepository; | ||
let settingModel: Model<Setting>; | ||
let eventEmitter: EventEmitter2; | ||
|
||
beforeAll(async () => { | ||
const module = await Test.createTestingModule({ | ||
imports: [ | ||
rootMongooseTestModule(installSettingFixtures), | ||
MongooseModule.forFeature([SettingModel]), | ||
], | ||
providers: [SettingRepository, EventEmitter2], | ||
}).compile(); | ||
|
||
settingRepository = module.get<SettingRepository>(SettingRepository); | ||
settingModel = module.get<Model<Setting>>(getModelToken(Setting.name)); | ||
eventEmitter = module.get<EventEmitter2>(EventEmitter2); | ||
}); | ||
|
||
afterEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
afterAll(closeInMongodConnection); | ||
|
||
describe('preCreateValidate', () => { | ||
it('should validate setting value during creation', async () => { | ||
const mockSetting = new settingModel({ | ||
type: SettingType.text, | ||
value: 'Sample Text', | ||
}); | ||
jest.spyOn(settingRepository, 'validateSettingValue'); | ||
|
||
await settingRepository.preCreateValidate(mockSetting); | ||
|
||
expect(settingRepository['validateSettingValue']).toHaveBeenCalledWith( | ||
SettingType.text, | ||
'Sample Text', | ||
); | ||
}); | ||
|
||
it('should throw an error for invalid value type', async () => { | ||
const mockSetting = new settingModel({ | ||
type: SettingType.checkbox, | ||
value: 'Invalid Value', | ||
}); | ||
|
||
await expect( | ||
settingRepository.preCreateValidate(mockSetting), | ||
).rejects.toThrow('Setting Model : Value must be a boolean!'); | ||
}); | ||
}); | ||
|
||
describe('preUpdateValidate', () => { | ||
it('should validate updated setting value', async () => { | ||
const criteria = { _id: '123' }; | ||
const updates = { | ||
$set: { value: 'Updated Text' }, | ||
}; | ||
|
||
jest.spyOn(settingRepository, 'findOne').mockResolvedValue({ | ||
type: SettingType.text, | ||
} as any); | ||
|
||
await settingRepository.preUpdateValidate(criteria, updates); | ||
|
||
expect(settingRepository.findOne).toHaveBeenCalledWith(criteria); | ||
expect(settingRepository['validateSettingValue']).toHaveBeenCalledWith( | ||
SettingType.text, | ||
'Updated Text', | ||
); | ||
}); | ||
}); | ||
|
||
describe('postUpdate', () => { | ||
it('should emit an event after updating a setting', async () => { | ||
const mockSetting = new settingModel({ | ||
group: 'general', | ||
label: 'theme', | ||
}); | ||
|
||
jest.spyOn(eventEmitter, 'emit'); | ||
|
||
await settingRepository.postUpdate({} as any, mockSetting); | ||
|
||
expect(eventEmitter.emit).toHaveBeenCalledWith( | ||
'hook:general:theme', | ||
mockSetting, | ||
); | ||
}); | ||
}); | ||
|
||
describe('validateSettingValue', () => { | ||
it('should validate value types correctly', () => { | ||
expect(() => | ||
settingRepository['validateSettingValue']( | ||
SettingType.text, | ||
'Valid Text', | ||
), | ||
).not.toThrow(); | ||
|
||
expect(() => | ||
settingRepository['validateSettingValue'](SettingType.checkbox, true), | ||
).not.toThrow(); | ||
|
||
expect(() => | ||
settingRepository['validateSettingValue'](SettingType.number, 123), | ||
).not.toThrow(); | ||
|
||
expect(() => | ||
settingRepository['validateSettingValue'](SettingType.text, 123), | ||
).toThrow('Setting Model : Value must be a string!'); | ||
}); | ||
}); | ||
|
||
describe('validateSettingValue', () => { | ||
const testCases = [ | ||
{ | ||
type: SettingType.text, | ||
value: 123, | ||
error: 'Setting Model : Value must be a string!', | ||
}, | ||
{ | ||
type: SettingType.checkbox, | ||
value: 'true', | ||
error: 'Setting Model : Value must be a boolean!', | ||
}, | ||
{ | ||
type: SettingType.number, | ||
value: '123', | ||
}, | ||
{ | ||
type: SettingType.multiple_text, | ||
value: ['valid', 123], | ||
}, | ||
{ | ||
type: SettingType.attachment, | ||
value: 123, | ||
}, | ||
{ | ||
type: SettingType.secret, | ||
value: 123, | ||
}, | ||
{ | ||
type: SettingType.select, | ||
value: 123, | ||
}, | ||
{ | ||
type: SettingType.multiple_attachment, | ||
value: [123, 'valid'], | ||
}, | ||
]; | ||
|
||
testCases.forEach(({ type, value }) => { | ||
it(`should throw an error when value type does not match SettingType.${type}`, () => { | ||
expect(() => | ||
settingRepository['validateSettingValue'](type, value), | ||
).toThrow(); | ||
}); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters