Skip to content

Commit 99cced4

Browse files
committed
Add tests for resolvedRef usage in createSourceFromState
Add tests to verify that createSourceFromState correctly uses resolvedRef from state metadata when creating source instances: - Test that GitHub source receives resolvedRef as ref when present - Test that GitLab source receives resolvedRef as ref when present - Test that BitBucket source receives resolvedRef as ref when present - Test that original config.ref is used when resolvedRef is missing - Test that website sources work correctly without resolvedRef Uses vi.mock to mock the source constructors and verify they receive the correct ref parameter. Agent-Id: agent-cb10d5cd-ffb8-488e-81b3-914f1aeda05a
1 parent 14d54ee commit 99cced4

1 file changed

Lines changed: 223 additions & 0 deletions

File tree

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
/**
2+
* Tests for MultiIndexRunner
3+
*
4+
* These tests verify that createSourceFromState correctly uses resolvedRef
5+
* from state metadata when creating source instances.
6+
*/
7+
8+
import { describe, it, expect, vi, beforeEach } from "vitest";
9+
import type { IndexStateSearchOnly, SourceMetadata } from "../core/types.js";
10+
import type { IndexStoreReader } from "../stores/types.js";
11+
12+
// Mock the source modules
13+
vi.mock("../sources/github.js", () => ({
14+
GitHubSource: vi.fn().mockImplementation((config) => ({
15+
type: "github" as const,
16+
config,
17+
listFiles: vi.fn().mockResolvedValue([]),
18+
readFile: vi.fn().mockResolvedValue(""),
19+
fetchAll: vi.fn(),
20+
fetchChanges: vi.fn(),
21+
getMetadata: vi.fn().mockResolvedValue({
22+
type: "github",
23+
config,
24+
syncedAt: new Date().toISOString(),
25+
}),
26+
})),
27+
}));
28+
29+
vi.mock("../sources/gitlab.js", () => ({
30+
GitLabSource: vi.fn().mockImplementation((config) => ({
31+
type: "gitlab" as const,
32+
config,
33+
listFiles: vi.fn().mockResolvedValue([]),
34+
readFile: vi.fn().mockResolvedValue(""),
35+
fetchAll: vi.fn(),
36+
fetchChanges: vi.fn(),
37+
getMetadata: vi.fn().mockResolvedValue({
38+
type: "gitlab",
39+
config,
40+
syncedAt: new Date().toISOString(),
41+
}),
42+
})),
43+
}));
44+
45+
vi.mock("../sources/bitbucket.js", () => ({
46+
BitBucketSource: vi.fn().mockImplementation((config) => ({
47+
type: "bitbucket" as const,
48+
config,
49+
listFiles: vi.fn().mockResolvedValue([]),
50+
readFile: vi.fn().mockResolvedValue(""),
51+
fetchAll: vi.fn(),
52+
fetchChanges: vi.fn(),
53+
getMetadata: vi.fn().mockResolvedValue({
54+
type: "bitbucket",
55+
config,
56+
syncedAt: new Date().toISOString(),
57+
}),
58+
})),
59+
}));
60+
61+
vi.mock("../sources/website.js", () => ({
62+
WebsiteSource: vi.fn().mockImplementation((config) => ({
63+
type: "website" as const,
64+
config,
65+
listFiles: vi.fn().mockResolvedValue([]),
66+
readFile: vi.fn().mockResolvedValue(""),
67+
fetchAll: vi.fn(),
68+
fetchChanges: vi.fn(),
69+
getMetadata: vi.fn().mockResolvedValue({
70+
type: "website",
71+
config,
72+
syncedAt: new Date().toISOString(),
73+
}),
74+
})),
75+
}));
76+
77+
// Import after mocking
78+
import { MultiIndexRunner } from "./multi-index-runner.js";
79+
import { GitHubSource } from "../sources/github.js";
80+
import { GitLabSource } from "../sources/gitlab.js";
81+
import { BitBucketSource } from "../sources/bitbucket.js";
82+
import { WebsiteSource } from "../sources/website.js";
83+
84+
// Create mock state with specific source metadata
85+
const createMockState = (source: SourceMetadata): IndexStateSearchOnly => ({
86+
version: 1,
87+
contextState: {
88+
version: 1,
89+
} as any,
90+
source,
91+
});
92+
93+
// Create mock store
94+
const createMockStore = (stateMap: Map<string, IndexStateSearchOnly>): IndexStoreReader => ({
95+
loadState: vi.fn().mockImplementation(async (name: string) => stateMap.get(name) ?? null),
96+
loadSearch: vi.fn().mockImplementation(async (name: string) => stateMap.get(name) ?? null),
97+
list: vi.fn().mockResolvedValue(Array.from(stateMap.keys())),
98+
});
99+
100+
describe("MultiIndexRunner", () => {
101+
beforeEach(() => {
102+
vi.clearAllMocks();
103+
});
104+
105+
describe("createSourceFromState via getClient", () => {
106+
it("uses resolvedRef for GitHub source when present", async () => {
107+
const state = createMockState({
108+
type: "github",
109+
config: { owner: "test-owner", repo: "test-repo", ref: "main" },
110+
resolvedRef: "abc123sha",
111+
syncedAt: new Date().toISOString(),
112+
});
113+
const stateMap = new Map([["test-index", state]]);
114+
const store = createMockStore(stateMap);
115+
116+
const runner = await MultiIndexRunner.create({ store });
117+
await runner.getClient("test-index");
118+
119+
expect(GitHubSource).toHaveBeenCalledWith({
120+
owner: "test-owner",
121+
repo: "test-repo",
122+
ref: "abc123sha",
123+
});
124+
});
125+
126+
it("uses resolvedRef for GitLab source when present", async () => {
127+
const state = createMockState({
128+
type: "gitlab",
129+
config: { projectId: "group/project", ref: "main" },
130+
resolvedRef: "def456sha",
131+
syncedAt: new Date().toISOString(),
132+
});
133+
const stateMap = new Map([["test-index", state]]);
134+
const store = createMockStore(stateMap);
135+
136+
const runner = await MultiIndexRunner.create({ store });
137+
await runner.getClient("test-index");
138+
139+
expect(GitLabSource).toHaveBeenCalledWith({
140+
projectId: "group/project",
141+
ref: "def456sha",
142+
});
143+
});
144+
145+
it("uses resolvedRef for BitBucket source when present", async () => {
146+
const state = createMockState({
147+
type: "bitbucket",
148+
config: { workspace: "my-workspace", repo: "my-repo", ref: "develop" },
149+
resolvedRef: "ghi789sha",
150+
syncedAt: new Date().toISOString(),
151+
});
152+
const stateMap = new Map([["test-index", state]]);
153+
const store = createMockStore(stateMap);
154+
155+
const runner = await MultiIndexRunner.create({ store });
156+
await runner.getClient("test-index");
157+
158+
expect(BitBucketSource).toHaveBeenCalledWith({
159+
workspace: "my-workspace",
160+
repo: "my-repo",
161+
ref: "ghi789sha",
162+
});
163+
});
164+
165+
it("uses original config.ref when resolvedRef is missing for GitHub", async () => {
166+
const state = createMockState({
167+
type: "github",
168+
config: { owner: "test-owner", repo: "test-repo", ref: "main" },
169+
// No resolvedRef
170+
syncedAt: new Date().toISOString(),
171+
});
172+
const stateMap = new Map([["test-index", state]]);
173+
const store = createMockStore(stateMap);
174+
175+
const runner = await MultiIndexRunner.create({ store });
176+
await runner.getClient("test-index");
177+
178+
expect(GitHubSource).toHaveBeenCalledWith({
179+
owner: "test-owner",
180+
repo: "test-repo",
181+
ref: "main",
182+
});
183+
});
184+
185+
it("uses original config.ref when resolvedRef is undefined for GitLab", async () => {
186+
const state = createMockState({
187+
type: "gitlab",
188+
config: { projectId: "group/project", ref: "develop" },
189+
resolvedRef: undefined,
190+
syncedAt: new Date().toISOString(),
191+
});
192+
const stateMap = new Map([["test-index", state]]);
193+
const store = createMockStore(stateMap);
194+
195+
const runner = await MultiIndexRunner.create({ store });
196+
await runner.getClient("test-index");
197+
198+
expect(GitLabSource).toHaveBeenCalledWith({
199+
projectId: "group/project",
200+
ref: "develop",
201+
});
202+
});
203+
204+
it("website source works correctly without resolvedRef", async () => {
205+
const state = createMockState({
206+
type: "website",
207+
config: { url: "https://example.com", maxDepth: 2 },
208+
syncedAt: new Date().toISOString(),
209+
});
210+
const stateMap = new Map([["test-index", state]]);
211+
const store = createMockStore(stateMap);
212+
213+
const runner = await MultiIndexRunner.create({ store });
214+
await runner.getClient("test-index");
215+
216+
expect(WebsiteSource).toHaveBeenCalledWith({
217+
url: "https://example.com",
218+
maxDepth: 2,
219+
});
220+
});
221+
});
222+
});
223+

0 commit comments

Comments
 (0)