cli / mcp for bitbucket
1import type { Result } from '@bitbucket-tool/core';
2import { afterEach, describe, expect, it, vi } from 'vitest';
3import {
4 errorResponse,
5 jsonResponse,
6 resolveWorkspace,
7 resultToResponse,
8 textResponse,
9} from '../tools/helpers';
10
11describe('resolveWorkspace', () => {
12 afterEach(() => {
13 vi.unstubAllEnvs();
14 });
15
16 it('returns workspace when provided directly', () => {
17 expect(resolveWorkspace('my-ws')).toBe('my-ws');
18 });
19
20 it('falls back to BITBUCKET_WORKSPACE env var when empty string', () => {
21 vi.stubEnv('BITBUCKET_WORKSPACE', 'env-ws');
22 expect(resolveWorkspace('')).toBe('env-ws');
23 });
24
25 it('prefers direct value over env var', () => {
26 vi.stubEnv('BITBUCKET_WORKSPACE', 'env-ws');
27 expect(resolveWorkspace('direct-ws')).toBe('direct-ws');
28 });
29
30 it('throws when neither provided nor env var set', () => {
31 vi.stubEnv('BITBUCKET_WORKSPACE', '');
32 expect(() => resolveWorkspace('')).toThrow('workspace is required');
33 });
34
35 it('throws when workspace is empty and env var is undefined', () => {
36 delete process.env.BITBUCKET_WORKSPACE;
37 expect(() => resolveWorkspace('')).toThrow('workspace is required');
38 });
39});
40
41describe('jsonResponse', () => {
42 it('wraps data as JSON text content', () => {
43 const result = jsonResponse({ id: 1, name: 'test' });
44
45 expect(result).toEqual({
46 content: [{ type: 'text', text: JSON.stringify({ id: 1, name: 'test' }, null, 2) }],
47 });
48 });
49
50 it('does not set isError', () => {
51 expect(jsonResponse({})).not.toHaveProperty('isError');
52 });
53});
54
55describe('textResponse', () => {
56 it('wraps string as text content', () => {
57 const result = textResponse('hello world');
58
59 expect(result).toEqual({
60 content: [{ type: 'text', text: 'hello world' }],
61 });
62 });
63
64 it('does not set isError', () => {
65 expect(textResponse('x')).not.toHaveProperty('isError');
66 });
67});
68
69describe('errorResponse', () => {
70 it('wraps message as text content with isError', () => {
71 const result = errorResponse('something broke');
72
73 expect(result).toEqual({
74 content: [{ type: 'text', text: 'something broke' }],
75 isError: true,
76 });
77 });
78});
79
80describe('resultToResponse', () => {
81 it('converts ok Result to JSON response', () => {
82 const result: Result<{ id: number }> = { ok: true, data: { id: 42 } };
83 const response = resultToResponse(result);
84
85 expect(response).toEqual({
86 content: [{ type: 'text', text: JSON.stringify({ id: 42 }, null, 2) }],
87 });
88 });
89
90 it('converts ok Result with custom formatter to text response', () => {
91 const result: Result<string> = { ok: true, data: 'raw diff output' };
92 const response = resultToResponse(result, (d) => d);
93
94 expect(response).toEqual({
95 content: [{ type: 'text', text: 'raw diff output' }],
96 });
97 });
98
99 it('converts error Result to error response with status', () => {
100 const result: Result<never> = {
101 ok: false,
102 error: { status: 404, message: 'Not found' },
103 };
104 const response = resultToResponse(result);
105
106 expect(response).toEqual({
107 content: [{ type: 'text', text: 'Not found (404)' }],
108 isError: true,
109 });
110 });
111});