mirror of
https://github.com/Dokploy/dokploy.git
synced 2026-09-14 11:06:15 +05:00
test: cover non-S3 rclone destination routing
This commit is contained in:
parent
d96e7f7c30
commit
a52768e8f0
@ -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,
|
||||
);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user