import { describe, it, expect } from 'vitest';
import {
formatPipelinesResponse,
formatJobsResponse,
formatEnvironmentsResponse,
formatBranchesResponse,
formatTagsResponse,
formatTreeResponse,
formatReleasesResponse,
formatLabelsResponse,
formatMilestonesResponse,
formatProtectedBranchesResponse,
formatUsersResponse,
formatGroupsResponse
} from './formatters.js';
describe('formatPipelinesResponse', () => {
it('formats pipelines with summary', () => {
const response = formatPipelinesResponse({
count: 2,
items: [
{
id: 1,
project_id: 1,
sha: 'abc123def456',
ref: 'main',
status: 'success',
source: 'push',
created_at: '2024-01-01T00:00:00Z',
updated_at: '2024-01-01T00:00:00Z',
web_url: 'https://gitlab.com/pipelines/1',
duration: 120
},
{
id: 2,
project_id: 1,
sha: 'def456abc123',
ref: 'develop',
status: 'failed',
source: 'web',
created_at: '2024-01-02T00:00:00Z',
updated_at: '2024-01-02T00:00:00Z',
web_url: 'https://gitlab.com/pipelines/2',
duration: 60
}
]
});
expect(response.content).toHaveLength(2);
expect(response.content[0].text).toBe('Found 2 pipelines');
const items = JSON.parse(response.content[1].text);
expect(items).toHaveLength(2);
expect(items[0].sha).toBe('abc123de'); // Truncated to 8 chars
expect(items[0].status).toBe('success');
});
});
describe('formatJobsResponse', () => {
it('formats jobs with summary', () => {
const response = formatJobsResponse({
count: 1,
items: [
{
id: 1,
status: 'success',
stage: 'build',
name: 'build-job',
ref: 'main',
tag: false,
created_at: '2024-01-01T00:00:00Z',
web_url: 'https://gitlab.com/jobs/1',
duration: 30
}
]
});
expect(response.content[0].text).toBe('Found 1 jobs');
const items = JSON.parse(response.content[1].text);
expect(items[0].name).toBe('build-job');
expect(items[0].stage).toBe('build');
});
});
describe('formatEnvironmentsResponse', () => {
it('formats environments with summary', () => {
const response = formatEnvironmentsResponse({
count: 2,
items: [
{
id: 1,
name: 'production',
slug: 'production',
state: 'available'
},
{
id: 2,
name: 'staging',
slug: 'staging',
state: 'stopped'
}
]
});
expect(response.content[0].text).toBe('Found 2 environments');
const items = JSON.parse(response.content[1].text);
expect(items[0].name).toBe('production');
expect(items[0].state).toBe('available');
});
});
describe('formatBranchesResponse', () => {
it('formats branches with summary', () => {
const response = formatBranchesResponse({
count: 1,
items: [
{
name: 'main',
protected: true,
commit: {
id: 'abc123',
short_id: 'abc123',
title: 'Initial commit',
created_at: '2024-01-01T00:00:00Z',
author_name: 'Test User'
}
}
]
});
expect(response.content[0].text).toBe('Found 1 branches');
const items = JSON.parse(response.content[1].text);
expect(items[0].name).toBe('main');
expect(items[0].protected).toBe(true);
});
});
describe('formatTagsResponse', () => {
it('formats tags with summary', () => {
const response = formatTagsResponse({
count: 1,
items: [
{
name: 'v1.0.0',
message: 'Release version 1.0.0',
protected: false,
commit: {
id: 'abc123',
short_id: 'abc123',
title: 'Release commit',
created_at: '2024-01-01T00:00:00Z'
}
}
]
});
expect(response.content[0].text).toBe('Found 1 tags');
const items = JSON.parse(response.content[1].text);
expect(items[0].name).toBe('v1.0.0');
expect(items[0].message).toBe('Release version 1.0.0');
});
});
describe('formatTreeResponse', () => {
it('formats tree items with summary', () => {
const response = formatTreeResponse({
count: 3,
items: [
{ id: '1', name: 'src', type: 'tree', path: 'src', mode: '040000' },
{ id: '2', name: 'README.md', type: 'blob', path: 'README.md', mode: '100644' },
{ id: '3', name: 'package.json', type: 'blob', path: 'package.json', mode: '100644' }
]
});
expect(response.content[0].text).toBe('Found 3 items');
const items = JSON.parse(response.content[1].text);
expect(items[0].type).toBe('tree');
expect(items[1].type).toBe('blob');
});
});
describe('formatReleasesResponse', () => {
it('formats releases with summary', () => {
const response = formatReleasesResponse({
count: 1,
items: [
{
tag_name: 'v1.0.0',
name: 'Version 1.0.0',
description: 'First release',
created_at: '2024-01-01T00:00:00Z'
}
]
});
expect(response.content[0].text).toBe('Found 1 releases');
const items = JSON.parse(response.content[1].text);
expect(items[0].tag_name).toBe('v1.0.0');
expect(items[0].name).toBe('Version 1.0.0');
});
it('truncates long descriptions', () => {
const longDescription = 'A'.repeat(200);
const response = formatReleasesResponse({
count: 1,
items: [
{
tag_name: 'v1.0.0',
name: null,
description: longDescription,
created_at: '2024-01-01T00:00:00Z'
}
]
});
const items = JSON.parse(response.content[1].text);
expect(items[0].description.length).toBeLessThan(longDescription.length);
expect(items[0].description.endsWith('...')).toBe(true);
});
});
describe('formatLabelsResponse', () => {
it('formats labels with summary', () => {
const response = formatLabelsResponse({
count: 2,
items: [
{
id: 1,
name: 'bug',
color: '#FF0000',
description: 'Bug reports'
},
{
id: 2,
name: 'feature',
color: '#00FF00',
description: 'Feature requests'
}
]
});
expect(response.content[0].text).toBe('Found 2 labels');
const items = JSON.parse(response.content[1].text);
expect(items[0].name).toBe('bug');
expect(items[0].color).toBe('#FF0000');
});
});
describe('formatMilestonesResponse', () => {
it('formats milestones with summary', () => {
const response = formatMilestonesResponse({
count: 1,
items: [
{
id: 1,
iid: 1,
title: 'v1.0',
description: 'First milestone',
state: 'active',
created_at: '2024-01-01T00:00:00Z',
updated_at: '2024-01-01T00:00:00Z',
due_date: '2024-06-01',
start_date: '2024-01-01',
web_url: 'https://gitlab.com/milestones/1'
}
]
});
expect(response.content[0].text).toBe('Found 1 milestones');
const items = JSON.parse(response.content[1].text);
expect(items[0].title).toBe('v1.0');
expect(items[0].state).toBe('active');
});
});
describe('formatProtectedBranchesResponse', () => {
it('formats protected branches with summary', () => {
const response = formatProtectedBranchesResponse({
count: 1,
items: [
{
id: 1,
name: 'main',
push_access_levels: [{ access_level: 40, access_level_description: 'Maintainers' }],
merge_access_levels: [{ access_level: 30, access_level_description: 'Developers + Maintainers' }],
allow_force_push: false
}
]
});
expect(response.content[0].text).toBe('Found 1 protected branches');
const items = JSON.parse(response.content[1].text);
expect(items[0].name).toBe('main');
expect(items[0].push_access_levels).toContain('Maintainers');
});
});
describe('formatUsersResponse', () => {
it('formats users with summary', () => {
const response = formatUsersResponse({
count: 1,
items: [
{
id: 1,
username: 'testuser',
name: 'Test User',
state: 'active',
avatar_url: 'https://gitlab.com/avatar.png',
web_url: 'https://gitlab.com/testuser'
}
]
});
expect(response.content[0].text).toBe('Found 1 users');
const items = JSON.parse(response.content[1].text);
expect(items[0].username).toBe('testuser');
expect(items[0].name).toBe('Test User');
});
});
describe('formatGroupsResponse', () => {
it('formats groups with summary', () => {
const response = formatGroupsResponse({
count: 2,
items: [
{
id: 1,
name: 'Group One',
path: 'group-one',
full_path: 'group-one',
description: 'First group',
visibility: 'private',
web_url: 'https://gitlab.com/group-one'
},
{
id: 2,
name: 'Subgroup',
path: 'subgroup',
full_path: 'group-one/subgroup',
description: 'A subgroup',
visibility: 'internal',
parent_id: 1,
web_url: 'https://gitlab.com/group-one/subgroup'
}
]
});
expect(response.content[0].text).toBe('Found 2 groups');
const items = JSON.parse(response.content[1].text);
expect(items[0].name).toBe('Group One');
expect(items[1].parent_id).toBe(1);
});
});