mirror of
https://github.com/unraid/api.git
synced 2025-12-30 04:59:51 -06:00
test(file-modification): add unit tests for version comparison methods
- Introduced a new test suite for the FileModification class to validate version comparison methods. - Implemented tests for isUnraidVersionGreaterThanOrEqualTo and isUnraidVersionLessThanOrEqualTo, including scenarios for stable and prerelease versions. - Enhanced the compareUnraidVersion method to streamline version comparison logic.
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
import { Logger } from '@nestjs/common';
|
||||
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import * as getUnraidVersionModule from '@app/common/dashboard/get-unraid-version.js';
|
||||
import { FileModification } from '@app/unraid-api/unraid-file-modifier/file-modification.js';
|
||||
|
||||
vi.mock('@app/common/dashboard/get-unraid-version.js');
|
||||
|
||||
class TestFileModification extends FileModification {
|
||||
id = 'test';
|
||||
filePath = '/test/file';
|
||||
|
||||
protected async generatePatch(): Promise<string> {
|
||||
return 'test patch';
|
||||
}
|
||||
}
|
||||
|
||||
describe('FileModification', () => {
|
||||
let modification: TestFileModification;
|
||||
let getUnraidVersionMock: any;
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
const logger = new Logger('TestFileModification');
|
||||
modification = new TestFileModification(logger);
|
||||
getUnraidVersionMock = vi.mocked(getUnraidVersionModule.getUnraidVersion);
|
||||
});
|
||||
|
||||
describe('version comparison methods', () => {
|
||||
describe('isUnraidVersionGreaterThanOrEqualTo', () => {
|
||||
it('should return true when current version is greater', async () => {
|
||||
getUnraidVersionMock.mockResolvedValue('7.3.0');
|
||||
const result = await modification['isUnraidVersionGreaterThanOrEqualTo']('7.2.0');
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return true when current version is equal', async () => {
|
||||
getUnraidVersionMock.mockResolvedValue('7.2.0');
|
||||
const result = await modification['isUnraidVersionGreaterThanOrEqualTo']('7.2.0');
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false when current version is less', async () => {
|
||||
getUnraidVersionMock.mockResolvedValue('7.1.0');
|
||||
const result = await modification['isUnraidVersionGreaterThanOrEqualTo']('7.2.0');
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it('should handle prerelease versions correctly', async () => {
|
||||
getUnraidVersionMock.mockResolvedValue('7.2.0-beta.1');
|
||||
const result = await modification['isUnraidVersionGreaterThanOrEqualTo']('7.2.0-beta.1');
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should treat prerelease as greater than stable when base versions are equal', async () => {
|
||||
getUnraidVersionMock.mockResolvedValue('7.2.0-beta.1');
|
||||
const result = await modification['isUnraidVersionGreaterThanOrEqualTo']('7.2.0', {
|
||||
includePrerelease: true,
|
||||
});
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should compare prerelease versions correctly', async () => {
|
||||
getUnraidVersionMock.mockResolvedValue('7.2.0-beta.2.4');
|
||||
const result =
|
||||
await modification['isUnraidVersionGreaterThanOrEqualTo']('7.2.0-beta.2.3');
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should handle beta.2.3 being less than beta.2.4', async () => {
|
||||
getUnraidVersionMock.mockResolvedValue('7.2.0-beta.2.3');
|
||||
const result =
|
||||
await modification['isUnraidVersionGreaterThanOrEqualTo']('7.2.0-beta.2.4');
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isUnraidVersionLessThanOrEqualTo', () => {
|
||||
it('should return true when current version is less', async () => {
|
||||
getUnraidVersionMock.mockResolvedValue('7.1.0');
|
||||
const result = await modification['isUnraidVersionLessThanOrEqualTo']('7.2.0');
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return true when current version is equal', async () => {
|
||||
getUnraidVersionMock.mockResolvedValue('7.2.0');
|
||||
const result = await modification['isUnraidVersionLessThanOrEqualTo']('7.2.0');
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false when current version is greater', async () => {
|
||||
getUnraidVersionMock.mockResolvedValue('7.3.0');
|
||||
const result = await modification['isUnraidVersionLessThanOrEqualTo']('7.2.0');
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it('should handle prerelease versions correctly', async () => {
|
||||
getUnraidVersionMock.mockResolvedValue('7.2.0-beta.1');
|
||||
const result = await modification['isUnraidVersionLessThanOrEqualTo']('7.2.0-beta.1');
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should treat prerelease as less than stable when base versions are equal', async () => {
|
||||
getUnraidVersionMock.mockResolvedValue('7.2.0-beta.1');
|
||||
const result = await modification['isUnraidVersionLessThanOrEqualTo']('7.2.0', {
|
||||
includePrerelease: true,
|
||||
});
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
|
||||
it('should compare prerelease versions correctly', async () => {
|
||||
getUnraidVersionMock.mockResolvedValue('7.2.0-beta.2.3');
|
||||
const result = await modification['isUnraidVersionLessThanOrEqualTo']('7.2.0-beta.2.4');
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should handle beta.2.3 being equal to beta.2.3', async () => {
|
||||
getUnraidVersionMock.mockResolvedValue('7.2.0-beta.2.3');
|
||||
const result = await modification['isUnraidVersionLessThanOrEqualTo']('7.2.0-beta.2.3');
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it('should handle beta.2.4 being greater than beta.2.3', async () => {
|
||||
getUnraidVersionMock.mockResolvedValue('7.2.0-beta.2.4');
|
||||
const result = await modification['isUnraidVersionLessThanOrEqualTo']('7.2.0-beta.2.3');
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('inverse relationship', () => {
|
||||
it('should have opposite results for greater-than-or-equal and less-than-or-equal when not equal', async () => {
|
||||
getUnraidVersionMock.mockResolvedValue('7.2.5');
|
||||
const gte = await modification['isUnraidVersionGreaterThanOrEqualTo']('7.2.0');
|
||||
const lte = await modification['isUnraidVersionLessThanOrEqualTo']('7.2.0');
|
||||
expect(gte).toBe(true);
|
||||
expect(lte).toBe(false);
|
||||
});
|
||||
|
||||
it('should both return true when versions are equal', async () => {
|
||||
getUnraidVersionMock.mockResolvedValue('7.2.0');
|
||||
const gte = await modification['isUnraidVersionGreaterThanOrEqualTo']('7.2.0');
|
||||
const lte = await modification['isUnraidVersionLessThanOrEqualTo']('7.2.0');
|
||||
expect(gte).toBe(true);
|
||||
expect(lte).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -5,7 +5,7 @@ import { access, readFile, unlink, writeFile } from 'fs/promises';
|
||||
import { basename, dirname, join } from 'path';
|
||||
|
||||
import { applyPatch, createPatch, parsePatch, reversePatch } from 'diff';
|
||||
import { coerce, compare, gte } from 'semver';
|
||||
import { coerce, compare, gte, lte } from 'semver';
|
||||
|
||||
import { getUnraidVersion } from '@app/common/dashboard/get-unraid-version.js';
|
||||
|
||||
@@ -259,29 +259,53 @@ export abstract class FileModification {
|
||||
return patch;
|
||||
}
|
||||
|
||||
protected async isUnraidVersionGreaterThanOrEqualTo(
|
||||
version: string = '7.2.0', // Defaults to the version of Unraid that includes the API by default
|
||||
private async compareUnraidVersion(
|
||||
version: string,
|
||||
compareFn: typeof gte | typeof lte,
|
||||
{ includePrerelease = true }: { includePrerelease?: boolean } = {}
|
||||
): Promise<boolean> {
|
||||
const unraidVersion = coerce(await getUnraidVersion(), { includePrerelease });
|
||||
const comparedVersion = coerce(version, { includePrerelease });
|
||||
|
||||
if (!unraidVersion) {
|
||||
throw new Error(`Failed to compare Unraid version - missing unraid version`);
|
||||
}
|
||||
if (!comparedVersion) {
|
||||
throw new Error(`Failed to compare Unraid version - missing comparison version`);
|
||||
}
|
||||
// If includePrerelease and base versions are equal, treat prerelease as greater
|
||||
|
||||
// Special handling for prerelease versions when base versions are equal
|
||||
if (includePrerelease) {
|
||||
const baseUnraid = `${unraidVersion.major}.${unraidVersion.minor}.${unraidVersion.patch}`;
|
||||
const baseCompared = `${comparedVersion.major}.${comparedVersion.minor}.${comparedVersion.patch}`;
|
||||
|
||||
if (baseUnraid === baseCompared) {
|
||||
// If unraidVersion has prerelease and comparedVersion does not, treat as greater
|
||||
if (unraidVersion.prerelease.length && !comparedVersion.prerelease.length) {
|
||||
return true;
|
||||
const unraidHasPrerelease = unraidVersion.prerelease.length > 0;
|
||||
const comparedHasPrerelease = comparedVersion.prerelease.length > 0;
|
||||
|
||||
// If one has prerelease and the other doesn't, handle specially
|
||||
if (unraidHasPrerelease && !comparedHasPrerelease) {
|
||||
// For gte: prerelease is considered greater than stable
|
||||
// For lte: prerelease is considered less than stable
|
||||
return compareFn === gte;
|
||||
}
|
||||
}
|
||||
}
|
||||
return gte(unraidVersion, comparedVersion);
|
||||
|
||||
return compareFn(unraidVersion, comparedVersion);
|
||||
}
|
||||
|
||||
protected async isUnraidVersionGreaterThanOrEqualTo(
|
||||
version: string = '7.2.0', // Defaults to the version of Unraid that includes the API by default
|
||||
{ includePrerelease = true }: { includePrerelease?: boolean } = {}
|
||||
): Promise<boolean> {
|
||||
return this.compareUnraidVersion(version, gte, { includePrerelease });
|
||||
}
|
||||
|
||||
protected async isUnraidVersionLessThanOrEqualTo(
|
||||
version: string,
|
||||
{ includePrerelease = true }: { includePrerelease?: boolean } = {}
|
||||
): Promise<boolean> {
|
||||
return this.compareUnraidVersion(version, lte, { includePrerelease });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,10 @@ import { readFile } from 'fs/promises';
|
||||
import { join } from 'node:path';
|
||||
|
||||
import { fileExists } from '@app/core/utils/files/file-exists.js';
|
||||
import { FileModification } from '@app/unraid-api/unraid-file-modifier/file-modification.js';
|
||||
import {
|
||||
FileModification,
|
||||
ShouldApplyWithReason,
|
||||
} from '@app/unraid-api/unraid-file-modifier/file-modification.js';
|
||||
|
||||
export default class AuthRequestModification extends FileModification {
|
||||
public filePath: string = '/usr/local/emhttp/auth-request.php' as const;
|
||||
@@ -30,6 +33,30 @@ export default class AuthRequestModification extends FileModification {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this modification should be applied based on Unraid version
|
||||
* Only apply for Unraid versions up to 7.2.0-beta.2.3
|
||||
*/
|
||||
async shouldApply(): Promise<ShouldApplyWithReason> {
|
||||
// Apply for versions up to and including 7.2.0-beta.2.3
|
||||
const maxVersion = '7.2.0-beta.2.3';
|
||||
const isCompatibleVersion = await this.isUnraidVersionLessThanOrEqualTo(maxVersion, {
|
||||
includePrerelease: true,
|
||||
});
|
||||
|
||||
if (!isCompatibleVersion) {
|
||||
return {
|
||||
shouldApply: false,
|
||||
reason: `Auth request modification only applies to Unraid versions up to ${maxVersion}`,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
shouldApply: true,
|
||||
reason: `Auth request modification needed for Unraid version <= ${maxVersion}`,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a patch for the auth-request.php file
|
||||
* @param overridePath - The path to override the default file path
|
||||
|
||||
Reference in New Issue
Block a user