From 4d45caf25869ba14192e0a0d47fbc064cfc8723e Mon Sep 17 00:00:00 2001 From: Eli Bosley Date: Fri, 31 Jan 2025 13:59:34 -0500 Subject: [PATCH] feat: extensive file checking --- .../unraid-file-modifier/file-modification.ts | 7 +- .../modifications/__fixtures__/test.patch | 9 + .../default-page-layout.modification.spec.ts | 90 ++++-- .../notifications-page.modification.spec.ts | 19 -- ...faultPageLayout.php.modified.snapshot.php} | 0 .../DefaultPageLayout.php.original.php} | 0 .../DefaultPageLayout.php.snapshot.patch} | 0 .../Notifications.page.modified.snapshot.php} | 0 .../snapshots/Notifications.page.original.php | 286 ++++++++++++++++++ .../Notifications.page.snapshot.patch | 28 ++ .../modifications/sso.modification.ts | 8 +- .../unraid-file-modifier.spec.ts | 91 +++--- 12 files changed, 428 insertions(+), 110 deletions(-) create mode 100644 api/src/unraid-api/unraid-file-modifier/modifications/__fixtures__/test.patch delete mode 100644 api/src/unraid-api/unraid-file-modifier/modifications/__test__/notifications-page.modification.spec.ts rename api/src/unraid-api/unraid-file-modifier/modifications/__test__/{DefaultPageLayout.modified.php => snapshots/DefaultPageLayout.php.modified.snapshot.php} (100%) rename api/src/unraid-api/unraid-file-modifier/modifications/__test__/{DefaultPageLayout.original.php => snapshots/DefaultPageLayout.php.original.php} (100%) rename api/src/unraid-api/unraid-file-modifier/modifications/__test__/{DefaultPageLayout.patch.php => snapshots/DefaultPageLayout.php.snapshot.patch} (100%) rename api/src/unraid-api/unraid-file-modifier/modifications/__test__/{Notifications.modified.page => snapshots/Notifications.page.modified.snapshot.php} (100%) create mode 100644 api/src/unraid-api/unraid-file-modifier/modifications/__test__/snapshots/Notifications.page.original.php create mode 100644 api/src/unraid-api/unraid-file-modifier/modifications/__test__/snapshots/Notifications.page.snapshot.patch diff --git a/api/src/unraid-api/unraid-file-modifier/file-modification.ts b/api/src/unraid-api/unraid-file-modifier/file-modification.ts index 9759049ac..839d32f9a 100644 --- a/api/src/unraid-api/unraid-file-modifier/file-modification.ts +++ b/api/src/unraid-api/unraid-file-modifier/file-modification.ts @@ -1,7 +1,7 @@ import { Logger } from '@nestjs/common'; -import { readFile, writeFile, access } from 'fs/promises'; +import { readFile, writeFile, access, unlink } from 'fs/promises'; import { constants } from 'fs'; -import { join, dirname } from 'path'; +import { join, dirname, basename } from 'path'; import { applyPatch, parsePatch, reversePatch } from 'diff'; export interface PatchResult { @@ -25,7 +25,7 @@ export abstract class FileModification { private getPatchFilePath(targetFile: string): string { const dir = dirname(targetFile); - const filename = `${this.id}.patch`; + const filename = `${basename(targetFile)}.patch`; return join(dir, filename); } @@ -50,7 +50,6 @@ export abstract class FileModification { const { targetFile, patch } = patchResult; const currentContent = await readFile(targetFile, 'utf8'); const parsedPatch = parsePatch(patch)[0]; - const results = applyPatch(currentContent, parsedPatch); if (results === false) { throw new Error(`Failed to apply patch to ${targetFile}`); diff --git a/api/src/unraid-api/unraid-file-modifier/modifications/__fixtures__/test.patch b/api/src/unraid-api/unraid-file-modifier/modifications/__fixtures__/test.patch new file mode 100644 index 000000000..bc727f476 --- /dev/null +++ b/api/src/unraid-api/unraid-file-modifier/modifications/__fixtures__/test.patch @@ -0,0 +1,9 @@ +Index: text-patch-file.txt +=================================================================== +--- text-patch-file.txt ++++ text-patch-file.txt +@@ -1,1 +1,1 @@ +-original +\ No newline at end of file ++modified +\ No newline at end of file diff --git a/api/src/unraid-api/unraid-file-modifier/modifications/__test__/default-page-layout.modification.spec.ts b/api/src/unraid-api/unraid-file-modifier/modifications/__test__/default-page-layout.modification.spec.ts index b6ac7cd0e..33ec1c04b 100644 --- a/api/src/unraid-api/unraid-file-modifier/modifications/__test__/default-page-layout.modification.spec.ts +++ b/api/src/unraid-api/unraid-file-modifier/modifications/__test__/default-page-layout.modification.spec.ts @@ -1,47 +1,71 @@ import { Logger } from '@nestjs/common'; import { readFile } from 'fs/promises'; import { resolve } from 'path'; - - - -import { applyPatch } from 'diff'; import { describe, expect, test } from 'vitest'; - - import DefaultPageLayoutModification from '@app/unraid-api/unraid-file-modifier/modifications/default-page-layout.modification'; +import NotificationsPageModification from '@app/unraid-api/unraid-file-modifier/modifications/notifications-page.modification'; +import { FileModification } from '@app/unraid-api/unraid-file-modifier/file-modification'; +import SSOFileModification from '@app/unraid-api/unraid-file-modifier/modifications/sso.modification'; +interface ModificationTestCase { + name: string; + ModificationClass: new (logger: Logger) => FileModification; + fileName: string; +} +const testCases: ModificationTestCase[] = [ + { + name: 'DefaultPageLayout.php', + ModificationClass: DefaultPageLayoutModification, + fileName: 'DefaultPageLayout.php' + }, + { + name: 'Notifications.page', + ModificationClass: NotificationsPageModification, + fileName: 'Notifications.page' + }, + { + name: '.login.php', + ModificationClass: SSOFileModification, + fileName: '.login.php' + } +]; +async function testModification(testCase: ModificationTestCase) { + const path = resolve(__dirname, `../__fixtures__/${testCase.fileName}`); + const fileContent = await readFile(path, 'utf-8'); + expect(fileContent.length).toBeGreaterThan(0); + const logger = new Logger(); + const patcher = await new testCase.ModificationClass(logger); + // @ts-ignore - Ignore for testing purposes + patcher.filePath = path; + + // @ts-ignore - Ignore for testing purposes + const patch = await patcher.generatePatch(); + + // Test patch matches snapshot + await expect(patch.patch).toMatchFileSnapshot( + `snapshots/${testCase.fileName}.snapshot.patch` + ); -describe('DefaultPageLayout.php modifier', () => { - test('correctly applies to fresh install', async () => { - const fileContent = await readFile( - resolve(__dirname, '../__fixtures__/DefaultPageLayout.php'), - 'utf-8' - ); - const path = resolve(__dirname, '../__fixtures__/DefaultPageLayout.php'); - expect(fileContent.length).toBeGreaterThan(0); - const logger = new Logger(); - const patcher = await new DefaultPageLayoutModification(logger); - patcher.filePath = path; - const patch = await patcher.generatePatch(); + // Apply patch and verify modified file + await patcher.apply(); + await expect(await readFile(path, 'utf-8')).toMatchFileSnapshot( + `snapshots/${testCase.fileName}.modified.snapshot.php` + ); - await expect(patch.patch).toMatchFileSnapshot('DefaultPageLayout.patch.php'); - // Now we need to apply the patch + // Rollback and verify original state + await patcher.rollback(); + const revertedContent = await readFile(path, 'utf-8'); + await expect(revertedContent).toMatchFileSnapshot( + `snapshots/${testCase.fileName}.original.php` + ); +} - const newContent = applyPatch(fileContent, patch.patch, { - fuzzFactor: 1, - }); - await expect(newContent).toMatchFileSnapshot('DefaultPageLayout.modified.php'); - - // Now apply the patch - await patcher.apply(); - - // Now rollback the patch and check that the file is back to the original - await patcher.rollback(); - const revertedContent = await readFile(path, 'utf-8'); - await expect(revertedContent).toMatchFileSnapshot('DefaultPageLayout.original.php'); +describe('File modifications', () => { + test.each(testCases)('$name modifier correctly applies to fresh install', async (testCase) => { + await testModification(testCase); }); -}); \ No newline at end of file +}); diff --git a/api/src/unraid-api/unraid-file-modifier/modifications/__test__/notifications-page.modification.spec.ts b/api/src/unraid-api/unraid-file-modifier/modifications/__test__/notifications-page.modification.spec.ts deleted file mode 100644 index 826cf57ff..000000000 --- a/api/src/unraid-api/unraid-file-modifier/modifications/__test__/notifications-page.modification.spec.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { readFile } from 'fs/promises'; -import { resolve } from 'path'; - -import { describe, expect, test } from 'vitest'; - -import NotificationsPageModification from '@app/unraid-api/unraid-file-modifier/modifications/notifications-page.modification'; - -describe('Notifications.page modifier', () => { - test('correctly applies to fresh install', async () => { - const fileContent = await readFile( - resolve(__dirname, '../__fixtures__/Notifications.page'), - 'utf-8' - ); - expect(fileContent.length).toBeGreaterThan(0); - await expect(NotificationsPageModification.applyToSource(fileContent)).toMatchFileSnapshot( - 'Notifications.modified.page' - ); - }); -}); diff --git a/api/src/unraid-api/unraid-file-modifier/modifications/__test__/DefaultPageLayout.modified.php b/api/src/unraid-api/unraid-file-modifier/modifications/__test__/snapshots/DefaultPageLayout.php.modified.snapshot.php similarity index 100% rename from api/src/unraid-api/unraid-file-modifier/modifications/__test__/DefaultPageLayout.modified.php rename to api/src/unraid-api/unraid-file-modifier/modifications/__test__/snapshots/DefaultPageLayout.php.modified.snapshot.php diff --git a/api/src/unraid-api/unraid-file-modifier/modifications/__test__/DefaultPageLayout.original.php b/api/src/unraid-api/unraid-file-modifier/modifications/__test__/snapshots/DefaultPageLayout.php.original.php similarity index 100% rename from api/src/unraid-api/unraid-file-modifier/modifications/__test__/DefaultPageLayout.original.php rename to api/src/unraid-api/unraid-file-modifier/modifications/__test__/snapshots/DefaultPageLayout.php.original.php diff --git a/api/src/unraid-api/unraid-file-modifier/modifications/__test__/DefaultPageLayout.patch.php b/api/src/unraid-api/unraid-file-modifier/modifications/__test__/snapshots/DefaultPageLayout.php.snapshot.patch similarity index 100% rename from api/src/unraid-api/unraid-file-modifier/modifications/__test__/DefaultPageLayout.patch.php rename to api/src/unraid-api/unraid-file-modifier/modifications/__test__/snapshots/DefaultPageLayout.php.snapshot.patch diff --git a/api/src/unraid-api/unraid-file-modifier/modifications/__test__/Notifications.modified.page b/api/src/unraid-api/unraid-file-modifier/modifications/__test__/snapshots/Notifications.page.modified.snapshot.php similarity index 100% rename from api/src/unraid-api/unraid-file-modifier/modifications/__test__/Notifications.modified.page rename to api/src/unraid-api/unraid-file-modifier/modifications/__test__/snapshots/Notifications.page.modified.snapshot.php diff --git a/api/src/unraid-api/unraid-file-modifier/modifications/__test__/snapshots/Notifications.page.original.php b/api/src/unraid-api/unraid-file-modifier/modifications/__test__/snapshots/Notifications.page.original.php new file mode 100644 index 000000000..22e485de7 --- /dev/null +++ b/api/src/unraid-api/unraid-file-modifier/modifications/__test__/snapshots/Notifications.page.original.php @@ -0,0 +1,286 @@ +Menu="UserPreferences" +Type="xmenu" +Title="Notification Settings" +Icon="icon-notifications" +Tag="phone-square" +--- + + + +
+ + + + + + + + + + + + + +_(Notifications display)_: +: + +:notifications_display_help: + +_(Display position)_: +: + +:notifications_display_position_help: + +_(Auto-close)_ (_(seconds)_): +: _(a value of zero means no automatic closure)_ + +:notifications_auto_close_help: + +_(Date format)_: +: + +:notifications_date_format_help: + +_(Time format)_: +: + +:notifications_time_format_help: + +_(Store notifications to flash)_: +: + +:notifications_store_flash_help: + +_(System notifications)_: +: + +:notifications_system_help: + +_(Unraid OS update notification)_: +: + +:notifications_os_update_help: + +_(Plugins update notification)_: +: + +:notifications_plugins_update_help: + +_(Docker update notification)_: +: + +:notifications_docker_update_help: + +_(Language update notification)_: +: + +_(Array status notification)_: +: + +:notifications_array_status_help: + + +: + + +: + + +: + + +: + + +: + +:notifications_agent_selection_help: + +_(Notification entity)_: +: _(Notices)_ + >_(Browser)_   + >_(Email)_   + >_(Agents)_   + +  +: _(Warnings)_ + >_(Browser)_   + >_(Email)_   + >_(Agents)_   + +  +: _(Alerts)_ + >_(Browser)_   + >_(Email)_   + >_(Agents)_   + +:notifications_classification_help: + + +: +
diff --git a/api/src/unraid-api/unraid-file-modifier/modifications/__test__/snapshots/Notifications.page.snapshot.patch b/api/src/unraid-api/unraid-file-modifier/modifications/__test__/snapshots/Notifications.page.snapshot.patch new file mode 100644 index 000000000..62f67bc5d --- /dev/null +++ b/api/src/unraid-api/unraid-file-modifier/modifications/__test__/snapshots/Notifications.page.snapshot.patch @@ -0,0 +1,28 @@ +Index: /app/src/unraid-api/unraid-file-modifier/modifications/__fixtures__/Notifications.page +=================================================================== +--- /app/src/unraid-api/unraid-file-modifier/modifications/__fixtures__/Notifications.page ++++ /app/src/unraid-api/unraid-file-modifier/modifications/__fixtures__/Notifications.page +@@ -135,23 +135,7 @@ + + :notifications_auto_close_help: + +-_(Date format)_: +-: + +-:notifications_date_format_help: +- +-_(Time format)_: +-: +- +-:notifications_time_format_help: +- + _(Store notifications to flash)_: + :