diff --git a/api/src/unraid-api/unraid-file-modifier/__snapshots__/unraid-file-modifier.spec.ts.snap b/api/src/unraid-api/unraid-file-modifier/__snapshots__/unraid-file-modifier.spec.ts.snap new file mode 100644 index 000000000..6fc335f7f --- /dev/null +++ b/api/src/unraid-api/unraid-file-modifier/__snapshots__/unraid-file-modifier.spec.ts.snap @@ -0,0 +1,3 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`FileModificationService > should apply modifications 1`] = `[Error: Application not implemented.]`; diff --git a/api/src/unraid-api/unraid-file-modifier/unraid-file-modifier.spec.ts b/api/src/unraid-api/unraid-file-modifier/unraid-file-modifier.spec.ts index 5b9d9e66a..f8c1096ad 100644 --- a/api/src/unraid-api/unraid-file-modifier/unraid-file-modifier.spec.ts +++ b/api/src/unraid-api/unraid-file-modifier/unraid-file-modifier.spec.ts @@ -1,11 +1,59 @@ +import { Logger } from '@nestjs/common'; import { Test, TestingModule } from '@nestjs/testing'; -import { UnraidFileModificationService } from '@app/unraid-api/unraid-file-modifier/unraid-file-modifier.service'; +import { beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'; + +import { + FileModification, + UnraidFileModificationService, +} from '@app/unraid-api/unraid-file-modifier/unraid-file-modifier.service'; + +class TestFileModification implements FileModification { + constructor( + public applyImplementation?: () => Promise, + public rollbackImplementation?: () => Promise + ) {} + id = 'test'; + async apply() { + if (this.applyImplementation) { + return this.applyImplementation(); + } + throw new Error('Application not implemented.'); + } + async rollback() { + if (this.rollbackImplementation) { + return this.rollbackImplementation(); + } + throw new Error('Rollback not implemented.'); + } + async shouldApply() { + return { shouldApply: true, reason: 'Always Apply this mod' }; + } +} describe('FileModificationService', () => { + let mockLogger: { + log: ReturnType; + error: ReturnType; + warn: ReturnType; + debug: ReturnType; + verbose: ReturnType; + }; let service: UnraidFileModificationService; - beforeEach(async () => { + mockLogger = { + log: vi.fn(), + error: vi.fn(), + warn: vi.fn(), + debug: vi.fn(), + verbose: vi.fn(), + }; + // Mock the Logger constructor + vi.spyOn(Logger.prototype, 'log').mockImplementation(mockLogger.log); + vi.spyOn(Logger.prototype, 'error').mockImplementation(mockLogger.error); + vi.spyOn(Logger.prototype, 'warn').mockImplementation(mockLogger.warn); + vi.spyOn(Logger.prototype, 'debug').mockImplementation(mockLogger.debug); + vi.spyOn(Logger.prototype, 'verbose').mockImplementation(mockLogger.verbose); const module: TestingModule = await Test.createTestingModule({ providers: [UnraidFileModificationService], }).compile(); @@ -20,5 +68,35 @@ describe('FileModificationService', () => { it('should load modifications', async () => { const mods = await service.loadModifications(); expect(mods).toHaveLength(2); - }) + }); + + it('should apply modifications', async () => { + await expect( + service.applyModification(new TestFileModification()) + ).rejects.toThrowErrorMatchingSnapshot(); + }); + + it('should not rollback any mods without loaded', async () => { + await expect(service.rollbackAll()).resolves.toBe(undefined); + }); + + it('should rollback all mods', async () => { + await service.loadModifications(); + const applyFn = vi.fn(); + const rollbackFn = vi.fn(); + await service.applyModification(new TestFileModification(applyFn, rollbackFn)); + await expect(service.rollbackAll()).resolves.toBe(undefined); + expect(mockLogger.error).not.toHaveBeenCalled(); + expect(mockLogger.log).toHaveBeenCalledTimes(5); + expect(applyFn).toHaveBeenCalled(); + expect(rollbackFn).toHaveBeenCalled(); + expect(mockLogger.log).toHaveBeenNthCalledWith(1, 'RootTestModule dependencies initialized'); + expect(mockLogger.log).toHaveBeenNthCalledWith( + 2, + 'Applying modification: test - Always Apply this mod' + ); + expect(mockLogger.log).toHaveBeenNthCalledWith(3, 'Modification applied successfully: test'); + expect(mockLogger.log).toHaveBeenNthCalledWith(4, 'Rolling back modification: test'); + expect(mockLogger.log).toHaveBeenNthCalledWith(5, 'Modification rolled back successfully: test'); + }); });