Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions dev/test/cli/cli_create_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,16 @@ describe('createAgent', () => {

beforeEach(() => {
vi.clearAllMocks();
// createAgent() reads these before shelling out to gcloud, so a
// developer's exported values would shadow the execSync mock below.
vi.stubEnv('GOOGLE_CLOUD_PROJECT', undefined);
vi.stubEnv('GOOGLE_CLOUD_LOCATION', undefined);
(isCancel as unknown as Mock).mockReturnValue(false);
(listFiles as Mock).mockResolvedValue(['file1', 'file2']);
});

afterEach(() => {
vi.unstubAllEnvs();
vi.restoreAllMocks();
});

Expand Down Expand Up @@ -222,6 +227,64 @@ describe('createAgent', () => {
);
});

it('should prefer ambient Google Cloud env vars over gcloud config', async () => {
vi.stubEnv('GOOGLE_CLOUD_PROJECT', 'env-project');
vi.stubEnv('GOOGLE_CLOUD_LOCATION', 'env-region');

(select as Mock).mockResolvedValueOnce('gemini-2.5-flash');
(select as Mock).mockResolvedValueOnce('ts');
(select as Mock).mockResolvedValueOnce('vertex'); // Backend

(execSync as Mock).mockReturnValue('gcloud-project\n');

(text as Mock).mockResolvedValueOnce('env-project');
(text as Mock).mockResolvedValueOnce('env-region');

await createAgent(getFreshOptions());

expect(execSync).not.toHaveBeenCalled();
expect(text).toHaveBeenCalledWith(
expect.objectContaining({
message: 'Enter the Google Cloud Project ID',
initialValue: 'env-project',
}),
);
expect(text).toHaveBeenCalledWith(
expect.objectContaining({
message: 'Enter the Google Cloud Region',
initialValue: 'env-region',
}),
);
});

it('should seed empty defaults when the gcloud lookup fails', async () => {
(select as Mock).mockResolvedValueOnce('gemini-2.5-flash');
(select as Mock).mockResolvedValueOnce('ts');
(select as Mock).mockResolvedValueOnce('vertex'); // Backend

(execSync as Mock).mockImplementation(() => {
throw new Error('gcloud: command not found');
});

(text as Mock).mockResolvedValueOnce('manual-project');
(text as Mock).mockResolvedValueOnce('manual-region');

await createAgent(getFreshOptions());

expect(text).toHaveBeenCalledWith(
expect.objectContaining({
message: 'Enter the Google Cloud Project ID',
initialValue: '',
}),
);
expect(text).toHaveBeenCalledWith(
expect.objectContaining({
message: 'Enter the Google Cloud Region',
initialValue: '',
}),
);
});

it('should exit without writing files if project prompt is cancelled', async () => {
// Mirror clack's contract: only the raw cancel symbol counts as a cancel.
(isCancel as unknown as Mock).mockImplementation(
Expand Down
Loading