mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-01-30 06:12:03 +00:00
CRITICAL FIXES: - Fix dependency-resolver ES module failure by reverting to CommonJS - Removed "type": "module" from package.json - Changed tsconfig.json module from "ESNext" to "commonjs" - Added exports field for better module resolution - Package now works correctly at runtime - Fix Feature type incompatibility between server and UI - Added FeatureImagePath interface to @automaker/types - Made imagePaths property accept multiple formats - Added index signature for backward compatibility HIGH PRIORITY FIXES: - Remove duplicate model-resolver.ts from apps/server/src/lib/ - Update sdk-options.ts to import from @automaker/model-resolver - Use @automaker/types for CLAUDE_MODEL_MAP and DEFAULT_MODELS - Remove duplicate session types from apps/ui/src/types/ - Deleted identical session.ts file - Use @automaker/types for session type definitions - Update source file Feature imports - Fix create.ts and update.ts to import Feature from @automaker/types - Separate Feature type import from FeatureLoader class import MEDIUM PRIORITY FIXES: - Remove unused imports - Remove unused AbortError from agent-service.ts - Remove unused MessageSquare icon from kanban-card.tsx - Consolidate duplicate React imports in hotkey-button.tsx - Update test file imports to use @automaker/* packages - Update 12 test files to import from @automaker/utils - Update 2 test files to import from @automaker/platform - Update 1 test file to import from @automaker/model-resolver - Update dependency-resolver.test.ts imports - Update providers/types imports to @automaker/types VERIFICATION: - Server builds successfully ✓ - All 6 shared packages build correctly ✓ - Test imports updated and verified ✓ 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
243 lines
7.1 KiB
TypeScript
243 lines
7.1 KiB
TypeScript
import { describe, it, expect } from "vitest";
|
|
import { BaseProvider } from "@/providers/base-provider.js";
|
|
import type {
|
|
ProviderConfig,
|
|
ExecuteOptions,
|
|
ProviderMessage,
|
|
InstallationStatus,
|
|
ModelDefinition,
|
|
} from "@automaker/types";
|
|
|
|
// Concrete implementation for testing the abstract class
|
|
class TestProvider extends BaseProvider {
|
|
getName(): string {
|
|
return "test-provider";
|
|
}
|
|
|
|
async *executeQuery(
|
|
_options: ExecuteOptions
|
|
): AsyncGenerator<ProviderMessage> {
|
|
yield { type: "text", text: "test response" };
|
|
}
|
|
|
|
async detectInstallation(): Promise<InstallationStatus> {
|
|
return { installed: true };
|
|
}
|
|
|
|
getAvailableModels(): ModelDefinition[] {
|
|
return [
|
|
{ id: "test-model-1", name: "Test Model 1", description: "A test model" },
|
|
];
|
|
}
|
|
}
|
|
|
|
describe("base-provider.ts", () => {
|
|
describe("constructor", () => {
|
|
it("should initialize with empty config when none provided", () => {
|
|
const provider = new TestProvider();
|
|
expect(provider.getConfig()).toEqual({});
|
|
});
|
|
|
|
it("should initialize with provided config", () => {
|
|
const config: ProviderConfig = {
|
|
apiKey: "test-key",
|
|
baseUrl: "https://test.com",
|
|
};
|
|
const provider = new TestProvider(config);
|
|
expect(provider.getConfig()).toEqual(config);
|
|
});
|
|
|
|
it("should call getName() during initialization", () => {
|
|
const provider = new TestProvider();
|
|
expect(provider.getName()).toBe("test-provider");
|
|
});
|
|
});
|
|
|
|
describe("validateConfig", () => {
|
|
it("should return valid when config exists", () => {
|
|
const provider = new TestProvider({ apiKey: "test" });
|
|
const result = provider.validateConfig();
|
|
|
|
expect(result.valid).toBe(true);
|
|
expect(result.errors).toHaveLength(0);
|
|
expect(result.warnings).toHaveLength(0);
|
|
});
|
|
|
|
it("should return invalid when config is undefined", () => {
|
|
// Create provider without config
|
|
const provider = new TestProvider();
|
|
// Manually set config to undefined to test edge case
|
|
(provider as any).config = undefined;
|
|
|
|
const result = provider.validateConfig();
|
|
|
|
expect(result.valid).toBe(false);
|
|
expect(result.errors).toContain("Provider config is missing");
|
|
});
|
|
|
|
it("should return valid for empty config object", () => {
|
|
const provider = new TestProvider({});
|
|
const result = provider.validateConfig();
|
|
|
|
expect(result.valid).toBe(true);
|
|
expect(result.errors).toHaveLength(0);
|
|
});
|
|
|
|
it("should include warnings array in result", () => {
|
|
const provider = new TestProvider();
|
|
const result = provider.validateConfig();
|
|
|
|
expect(result).toHaveProperty("warnings");
|
|
expect(Array.isArray(result.warnings)).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe("supportsFeature", () => {
|
|
it("should support 'tools' feature", () => {
|
|
const provider = new TestProvider();
|
|
expect(provider.supportsFeature("tools")).toBe(true);
|
|
});
|
|
|
|
it("should support 'text' feature", () => {
|
|
const provider = new TestProvider();
|
|
expect(provider.supportsFeature("text")).toBe(true);
|
|
});
|
|
|
|
it("should not support unknown features", () => {
|
|
const provider = new TestProvider();
|
|
expect(provider.supportsFeature("vision")).toBe(false);
|
|
expect(provider.supportsFeature("mcp")).toBe(false);
|
|
expect(provider.supportsFeature("unknown")).toBe(false);
|
|
});
|
|
|
|
it("should be case-sensitive", () => {
|
|
const provider = new TestProvider();
|
|
expect(provider.supportsFeature("TOOLS")).toBe(false);
|
|
expect(provider.supportsFeature("Text")).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe("getConfig", () => {
|
|
it("should return current config", () => {
|
|
const config: ProviderConfig = {
|
|
apiKey: "test-key",
|
|
model: "test-model",
|
|
};
|
|
const provider = new TestProvider(config);
|
|
|
|
expect(provider.getConfig()).toEqual(config);
|
|
});
|
|
|
|
it("should return same reference", () => {
|
|
const config: ProviderConfig = { apiKey: "test" };
|
|
const provider = new TestProvider(config);
|
|
|
|
const retrieved1 = provider.getConfig();
|
|
const retrieved2 = provider.getConfig();
|
|
|
|
expect(retrieved1).toBe(retrieved2);
|
|
});
|
|
});
|
|
|
|
describe("setConfig", () => {
|
|
it("should merge partial config with existing config", () => {
|
|
const provider = new TestProvider({ apiKey: "original-key" });
|
|
|
|
provider.setConfig({ model: "new-model" });
|
|
|
|
expect(provider.getConfig()).toEqual({
|
|
apiKey: "original-key",
|
|
model: "new-model",
|
|
});
|
|
});
|
|
|
|
it("should override existing fields", () => {
|
|
const provider = new TestProvider({ apiKey: "old-key", model: "old-model" });
|
|
|
|
provider.setConfig({ apiKey: "new-key" });
|
|
|
|
expect(provider.getConfig()).toEqual({
|
|
apiKey: "new-key",
|
|
model: "old-model",
|
|
});
|
|
});
|
|
|
|
it("should accept empty object", () => {
|
|
const provider = new TestProvider({ apiKey: "test" });
|
|
const originalConfig = provider.getConfig();
|
|
|
|
provider.setConfig({});
|
|
|
|
expect(provider.getConfig()).toEqual(originalConfig);
|
|
});
|
|
|
|
it("should handle multiple updates", () => {
|
|
const provider = new TestProvider();
|
|
|
|
provider.setConfig({ apiKey: "key1" });
|
|
provider.setConfig({ model: "model1" });
|
|
provider.setConfig({ baseUrl: "https://test.com" });
|
|
|
|
expect(provider.getConfig()).toEqual({
|
|
apiKey: "key1",
|
|
model: "model1",
|
|
baseUrl: "https://test.com",
|
|
});
|
|
});
|
|
|
|
it("should preserve other fields when updating one field", () => {
|
|
const provider = new TestProvider({
|
|
apiKey: "key",
|
|
model: "model",
|
|
baseUrl: "https://test.com",
|
|
});
|
|
|
|
provider.setConfig({ model: "new-model" });
|
|
|
|
expect(provider.getConfig()).toEqual({
|
|
apiKey: "key",
|
|
model: "new-model",
|
|
baseUrl: "https://test.com",
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("abstract methods", () => {
|
|
it("should require getName implementation", () => {
|
|
const provider = new TestProvider();
|
|
expect(typeof provider.getName).toBe("function");
|
|
expect(provider.getName()).toBe("test-provider");
|
|
});
|
|
|
|
it("should require executeQuery implementation", async () => {
|
|
const provider = new TestProvider();
|
|
expect(typeof provider.executeQuery).toBe("function");
|
|
|
|
const generator = provider.executeQuery({
|
|
prompt: "test",
|
|
projectDirectory: "/test",
|
|
});
|
|
const result = await generator.next();
|
|
|
|
expect(result.value).toEqual({ type: "text", text: "test response" });
|
|
});
|
|
|
|
it("should require detectInstallation implementation", async () => {
|
|
const provider = new TestProvider();
|
|
expect(typeof provider.detectInstallation).toBe("function");
|
|
|
|
const status = await provider.detectInstallation();
|
|
expect(status).toHaveProperty("installed");
|
|
});
|
|
|
|
it("should require getAvailableModels implementation", () => {
|
|
const provider = new TestProvider();
|
|
expect(typeof provider.getAvailableModels).toBe("function");
|
|
|
|
const models = provider.getAvailableModels();
|
|
expect(Array.isArray(models)).toBe(true);
|
|
expect(models.length).toBeGreaterThan(0);
|
|
});
|
|
});
|
|
});
|