import type Docker from "dockerode";
import { describe, expect, it, vi } from "vitest";
import type { HostConfig } from "../../../types.js";
import {
DefaultDockerClientFactory,
type IDockerClientFactory,
isSocketPath,
} from "./client-factory.js";
describe("isSocketPath", () => {
it("should return true for standard Docker socket path", (): void => {
expect(isSocketPath("/var/run/docker.sock")).toBe(true);
});
it("should return true for paths containing /docker", (): void => {
expect(isSocketPath("/some/docker/path")).toBe(true);
});
it("should return true for paths containing /run/", (): void => {
expect(isSocketPath("/run/user/1000/docker.sock")).toBe(true);
});
it("should return true for paths ending in .sock", (): void => {
expect(isSocketPath("/custom/path/my.sock")).toBe(true);
});
it("should return false for non-socket paths", (): void => {
expect(isSocketPath("localhost")).toBe(false);
expect(isSocketPath("192.168.1.100")).toBe(false);
expect(isSocketPath("http://example.com")).toBe(false);
});
it("should return false for paths not starting with /", (): void => {
expect(isSocketPath("docker.sock")).toBe(false);
expect(isSocketPath("run/docker.sock")).toBe(false);
});
});
describe("DefaultDockerClientFactory", () => {
it("should create client with Unix socket path from dockerSocketPath", async (): Promise<void> => {
const factory = new DefaultDockerClientFactory();
const config: HostConfig = {
name: "test",
host: "localhost",
dockerSocketPath: "/var/run/docker.sock",
};
const client = await factory.createClient(config);
expect(client).toBeDefined();
// Verify it's a Docker client (has expected methods)
expect(typeof client.listContainers).toBe("function");
});
it("should create client with Unix socket path from host field", async (): Promise<void> => {
const factory = new DefaultDockerClientFactory();
const config: HostConfig = {
name: "test",
host: "/var/run/docker.sock",
};
const client = await factory.createClient(config);
expect(client).toBeDefined();
expect(typeof client.listContainers).toBe("function");
});
it("should create SSH client when protocol is ssh", async (): Promise<void> => {
const factory = new DefaultDockerClientFactory();
const config: HostConfig = {
name: "test",
host: "remote.example.com",
protocol: "ssh",
username: "testuser",
sshKeyPath: "/home/user/.ssh/id_rsa",
};
const client = await factory.createClient(config);
expect(client).toBeDefined();
expect(typeof client.listContainers).toBe("function");
});
it("should create HTTP client for standard host without protocol", async (): Promise<void> => {
const factory = new DefaultDockerClientFactory();
const config: HostConfig = {
name: "test",
host: "192.168.1.100",
port: 2375,
};
const client = await factory.createClient(config);
expect(client).toBeDefined();
expect(typeof client.listContainers).toBe("function");
});
it("should create HTTPS client when protocol is https", async (): Promise<void> => {
const factory = new DefaultDockerClientFactory();
const config: HostConfig = {
name: "test",
host: "secure.example.com",
protocol: "https",
port: 2376,
};
const client = await factory.createClient(config);
expect(client).toBeDefined();
expect(typeof client.listContainers).toBe("function");
});
it("should prefer dockerSocketPath over host field", async (): Promise<void> => {
const factory = new DefaultDockerClientFactory();
const config: HostConfig = {
name: "test",
host: "remote.example.com",
dockerSocketPath: "/custom/docker.sock",
};
const client = await factory.createClient(config);
expect(client).toBeDefined();
expect(typeof client.listContainers).toBe("function");
});
});
describe("IDockerClientFactory interface", () => {
it("should allow custom factory implementation", async (): Promise<void> => {
class MockDockerClientFactory implements IDockerClientFactory {
async createClient(_config: HostConfig): Promise<Docker> {
// Return a mock Docker client
return {
listContainers: vi.fn(),
getContainer: vi.fn(),
listImages: vi.fn(),
} as unknown as Docker;
}
}
const factory = new MockDockerClientFactory();
const config: HostConfig = {
name: "test",
host: "localhost",
};
const client = await factory.createClient(config);
expect(client).toBeDefined();
expect(typeof client.listContainers).toBe("function");
});
});