feat: downloads widget (#844)
Usenet and Torrent downloads in 1 widget.
sabNZBd, NzbGet, Deluge, qBitTorrent, and transmission support.
Columns can be reordered in Edit mode.
Sorting enabled.
Time uses Dayjs with auto translation.
Can pause/resume single items, clients, or all.
Can delete items (With option to delete assossiated files).
Clients list and details.
Include all filtering and processing for ratio from oldmarr torrent widget.
Invalidation of old data (older than 30 seconds) to show an integration is not responding anymore.
Misc (So many miscs):
Fixed validation error with multiText.
Fixed translation application for multiSelect to behave the same as select.
Added background to gitignore (I needed to add a background to visually test opacity, probably will in the future too)
Added setOptions to frontend components so potential updates made from the Dashboard can be saved.
Extracted background and border color to use in widgets.
humanFileSize function based on the si format (powers of 1024, not 1000).
Improved integrationCreatorByKind by @Meierschlumpf.
Changed integrationCreatorByKind to integrationCreator so it functions directly from the integration.
Added integrationCreatorFromSecrets to directly work with secrets from db.
Added getIntegrationKindsByCategory to get a list of integrations sharing categories.
Added IntegrationKindByCategory type to get the types possible for a category (Great to cast on integration.kind that isn't already properly limited/typed but for which we know the limitation)
Added a common AtLeastOneOf type. Applied to TKind and IntegrationSecretKind[] where it was already being used and Added to the getIntegrationKindsByCategory's output to be more freely used.
Added the Modify type, instead of omiting to then add again just to change a parameters type, use the modify instead. Applied code wide already.
Hook to get list of integration depending on permission level of user. (By @Meierschlumpf)
2024-09-11 17:30:21 +02:00
|
|
|
import { join } from "path";
|
|
|
|
|
import { GenericContainer, getContainerRuntimeClient, ImageName, Wait } from "testcontainers";
|
|
|
|
|
import type { StartedTestContainer } from "testcontainers";
|
2025-05-16 20:59:12 +02:00
|
|
|
import { beforeAll, describe, expect, test, vi } from "vitest";
|
|
|
|
|
|
|
|
|
|
import { createDb } from "@homarr/db/test";
|
feat: downloads widget (#844)
Usenet and Torrent downloads in 1 widget.
sabNZBd, NzbGet, Deluge, qBitTorrent, and transmission support.
Columns can be reordered in Edit mode.
Sorting enabled.
Time uses Dayjs with auto translation.
Can pause/resume single items, clients, or all.
Can delete items (With option to delete assossiated files).
Clients list and details.
Include all filtering and processing for ratio from oldmarr torrent widget.
Invalidation of old data (older than 30 seconds) to show an integration is not responding anymore.
Misc (So many miscs):
Fixed validation error with multiText.
Fixed translation application for multiSelect to behave the same as select.
Added background to gitignore (I needed to add a background to visually test opacity, probably will in the future too)
Added setOptions to frontend components so potential updates made from the Dashboard can be saved.
Extracted background and border color to use in widgets.
humanFileSize function based on the si format (powers of 1024, not 1000).
Improved integrationCreatorByKind by @Meierschlumpf.
Changed integrationCreatorByKind to integrationCreator so it functions directly from the integration.
Added integrationCreatorFromSecrets to directly work with secrets from db.
Added getIntegrationKindsByCategory to get a list of integrations sharing categories.
Added IntegrationKindByCategory type to get the types possible for a category (Great to cast on integration.kind that isn't already properly limited/typed but for which we know the limitation)
Added a common AtLeastOneOf type. Applied to TKind and IntegrationSecretKind[] where it was already being used and Added to the getIntegrationKindsByCategory's output to be more freely used.
Added the Modify type, instead of omiting to then add again just to change a parameters type, use the modify instead. Applied code wide already.
Hook to get list of integration depending on permission level of user. (By @Meierschlumpf)
2024-09-11 17:30:21 +02:00
|
|
|
|
|
|
|
|
import { SabnzbdIntegration } from "../src";
|
2025-05-16 20:59:12 +02:00
|
|
|
import { TestConnectionError } from "../src/base/test-connection/test-connection-error";
|
feat: downloads widget (#844)
Usenet and Torrent downloads in 1 widget.
sabNZBd, NzbGet, Deluge, qBitTorrent, and transmission support.
Columns can be reordered in Edit mode.
Sorting enabled.
Time uses Dayjs with auto translation.
Can pause/resume single items, clients, or all.
Can delete items (With option to delete assossiated files).
Clients list and details.
Include all filtering and processing for ratio from oldmarr torrent widget.
Invalidation of old data (older than 30 seconds) to show an integration is not responding anymore.
Misc (So many miscs):
Fixed validation error with multiText.
Fixed translation application for multiSelect to behave the same as select.
Added background to gitignore (I needed to add a background to visually test opacity, probably will in the future too)
Added setOptions to frontend components so potential updates made from the Dashboard can be saved.
Extracted background and border color to use in widgets.
humanFileSize function based on the si format (powers of 1024, not 1000).
Improved integrationCreatorByKind by @Meierschlumpf.
Changed integrationCreatorByKind to integrationCreator so it functions directly from the integration.
Added integrationCreatorFromSecrets to directly work with secrets from db.
Added getIntegrationKindsByCategory to get a list of integrations sharing categories.
Added IntegrationKindByCategory type to get the types possible for a category (Great to cast on integration.kind that isn't already properly limited/typed but for which we know the limitation)
Added a common AtLeastOneOf type. Applied to TKind and IntegrationSecretKind[] where it was already being used and Added to the getIntegrationKindsByCategory's output to be more freely used.
Added the Modify type, instead of omiting to then add again just to change a parameters type, use the modify instead. Applied code wide already.
Hook to get list of integration depending on permission level of user. (By @Meierschlumpf)
2024-09-11 17:30:21 +02:00
|
|
|
import type { DownloadClientItem } from "../src/interfaces/downloads/download-client-items";
|
|
|
|
|
|
2025-05-16 20:59:12 +02:00
|
|
|
vi.mock("@homarr/db", async (importActual) => {
|
|
|
|
|
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
|
|
|
|
|
const actual = await importActual<typeof import("@homarr/db")>();
|
|
|
|
|
return {
|
|
|
|
|
...actual,
|
|
|
|
|
db: createDb(),
|
|
|
|
|
};
|
|
|
|
|
});
|
|
|
|
|
|
feat: downloads widget (#844)
Usenet and Torrent downloads in 1 widget.
sabNZBd, NzbGet, Deluge, qBitTorrent, and transmission support.
Columns can be reordered in Edit mode.
Sorting enabled.
Time uses Dayjs with auto translation.
Can pause/resume single items, clients, or all.
Can delete items (With option to delete assossiated files).
Clients list and details.
Include all filtering and processing for ratio from oldmarr torrent widget.
Invalidation of old data (older than 30 seconds) to show an integration is not responding anymore.
Misc (So many miscs):
Fixed validation error with multiText.
Fixed translation application for multiSelect to behave the same as select.
Added background to gitignore (I needed to add a background to visually test opacity, probably will in the future too)
Added setOptions to frontend components so potential updates made from the Dashboard can be saved.
Extracted background and border color to use in widgets.
humanFileSize function based on the si format (powers of 1024, not 1000).
Improved integrationCreatorByKind by @Meierschlumpf.
Changed integrationCreatorByKind to integrationCreator so it functions directly from the integration.
Added integrationCreatorFromSecrets to directly work with secrets from db.
Added getIntegrationKindsByCategory to get a list of integrations sharing categories.
Added IntegrationKindByCategory type to get the types possible for a category (Great to cast on integration.kind that isn't already properly limited/typed but for which we know the limitation)
Added a common AtLeastOneOf type. Applied to TKind and IntegrationSecretKind[] where it was already being used and Added to the getIntegrationKindsByCategory's output to be more freely used.
Added the Modify type, instead of omiting to then add again just to change a parameters type, use the modify instead. Applied code wide already.
Hook to get list of integration depending on permission level of user. (By @Meierschlumpf)
2024-09-11 17:30:21 +02:00
|
|
|
const DEFAULT_API_KEY = "8r45mfes43s3iw7x3oecto6dl9ilxnf9";
|
|
|
|
|
const IMAGE_NAME = "linuxserver/sabnzbd:latest";
|
|
|
|
|
|
|
|
|
|
describe("Sabnzbd integration", () => {
|
|
|
|
|
beforeAll(async () => {
|
|
|
|
|
const containerRuntimeClient = await getContainerRuntimeClient();
|
|
|
|
|
await containerRuntimeClient.image.pull(ImageName.fromString(IMAGE_NAME));
|
|
|
|
|
}, 100_000);
|
|
|
|
|
|
|
|
|
|
test("Test connection should work", async () => {
|
|
|
|
|
// Arrange
|
|
|
|
|
const startedContainer = await createSabnzbdContainer().start();
|
|
|
|
|
const sabnzbdIntegration = createSabnzbdIntegration(startedContainer, DEFAULT_API_KEY);
|
|
|
|
|
|
|
|
|
|
// Act
|
2025-05-16 20:59:12 +02:00
|
|
|
const result = await sabnzbdIntegration.testConnectionAsync();
|
feat: downloads widget (#844)
Usenet and Torrent downloads in 1 widget.
sabNZBd, NzbGet, Deluge, qBitTorrent, and transmission support.
Columns can be reordered in Edit mode.
Sorting enabled.
Time uses Dayjs with auto translation.
Can pause/resume single items, clients, or all.
Can delete items (With option to delete assossiated files).
Clients list and details.
Include all filtering and processing for ratio from oldmarr torrent widget.
Invalidation of old data (older than 30 seconds) to show an integration is not responding anymore.
Misc (So many miscs):
Fixed validation error with multiText.
Fixed translation application for multiSelect to behave the same as select.
Added background to gitignore (I needed to add a background to visually test opacity, probably will in the future too)
Added setOptions to frontend components so potential updates made from the Dashboard can be saved.
Extracted background and border color to use in widgets.
humanFileSize function based on the si format (powers of 1024, not 1000).
Improved integrationCreatorByKind by @Meierschlumpf.
Changed integrationCreatorByKind to integrationCreator so it functions directly from the integration.
Added integrationCreatorFromSecrets to directly work with secrets from db.
Added getIntegrationKindsByCategory to get a list of integrations sharing categories.
Added IntegrationKindByCategory type to get the types possible for a category (Great to cast on integration.kind that isn't already properly limited/typed but for which we know the limitation)
Added a common AtLeastOneOf type. Applied to TKind and IntegrationSecretKind[] where it was already being used and Added to the getIntegrationKindsByCategory's output to be more freely used.
Added the Modify type, instead of omiting to then add again just to change a parameters type, use the modify instead. Applied code wide already.
Hook to get list of integration depending on permission level of user. (By @Meierschlumpf)
2024-09-11 17:30:21 +02:00
|
|
|
|
|
|
|
|
// Assert
|
2025-05-16 20:59:12 +02:00
|
|
|
expect(result.success).toBe(true);
|
feat: downloads widget (#844)
Usenet and Torrent downloads in 1 widget.
sabNZBd, NzbGet, Deluge, qBitTorrent, and transmission support.
Columns can be reordered in Edit mode.
Sorting enabled.
Time uses Dayjs with auto translation.
Can pause/resume single items, clients, or all.
Can delete items (With option to delete assossiated files).
Clients list and details.
Include all filtering and processing for ratio from oldmarr torrent widget.
Invalidation of old data (older than 30 seconds) to show an integration is not responding anymore.
Misc (So many miscs):
Fixed validation error with multiText.
Fixed translation application for multiSelect to behave the same as select.
Added background to gitignore (I needed to add a background to visually test opacity, probably will in the future too)
Added setOptions to frontend components so potential updates made from the Dashboard can be saved.
Extracted background and border color to use in widgets.
humanFileSize function based on the si format (powers of 1024, not 1000).
Improved integrationCreatorByKind by @Meierschlumpf.
Changed integrationCreatorByKind to integrationCreator so it functions directly from the integration.
Added integrationCreatorFromSecrets to directly work with secrets from db.
Added getIntegrationKindsByCategory to get a list of integrations sharing categories.
Added IntegrationKindByCategory type to get the types possible for a category (Great to cast on integration.kind that isn't already properly limited/typed but for which we know the limitation)
Added a common AtLeastOneOf type. Applied to TKind and IntegrationSecretKind[] where it was already being used and Added to the getIntegrationKindsByCategory's output to be more freely used.
Added the Modify type, instead of omiting to then add again just to change a parameters type, use the modify instead. Applied code wide already.
Hook to get list of integration depending on permission level of user. (By @Meierschlumpf)
2024-09-11 17:30:21 +02:00
|
|
|
|
|
|
|
|
// Cleanup
|
|
|
|
|
await startedContainer.stop();
|
2024-12-16 15:06:31 +01:00
|
|
|
}, 30_000); // Timeout of 30 seconds
|
feat: downloads widget (#844)
Usenet and Torrent downloads in 1 widget.
sabNZBd, NzbGet, Deluge, qBitTorrent, and transmission support.
Columns can be reordered in Edit mode.
Sorting enabled.
Time uses Dayjs with auto translation.
Can pause/resume single items, clients, or all.
Can delete items (With option to delete assossiated files).
Clients list and details.
Include all filtering and processing for ratio from oldmarr torrent widget.
Invalidation of old data (older than 30 seconds) to show an integration is not responding anymore.
Misc (So many miscs):
Fixed validation error with multiText.
Fixed translation application for multiSelect to behave the same as select.
Added background to gitignore (I needed to add a background to visually test opacity, probably will in the future too)
Added setOptions to frontend components so potential updates made from the Dashboard can be saved.
Extracted background and border color to use in widgets.
humanFileSize function based on the si format (powers of 1024, not 1000).
Improved integrationCreatorByKind by @Meierschlumpf.
Changed integrationCreatorByKind to integrationCreator so it functions directly from the integration.
Added integrationCreatorFromSecrets to directly work with secrets from db.
Added getIntegrationKindsByCategory to get a list of integrations sharing categories.
Added IntegrationKindByCategory type to get the types possible for a category (Great to cast on integration.kind that isn't already properly limited/typed but for which we know the limitation)
Added a common AtLeastOneOf type. Applied to TKind and IntegrationSecretKind[] where it was already being used and Added to the getIntegrationKindsByCategory's output to be more freely used.
Added the Modify type, instead of omiting to then add again just to change a parameters type, use the modify instead. Applied code wide already.
Hook to get list of integration depending on permission level of user. (By @Meierschlumpf)
2024-09-11 17:30:21 +02:00
|
|
|
|
|
|
|
|
test("Test connection should fail with wrong ApiKey", async () => {
|
|
|
|
|
// Arrange
|
|
|
|
|
const startedContainer = await createSabnzbdContainer().start();
|
|
|
|
|
const sabnzbdIntegration = createSabnzbdIntegration(startedContainer, "wrong-api-key");
|
|
|
|
|
|
|
|
|
|
// Act
|
2025-05-16 20:59:12 +02:00
|
|
|
const result = await sabnzbdIntegration.testConnectionAsync();
|
feat: downloads widget (#844)
Usenet and Torrent downloads in 1 widget.
sabNZBd, NzbGet, Deluge, qBitTorrent, and transmission support.
Columns can be reordered in Edit mode.
Sorting enabled.
Time uses Dayjs with auto translation.
Can pause/resume single items, clients, or all.
Can delete items (With option to delete assossiated files).
Clients list and details.
Include all filtering and processing for ratio from oldmarr torrent widget.
Invalidation of old data (older than 30 seconds) to show an integration is not responding anymore.
Misc (So many miscs):
Fixed validation error with multiText.
Fixed translation application for multiSelect to behave the same as select.
Added background to gitignore (I needed to add a background to visually test opacity, probably will in the future too)
Added setOptions to frontend components so potential updates made from the Dashboard can be saved.
Extracted background and border color to use in widgets.
humanFileSize function based on the si format (powers of 1024, not 1000).
Improved integrationCreatorByKind by @Meierschlumpf.
Changed integrationCreatorByKind to integrationCreator so it functions directly from the integration.
Added integrationCreatorFromSecrets to directly work with secrets from db.
Added getIntegrationKindsByCategory to get a list of integrations sharing categories.
Added IntegrationKindByCategory type to get the types possible for a category (Great to cast on integration.kind that isn't already properly limited/typed but for which we know the limitation)
Added a common AtLeastOneOf type. Applied to TKind and IntegrationSecretKind[] where it was already being used and Added to the getIntegrationKindsByCategory's output to be more freely used.
Added the Modify type, instead of omiting to then add again just to change a parameters type, use the modify instead. Applied code wide already.
Hook to get list of integration depending on permission level of user. (By @Meierschlumpf)
2024-09-11 17:30:21 +02:00
|
|
|
|
|
|
|
|
// Assert
|
2025-05-16 20:59:12 +02:00
|
|
|
expect(result.success).toBe(false);
|
|
|
|
|
if (result.success) return;
|
|
|
|
|
expect(result.error).toBeInstanceOf(TestConnectionError);
|
|
|
|
|
expect(result.error.type).toBe("authorization");
|
feat: downloads widget (#844)
Usenet and Torrent downloads in 1 widget.
sabNZBd, NzbGet, Deluge, qBitTorrent, and transmission support.
Columns can be reordered in Edit mode.
Sorting enabled.
Time uses Dayjs with auto translation.
Can pause/resume single items, clients, or all.
Can delete items (With option to delete assossiated files).
Clients list and details.
Include all filtering and processing for ratio from oldmarr torrent widget.
Invalidation of old data (older than 30 seconds) to show an integration is not responding anymore.
Misc (So many miscs):
Fixed validation error with multiText.
Fixed translation application for multiSelect to behave the same as select.
Added background to gitignore (I needed to add a background to visually test opacity, probably will in the future too)
Added setOptions to frontend components so potential updates made from the Dashboard can be saved.
Extracted background and border color to use in widgets.
humanFileSize function based on the si format (powers of 1024, not 1000).
Improved integrationCreatorByKind by @Meierschlumpf.
Changed integrationCreatorByKind to integrationCreator so it functions directly from the integration.
Added integrationCreatorFromSecrets to directly work with secrets from db.
Added getIntegrationKindsByCategory to get a list of integrations sharing categories.
Added IntegrationKindByCategory type to get the types possible for a category (Great to cast on integration.kind that isn't already properly limited/typed but for which we know the limitation)
Added a common AtLeastOneOf type. Applied to TKind and IntegrationSecretKind[] where it was already being used and Added to the getIntegrationKindsByCategory's output to be more freely used.
Added the Modify type, instead of omiting to then add again just to change a parameters type, use the modify instead. Applied code wide already.
Hook to get list of integration depending on permission level of user. (By @Meierschlumpf)
2024-09-11 17:30:21 +02:00
|
|
|
|
|
|
|
|
// Cleanup
|
|
|
|
|
await startedContainer.stop();
|
2024-12-16 15:06:31 +01:00
|
|
|
}, 30_000); // Timeout of 30 seconds
|
feat: downloads widget (#844)
Usenet and Torrent downloads in 1 widget.
sabNZBd, NzbGet, Deluge, qBitTorrent, and transmission support.
Columns can be reordered in Edit mode.
Sorting enabled.
Time uses Dayjs with auto translation.
Can pause/resume single items, clients, or all.
Can delete items (With option to delete assossiated files).
Clients list and details.
Include all filtering and processing for ratio from oldmarr torrent widget.
Invalidation of old data (older than 30 seconds) to show an integration is not responding anymore.
Misc (So many miscs):
Fixed validation error with multiText.
Fixed translation application for multiSelect to behave the same as select.
Added background to gitignore (I needed to add a background to visually test opacity, probably will in the future too)
Added setOptions to frontend components so potential updates made from the Dashboard can be saved.
Extracted background and border color to use in widgets.
humanFileSize function based on the si format (powers of 1024, not 1000).
Improved integrationCreatorByKind by @Meierschlumpf.
Changed integrationCreatorByKind to integrationCreator so it functions directly from the integration.
Added integrationCreatorFromSecrets to directly work with secrets from db.
Added getIntegrationKindsByCategory to get a list of integrations sharing categories.
Added IntegrationKindByCategory type to get the types possible for a category (Great to cast on integration.kind that isn't already properly limited/typed but for which we know the limitation)
Added a common AtLeastOneOf type. Applied to TKind and IntegrationSecretKind[] where it was already being used and Added to the getIntegrationKindsByCategory's output to be more freely used.
Added the Modify type, instead of omiting to then add again just to change a parameters type, use the modify instead. Applied code wide already.
Hook to get list of integration depending on permission level of user. (By @Meierschlumpf)
2024-09-11 17:30:21 +02:00
|
|
|
|
|
|
|
|
test("pauseQueueAsync should work", async () => {
|
|
|
|
|
// Arrange
|
|
|
|
|
const startedContainer = await createSabnzbdContainer().start();
|
|
|
|
|
const sabnzbdIntegration = createSabnzbdIntegration(startedContainer, DEFAULT_API_KEY);
|
|
|
|
|
|
|
|
|
|
// Acts
|
|
|
|
|
const actAsync = async () => await sabnzbdIntegration.pauseQueueAsync();
|
|
|
|
|
const getAsync = async () => await sabnzbdIntegration.getClientJobsAndStatusAsync();
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
await expect(actAsync()).resolves.not.toThrow();
|
|
|
|
|
await expect(getAsync()).resolves.toMatchObject({ status: { paused: true } });
|
|
|
|
|
|
|
|
|
|
// Cleanup
|
|
|
|
|
await startedContainer.stop();
|
2024-12-16 15:06:31 +01:00
|
|
|
}, 30_000); // Timeout of 30 seconds
|
feat: downloads widget (#844)
Usenet and Torrent downloads in 1 widget.
sabNZBd, NzbGet, Deluge, qBitTorrent, and transmission support.
Columns can be reordered in Edit mode.
Sorting enabled.
Time uses Dayjs with auto translation.
Can pause/resume single items, clients, or all.
Can delete items (With option to delete assossiated files).
Clients list and details.
Include all filtering and processing for ratio from oldmarr torrent widget.
Invalidation of old data (older than 30 seconds) to show an integration is not responding anymore.
Misc (So many miscs):
Fixed validation error with multiText.
Fixed translation application for multiSelect to behave the same as select.
Added background to gitignore (I needed to add a background to visually test opacity, probably will in the future too)
Added setOptions to frontend components so potential updates made from the Dashboard can be saved.
Extracted background and border color to use in widgets.
humanFileSize function based on the si format (powers of 1024, not 1000).
Improved integrationCreatorByKind by @Meierschlumpf.
Changed integrationCreatorByKind to integrationCreator so it functions directly from the integration.
Added integrationCreatorFromSecrets to directly work with secrets from db.
Added getIntegrationKindsByCategory to get a list of integrations sharing categories.
Added IntegrationKindByCategory type to get the types possible for a category (Great to cast on integration.kind that isn't already properly limited/typed but for which we know the limitation)
Added a common AtLeastOneOf type. Applied to TKind and IntegrationSecretKind[] where it was already being used and Added to the getIntegrationKindsByCategory's output to be more freely used.
Added the Modify type, instead of omiting to then add again just to change a parameters type, use the modify instead. Applied code wide already.
Hook to get list of integration depending on permission level of user. (By @Meierschlumpf)
2024-09-11 17:30:21 +02:00
|
|
|
|
|
|
|
|
test("resumeQueueAsync should work", async () => {
|
|
|
|
|
// Arrange
|
|
|
|
|
const startedContainer = await createSabnzbdContainer().start();
|
|
|
|
|
const sabnzbdIntegration = createSabnzbdIntegration(startedContainer, DEFAULT_API_KEY);
|
|
|
|
|
await sabnzbdIntegration.pauseQueueAsync();
|
|
|
|
|
|
|
|
|
|
// Acts
|
|
|
|
|
const actAsync = async () => await sabnzbdIntegration.resumeQueueAsync();
|
|
|
|
|
const getAsync = async () => await sabnzbdIntegration.getClientJobsAndStatusAsync();
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
await expect(actAsync()).resolves.not.toThrow();
|
|
|
|
|
await expect(getAsync()).resolves.toMatchObject({
|
|
|
|
|
status: { paused: false },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Cleanup
|
|
|
|
|
await startedContainer.stop();
|
2024-12-16 15:06:31 +01:00
|
|
|
}, 30_000); // Timeout of 30 seconds
|
feat: downloads widget (#844)
Usenet and Torrent downloads in 1 widget.
sabNZBd, NzbGet, Deluge, qBitTorrent, and transmission support.
Columns can be reordered in Edit mode.
Sorting enabled.
Time uses Dayjs with auto translation.
Can pause/resume single items, clients, or all.
Can delete items (With option to delete assossiated files).
Clients list and details.
Include all filtering and processing for ratio from oldmarr torrent widget.
Invalidation of old data (older than 30 seconds) to show an integration is not responding anymore.
Misc (So many miscs):
Fixed validation error with multiText.
Fixed translation application for multiSelect to behave the same as select.
Added background to gitignore (I needed to add a background to visually test opacity, probably will in the future too)
Added setOptions to frontend components so potential updates made from the Dashboard can be saved.
Extracted background and border color to use in widgets.
humanFileSize function based on the si format (powers of 1024, not 1000).
Improved integrationCreatorByKind by @Meierschlumpf.
Changed integrationCreatorByKind to integrationCreator so it functions directly from the integration.
Added integrationCreatorFromSecrets to directly work with secrets from db.
Added getIntegrationKindsByCategory to get a list of integrations sharing categories.
Added IntegrationKindByCategory type to get the types possible for a category (Great to cast on integration.kind that isn't already properly limited/typed but for which we know the limitation)
Added a common AtLeastOneOf type. Applied to TKind and IntegrationSecretKind[] where it was already being used and Added to the getIntegrationKindsByCategory's output to be more freely used.
Added the Modify type, instead of omiting to then add again just to change a parameters type, use the modify instead. Applied code wide already.
Hook to get list of integration depending on permission level of user. (By @Meierschlumpf)
2024-09-11 17:30:21 +02:00
|
|
|
|
|
|
|
|
test("Items should be empty", async () => {
|
|
|
|
|
// Arrange
|
|
|
|
|
const startedContainer = await createSabnzbdContainer().start();
|
|
|
|
|
const sabnzbdIntegration = createSabnzbdIntegration(startedContainer, DEFAULT_API_KEY);
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
const getAsync = async () => await sabnzbdIntegration.getClientJobsAndStatusAsync();
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
await expect(getAsync()).resolves.not.toThrow();
|
|
|
|
|
await expect(getAsync()).resolves.toMatchObject({
|
|
|
|
|
items: [],
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Cleanup
|
|
|
|
|
await startedContainer.stop();
|
2024-12-16 15:06:31 +01:00
|
|
|
}, 30_000); // Timeout of 30 seconds
|
feat: downloads widget (#844)
Usenet and Torrent downloads in 1 widget.
sabNZBd, NzbGet, Deluge, qBitTorrent, and transmission support.
Columns can be reordered in Edit mode.
Sorting enabled.
Time uses Dayjs with auto translation.
Can pause/resume single items, clients, or all.
Can delete items (With option to delete assossiated files).
Clients list and details.
Include all filtering and processing for ratio from oldmarr torrent widget.
Invalidation of old data (older than 30 seconds) to show an integration is not responding anymore.
Misc (So many miscs):
Fixed validation error with multiText.
Fixed translation application for multiSelect to behave the same as select.
Added background to gitignore (I needed to add a background to visually test opacity, probably will in the future too)
Added setOptions to frontend components so potential updates made from the Dashboard can be saved.
Extracted background and border color to use in widgets.
humanFileSize function based on the si format (powers of 1024, not 1000).
Improved integrationCreatorByKind by @Meierschlumpf.
Changed integrationCreatorByKind to integrationCreator so it functions directly from the integration.
Added integrationCreatorFromSecrets to directly work with secrets from db.
Added getIntegrationKindsByCategory to get a list of integrations sharing categories.
Added IntegrationKindByCategory type to get the types possible for a category (Great to cast on integration.kind that isn't already properly limited/typed but for which we know the limitation)
Added a common AtLeastOneOf type. Applied to TKind and IntegrationSecretKind[] where it was already being used and Added to the getIntegrationKindsByCategory's output to be more freely used.
Added the Modify type, instead of omiting to then add again just to change a parameters type, use the modify instead. Applied code wide already.
Hook to get list of integration depending on permission level of user. (By @Meierschlumpf)
2024-09-11 17:30:21 +02:00
|
|
|
|
|
|
|
|
test("1 Items should exist after adding one", async () => {
|
|
|
|
|
// Arrange
|
|
|
|
|
const startedContainer = await createSabnzbdContainer().start();
|
|
|
|
|
const sabnzbdIntegration = createSabnzbdIntegration(startedContainer, DEFAULT_API_KEY);
|
|
|
|
|
await sabNzbdAddItemAsync(startedContainer, DEFAULT_API_KEY, sabnzbdIntegration);
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
const getAsync = async () => await sabnzbdIntegration.getClientJobsAndStatusAsync();
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
await expect(getAsync()).resolves.not.toThrow();
|
|
|
|
|
expect((await getAsync()).items).toHaveLength(1);
|
|
|
|
|
|
|
|
|
|
// Cleanup
|
|
|
|
|
await startedContainer.stop();
|
2024-12-16 15:06:31 +01:00
|
|
|
}, 30_000); // Timeout of 30 seconds
|
feat: downloads widget (#844)
Usenet and Torrent downloads in 1 widget.
sabNZBd, NzbGet, Deluge, qBitTorrent, and transmission support.
Columns can be reordered in Edit mode.
Sorting enabled.
Time uses Dayjs with auto translation.
Can pause/resume single items, clients, or all.
Can delete items (With option to delete assossiated files).
Clients list and details.
Include all filtering and processing for ratio from oldmarr torrent widget.
Invalidation of old data (older than 30 seconds) to show an integration is not responding anymore.
Misc (So many miscs):
Fixed validation error with multiText.
Fixed translation application for multiSelect to behave the same as select.
Added background to gitignore (I needed to add a background to visually test opacity, probably will in the future too)
Added setOptions to frontend components so potential updates made from the Dashboard can be saved.
Extracted background and border color to use in widgets.
humanFileSize function based on the si format (powers of 1024, not 1000).
Improved integrationCreatorByKind by @Meierschlumpf.
Changed integrationCreatorByKind to integrationCreator so it functions directly from the integration.
Added integrationCreatorFromSecrets to directly work with secrets from db.
Added getIntegrationKindsByCategory to get a list of integrations sharing categories.
Added IntegrationKindByCategory type to get the types possible for a category (Great to cast on integration.kind that isn't already properly limited/typed but for which we know the limitation)
Added a common AtLeastOneOf type. Applied to TKind and IntegrationSecretKind[] where it was already being used and Added to the getIntegrationKindsByCategory's output to be more freely used.
Added the Modify type, instead of omiting to then add again just to change a parameters type, use the modify instead. Applied code wide already.
Hook to get list of integration depending on permission level of user. (By @Meierschlumpf)
2024-09-11 17:30:21 +02:00
|
|
|
|
|
|
|
|
test("Pause item should work", async () => {
|
|
|
|
|
// Arrange
|
|
|
|
|
const startedContainer = await createSabnzbdContainer().start();
|
|
|
|
|
const sabnzbdIntegration = createSabnzbdIntegration(startedContainer, DEFAULT_API_KEY);
|
|
|
|
|
const item = await sabNzbdAddItemAsync(startedContainer, DEFAULT_API_KEY, sabnzbdIntegration);
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
const actAsync = async () => await sabnzbdIntegration.pauseItemAsync(item);
|
|
|
|
|
const getAsync = async () => await sabnzbdIntegration.getClientJobsAndStatusAsync();
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
await expect(getAsync()).resolves.toMatchObject({ items: [{ ...item, state: "downloading" }] });
|
|
|
|
|
await expect(actAsync()).resolves.not.toThrow();
|
|
|
|
|
await expect(getAsync()).resolves.toMatchObject({ items: [{ ...item, state: "paused" }] });
|
|
|
|
|
|
|
|
|
|
// Cleanup
|
|
|
|
|
await startedContainer.stop();
|
2024-12-16 15:06:31 +01:00
|
|
|
}, 30_000); // Timeout of 30 seconds
|
feat: downloads widget (#844)
Usenet and Torrent downloads in 1 widget.
sabNZBd, NzbGet, Deluge, qBitTorrent, and transmission support.
Columns can be reordered in Edit mode.
Sorting enabled.
Time uses Dayjs with auto translation.
Can pause/resume single items, clients, or all.
Can delete items (With option to delete assossiated files).
Clients list and details.
Include all filtering and processing for ratio from oldmarr torrent widget.
Invalidation of old data (older than 30 seconds) to show an integration is not responding anymore.
Misc (So many miscs):
Fixed validation error with multiText.
Fixed translation application for multiSelect to behave the same as select.
Added background to gitignore (I needed to add a background to visually test opacity, probably will in the future too)
Added setOptions to frontend components so potential updates made from the Dashboard can be saved.
Extracted background and border color to use in widgets.
humanFileSize function based on the si format (powers of 1024, not 1000).
Improved integrationCreatorByKind by @Meierschlumpf.
Changed integrationCreatorByKind to integrationCreator so it functions directly from the integration.
Added integrationCreatorFromSecrets to directly work with secrets from db.
Added getIntegrationKindsByCategory to get a list of integrations sharing categories.
Added IntegrationKindByCategory type to get the types possible for a category (Great to cast on integration.kind that isn't already properly limited/typed but for which we know the limitation)
Added a common AtLeastOneOf type. Applied to TKind and IntegrationSecretKind[] where it was already being used and Added to the getIntegrationKindsByCategory's output to be more freely used.
Added the Modify type, instead of omiting to then add again just to change a parameters type, use the modify instead. Applied code wide already.
Hook to get list of integration depending on permission level of user. (By @Meierschlumpf)
2024-09-11 17:30:21 +02:00
|
|
|
|
|
|
|
|
test("Resume item should work", async () => {
|
|
|
|
|
// Arrange
|
|
|
|
|
const startedContainer = await createSabnzbdContainer().start();
|
|
|
|
|
const sabnzbdIntegration = createSabnzbdIntegration(startedContainer, DEFAULT_API_KEY);
|
|
|
|
|
const item = await sabNzbdAddItemAsync(startedContainer, DEFAULT_API_KEY, sabnzbdIntegration);
|
|
|
|
|
await sabnzbdIntegration.pauseItemAsync(item);
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
const actAsync = async () => await sabnzbdIntegration.resumeItemAsync(item);
|
|
|
|
|
const getAsync = async () => await sabnzbdIntegration.getClientJobsAndStatusAsync();
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
await expect(getAsync()).resolves.toMatchObject({ items: [{ ...item, state: "paused" }] });
|
|
|
|
|
await expect(actAsync()).resolves.not.toThrow();
|
|
|
|
|
await expect(getAsync()).resolves.toMatchObject({ items: [{ ...item, state: "downloading" }] });
|
|
|
|
|
|
|
|
|
|
// Cleanup
|
|
|
|
|
await startedContainer.stop();
|
2024-12-16 15:06:31 +01:00
|
|
|
}, 30_000); // Timeout of 30 seconds
|
feat: downloads widget (#844)
Usenet and Torrent downloads in 1 widget.
sabNZBd, NzbGet, Deluge, qBitTorrent, and transmission support.
Columns can be reordered in Edit mode.
Sorting enabled.
Time uses Dayjs with auto translation.
Can pause/resume single items, clients, or all.
Can delete items (With option to delete assossiated files).
Clients list and details.
Include all filtering and processing for ratio from oldmarr torrent widget.
Invalidation of old data (older than 30 seconds) to show an integration is not responding anymore.
Misc (So many miscs):
Fixed validation error with multiText.
Fixed translation application for multiSelect to behave the same as select.
Added background to gitignore (I needed to add a background to visually test opacity, probably will in the future too)
Added setOptions to frontend components so potential updates made from the Dashboard can be saved.
Extracted background and border color to use in widgets.
humanFileSize function based on the si format (powers of 1024, not 1000).
Improved integrationCreatorByKind by @Meierschlumpf.
Changed integrationCreatorByKind to integrationCreator so it functions directly from the integration.
Added integrationCreatorFromSecrets to directly work with secrets from db.
Added getIntegrationKindsByCategory to get a list of integrations sharing categories.
Added IntegrationKindByCategory type to get the types possible for a category (Great to cast on integration.kind that isn't already properly limited/typed but for which we know the limitation)
Added a common AtLeastOneOf type. Applied to TKind and IntegrationSecretKind[] where it was already being used and Added to the getIntegrationKindsByCategory's output to be more freely used.
Added the Modify type, instead of omiting to then add again just to change a parameters type, use the modify instead. Applied code wide already.
Hook to get list of integration depending on permission level of user. (By @Meierschlumpf)
2024-09-11 17:30:21 +02:00
|
|
|
|
|
|
|
|
test("Delete item should result in empty items", async () => {
|
|
|
|
|
// Arrange
|
|
|
|
|
const startedContainer = await createSabnzbdContainer().start();
|
|
|
|
|
const sabnzbdIntegration = createSabnzbdIntegration(startedContainer, DEFAULT_API_KEY);
|
|
|
|
|
const item = await sabNzbdAddItemAsync(startedContainer, DEFAULT_API_KEY, sabnzbdIntegration);
|
|
|
|
|
|
|
|
|
|
// Act - fromDisk already doesn't work for sabnzbd, so only test deletion itself.
|
|
|
|
|
const actAsync = async () =>
|
|
|
|
|
await sabnzbdIntegration.deleteItemAsync({ ...item, progress: 0 } as DownloadClientItem, false);
|
|
|
|
|
const getAsync = async () => await sabnzbdIntegration.getClientJobsAndStatusAsync();
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
await expect(actAsync()).resolves.not.toThrow();
|
|
|
|
|
await expect(getAsync()).resolves.toMatchObject({ items: [] });
|
|
|
|
|
|
|
|
|
|
// Cleanup
|
|
|
|
|
await startedContainer.stop();
|
2024-12-16 15:06:31 +01:00
|
|
|
}, 30_000); // Timeout of 30 seconds
|
feat: downloads widget (#844)
Usenet and Torrent downloads in 1 widget.
sabNZBd, NzbGet, Deluge, qBitTorrent, and transmission support.
Columns can be reordered in Edit mode.
Sorting enabled.
Time uses Dayjs with auto translation.
Can pause/resume single items, clients, or all.
Can delete items (With option to delete assossiated files).
Clients list and details.
Include all filtering and processing for ratio from oldmarr torrent widget.
Invalidation of old data (older than 30 seconds) to show an integration is not responding anymore.
Misc (So many miscs):
Fixed validation error with multiText.
Fixed translation application for multiSelect to behave the same as select.
Added background to gitignore (I needed to add a background to visually test opacity, probably will in the future too)
Added setOptions to frontend components so potential updates made from the Dashboard can be saved.
Extracted background and border color to use in widgets.
humanFileSize function based on the si format (powers of 1024, not 1000).
Improved integrationCreatorByKind by @Meierschlumpf.
Changed integrationCreatorByKind to integrationCreator so it functions directly from the integration.
Added integrationCreatorFromSecrets to directly work with secrets from db.
Added getIntegrationKindsByCategory to get a list of integrations sharing categories.
Added IntegrationKindByCategory type to get the types possible for a category (Great to cast on integration.kind that isn't already properly limited/typed but for which we know the limitation)
Added a common AtLeastOneOf type. Applied to TKind and IntegrationSecretKind[] where it was already being used and Added to the getIntegrationKindsByCategory's output to be more freely used.
Added the Modify type, instead of omiting to then add again just to change a parameters type, use the modify instead. Applied code wide already.
Hook to get list of integration depending on permission level of user. (By @Meierschlumpf)
2024-09-11 17:30:21 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const createSabnzbdContainer = () => {
|
|
|
|
|
return new GenericContainer(IMAGE_NAME)
|
|
|
|
|
.withCopyFilesToContainer([
|
|
|
|
|
{
|
|
|
|
|
source: join(__dirname, "/volumes/usenet/sabnzbd.ini"),
|
|
|
|
|
target: "/config/sabnzbd.ini",
|
|
|
|
|
},
|
|
|
|
|
])
|
|
|
|
|
.withExposedPorts(1212)
|
|
|
|
|
.withEnvironment({ PUID: "0", PGID: "0" })
|
|
|
|
|
.withWaitStrategy(Wait.forHttp("/", 1212));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const createSabnzbdIntegration = (container: StartedTestContainer, apiKey: string) => {
|
|
|
|
|
return new SabnzbdIntegration({
|
|
|
|
|
id: "1",
|
|
|
|
|
decryptedSecrets: [
|
|
|
|
|
{
|
|
|
|
|
kind: "apiKey",
|
|
|
|
|
value: apiKey,
|
|
|
|
|
},
|
|
|
|
|
],
|
|
|
|
|
name: "Sabnzbd",
|
|
|
|
|
url: `http://${container.getHost()}:${container.getMappedPort(1212)}`,
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const sabNzbdAddItemAsync = async (
|
|
|
|
|
container: StartedTestContainer,
|
|
|
|
|
apiKey: string,
|
|
|
|
|
integration: SabnzbdIntegration,
|
|
|
|
|
) => {
|
|
|
|
|
// Add nzb file in the watch folder
|
|
|
|
|
await container.copyFilesToContainer([
|
|
|
|
|
{
|
|
|
|
|
source: join(__dirname, "/volumes/usenet/test_download_100MB.nzb"),
|
|
|
|
|
target: "/nzb/test_download_100MB.nzb",
|
|
|
|
|
},
|
|
|
|
|
]);
|
|
|
|
|
// Adding file is faster than triggering scan of the watch folder
|
|
|
|
|
// (local add: 1.4-1.6s, scan trigger: 2.5-2.7s, auto scan: 2.9-3s)
|
|
|
|
|
await fetch(
|
|
|
|
|
`http://${container.getHost()}:${container.getMappedPort(1212)}/api` +
|
|
|
|
|
"?mode=addlocalfile" +
|
|
|
|
|
"&name=%2Fnzb%2Ftest_download_100MB.nzb" +
|
|
|
|
|
`&apikey=${apiKey}`,
|
|
|
|
|
);
|
|
|
|
|
// Retries up to 5 times to let SabNzbd scan and process the nzb (1 retry should suffice tbh)
|
|
|
|
|
for (let i = 0; i < 5; i++) {
|
|
|
|
|
const {
|
|
|
|
|
items: [item],
|
|
|
|
|
} = await integration.getClientJobsAndStatusAsync();
|
|
|
|
|
if (item) return item;
|
|
|
|
|
}
|
|
|
|
|
// Throws if it can't find the item
|
|
|
|
|
throw new Error("No item found");
|
|
|
|
|
};
|