test: cover non-S3 rclone destination routing

This commit is contained in:
Furox 2026-09-04 20:34:41 +03:00 committed by Furox88
parent d96e7f7c30
commit a52768e8f0

View File

@ -1,4 +1,8 @@
import { normalizeS3Path } from "@dokploy/server/utils/backups/utils";
import { RCLONE_DESTINATION_PROVIDERS } from "@dokploy/server/db/validations/destination";
import {
getRclonePathAndFlags,
normalizeS3Path,
} from "@dokploy/server/utils/backups/utils";
import { describe, expect, test } from "vitest";
describe("normalizeS3Path", () => {
@ -59,3 +63,99 @@ describe("normalizeS3Path", () => {
expect(normalizeS3Path("instance-backups")).toBe("instance-backups/");
});
});
const destination = (overrides: Record<string, unknown> = {}) =>
({
destinationId: "destination-id",
name: "Test",
provider: "AWS",
accessKey: "access",
secretAccessKey: "secret",
bucket: "bucket",
region: "us-east-1",
endpoint: "https://s3.example.com",
additionalFlags: [],
organizationId: "organization-id",
createdAt: new Date(0),
...overrides,
}) as any;
describe("getRclonePathAndFlags", () => {
test("preserves the existing S3 destination behavior", async () => {
const result = await getRclonePathAndFlags(
destination(),
"service/prefix/backup.sql.gz",
);
expect(result.path).toBe(":s3:bucket/service/prefix/backup.sql.gz");
expect(result.flags).toContain("--s3-provider=AWS");
expect(result.flags).toContain("--s3-access-key-id=access");
expect(result.flags).toContain("--s3-secret-access-key=secret");
});
test.each([
RCLONE_DESTINATION_PROVIDERS.GOOGLE_DRIVE,
RCLONE_DESTINATION_PROVIDERS.ONEDRIVE,
RCLONE_DESTINATION_PROVIDERS.REMOTE,
])("builds a safe named rclone remote for %s", async (provider) => {
const result = await getRclonePathAndFlags(
destination({
provider,
endpoint: "team-drive",
bucket: "/dokploy/",
accessKey: "",
secretAccessKey: "",
region: "",
additionalFlags: ["--transfers=2"],
}),
"/service/backup.sql.gz",
);
expect(result.path).toBe("team-drive:dokploy/service/backup.sql.gz");
expect(result.flags).toEqual(["--transfers=2"]);
});
test("rejects unsafe named remote names", async () => {
await expect(
getRclonePathAndFlags(
destination({
provider: RCLONE_DESTINATION_PROVIDERS.GOOGLE_DRIVE,
endpoint: "drive;touch /tmp/pwned",
bucket: "",
}),
),
).rejects.toThrow("Invalid rclone remote name");
});
test.each([
[RCLONE_DESTINATION_PROVIDERS.FTP, "ftp", "21"],
[RCLONE_DESTINATION_PROVIDERS.SFTP, "sftp", "22"],
] as const)(
"builds stateless %s flags and destination without invoking password obscuring when password is empty",
async (provider, backend, defaultPort) => {
const result = await getRclonePathAndFlags(
destination({
provider,
endpoint: "storage.example.com",
accessKey: "backup-user",
secretAccessKey: "",
region: "",
bucket: "/backups/",
}),
"service/backup.tar",
);
expect(result.path).toBe(
`:${backend}:backups/service/backup.tar`,
);
expect(result.flags).toContain(
`--${backend}-host=storage.example.com`,
);
expect(result.flags).toContain(`--${backend}-user=backup-user`);
expect(result.flags).toContain(`--${backend}-port=${defaultPort}`);
expect(result.flags.some((flag) => flag.startsWith(`--${backend}-pass=`))).toBe(
false,
);
},
);
});