wgc
Version:
The official CLI tool to manage the GraphQL Federation Platform Cosmo
193 lines • 7.18 kB
JavaScript
import { Command } from 'commander';
import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest';
import { createClient, createRouterTransport } from '@connectrpc/connect';
import { EnumStatusCode } from '@wundergraph/cosmo-connect/dist/common/common_pb';
import { PlatformService, } from '@wundergraph/cosmo-connect/dist/platform/v1/platform_pb';
import ListClientsCommand from '../src/commands/clients/commands/list.js';
function createMockTransport(response, onGetClients) {
return createRouterTransport(({ service }) => {
service(PlatformService, {
getClients: (req) => {
onGetClients === null || onGetClients === void 0 ? void 0 : onGetClients(req);
return response;
},
});
});
}
async function runList(response, args = [], onGetClients) {
const client = {
platform: createClient(PlatformService, createMockTransport(response, onGetClients)),
};
const program = new Command();
program.exitOverride();
program.addCommand(ListClientsCommand({ client }));
await program.parseAsync(['list', 'mygraph', ...args], { from: 'user' });
}
function getJsonOutput(logSpy) {
const call = logSpy.mock.calls.find(([arg]) => {
try {
JSON.parse(String(arg));
return true;
}
catch {
return false;
}
});
if (!call) {
throw new Error('No JSON output found in console.log calls');
}
return JSON.parse(String(call[0]));
}
describe('stdout', () => {
let logSpy;
let stderrSpy;
let exitSpy;
beforeEach(() => {
logSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
stderrSpy = vi.spyOn(process.stderr, 'write').mockImplementation(() => true);
exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {
throw new Error('process.exit');
});
});
afterEach(() => {
process.exitCode = undefined;
});
test('prints clients table', async () => {
await runList({
response: { code: EnumStatusCode.OK },
clients: [
{
id: 'client-id',
name: 'web',
createdAt: '2026-04-23T10:00:00.000Z',
lastUpdatedAt: '2026-04-24T10:00:00.000Z',
createdBy: 'a@b.com',
lastUpdatedBy: 'c@d.com',
persistedOperationsCount: 2,
hasTraffic: true,
},
],
});
expect(logSpy).toHaveBeenCalledTimes(1);
expect(String(logSpy.mock.calls[0][0])).toContain('NAME');
expect(String(logSpy.mock.calls[0][0])).toContain('OPERATION_COUNT');
expect(String(logSpy.mock.calls[0][0])).toContain('HAS_TRAFFIC');
expect(String(logSpy.mock.calls[0][0])).toContain('CREATED_AT');
expect(String(logSpy.mock.calls[0][0])).toContain('LAST_PUSH');
expect(String(logSpy.mock.calls[0][0])).toContain('web');
expect(String(logSpy.mock.calls[0][0])).toContain('2');
expect(String(logSpy.mock.calls[0][0])).toContain('✔');
expect(String(logSpy.mock.calls[0][0])).toContain('2026-04-23T10:00:00.000Z');
expect(String(logSpy.mock.calls[0][0])).toContain('2026-04-24T10:00:00.000Z');
expect(String(logSpy.mock.calls[0][0])).not.toContain('client-id');
});
test('uses default namespace when not provided', async () => {
let requestNamespace = '';
await runList({
response: { code: EnumStatusCode.OK },
clients: [],
}, [], (req) => {
requestNamespace = req.namespace;
});
expect(requestNamespace).toBe('default');
});
test('requests traffic data', async () => {
let includeTraffic = false;
await runList({
response: { code: EnumStatusCode.OK },
clients: [],
}, [], (req) => {
includeTraffic = req.includeTraffic;
});
expect(includeTraffic).toBe(true);
});
test('prints empty message', async () => {
await runList({
response: { code: EnumStatusCode.OK },
clients: [],
});
expect(logSpy).toHaveBeenCalledWith('No clients found');
});
test('fails on rpc error', async () => {
await expect(runList({
response: { code: EnumStatusCode.ERR, details: 'boom' },
clients: [],
})).rejects.toThrow();
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining('boom'));
expect(stderrSpy).toHaveBeenCalled();
expect(exitSpy).toHaveBeenCalled();
});
});
describe('json output', () => {
let logSpy;
let stderrSpy;
let exitSpy;
beforeEach(() => {
logSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
stderrSpy = vi.spyOn(process.stderr, 'write').mockImplementation(() => true);
exitSpy = vi.spyOn(process, 'exit').mockImplementation(() => {
throw new Error('process.exit');
});
});
afterEach(() => {
process.exitCode = undefined;
});
test('prints clients as raw json', async () => {
await runList({
response: { code: EnumStatusCode.OK },
clients: [
{
id: 'client-id',
name: 'web',
createdAt: '2026-04-23T10:00:00.000Z',
lastUpdatedAt: '',
createdBy: 'a@b.com',
lastUpdatedBy: '',
persistedOperationsCount: 3,
hasTraffic: false,
},
],
}, ['--json']);
expect(getJsonOutput(logSpy)).toEqual({
status: 'success',
clients: [
{
id: 'client-id',
name: 'web',
createdAt: '2026-04-23T10:00:00.000Z',
lastUpdatedAt: '',
createdBy: 'a@b.com',
lastUpdatedBy: '',
persistedOperationsCount: 3,
hasTraffic: false,
},
],
});
});
test('prints empty clients json when no clients found', async () => {
await runList({
response: { code: EnumStatusCode.OK },
clients: [],
}, ['--json']);
expect(getJsonOutput(logSpy)).toEqual({
status: 'success',
clients: [],
});
});
test('prints error json on rpc error', async () => {
await runList({
response: { code: EnumStatusCode.ERR, details: 'boom' },
clients: [],
}, ['--json']);
expect(getJsonOutput(logSpy)).toEqual({
status: 'error',
code: EnumStatusCode.ERR,
message: 'Could not fetch clients.',
details: 'boom',
});
expect(process.exitCode).toBe(1);
expect(stderrSpy).not.toHaveBeenCalled();
expect(exitSpy).not.toHaveBeenCalled();
});
});
//# sourceMappingURL=clients-list.test.js.map