Skip to content
Merged
Show file tree
Hide file tree
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
107 changes: 107 additions & 0 deletions src/__tests__/boolean-string-transform.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/// <reference types="jest" />

/**
* @jest-environment node
*/

import { describe, it, expect } from '@jest/globals';
import { z } from 'zod';

describe('Boolean string transform', () => {
// Test the boolean transform that's used in the tool registrations
const booleanStringTransform = (val: string) => val === 'true';

// Create a schema that matches the one in index.ts
const booleanSchema = z
.union([z.boolean(), z.string().transform(booleanStringTransform)])
.nullable()
.optional();

describe('direct transform function', () => {
it('should transform "true" to true', () => {
expect(booleanStringTransform('true')).toBe(true);
});

it('should transform anything else to false', () => {
expect(booleanStringTransform('false')).toBe(false);
expect(booleanStringTransform('True')).toBe(false);
expect(booleanStringTransform('1')).toBe(false);
expect(booleanStringTransform('')).toBe(false);
});
});

describe('zod schema with boolean transform', () => {
it('should accept and pass through boolean values', () => {
expect(booleanSchema.parse(true)).toBe(true);
expect(booleanSchema.parse(false)).toBe(false);
});

it('should transform string "true" to boolean true', () => {
expect(booleanSchema.parse('true')).toBe(true);
});

it('should transform other string values to boolean false', () => {
expect(booleanSchema.parse('false')).toBe(false);
expect(booleanSchema.parse('1')).toBe(false);
expect(booleanSchema.parse('')).toBe(false);
});

it('should pass through null and undefined', () => {
expect(booleanSchema.parse(null)).toBeNull();
expect(booleanSchema.parse(undefined)).toBeUndefined();
});
});

// Test multiple boolean schema transformations in the same schema
describe('multiple boolean transforms in schema', () => {
// Create a schema with multiple boolean transforms
const complexSchema = z.object({
resolved: z
.union([z.boolean(), z.string().transform(booleanStringTransform)])
.nullable()
.optional(),
on_component_only: z
.union([z.boolean(), z.string().transform(booleanStringTransform)])
.nullable()
.optional(),
since_leak_period: z
.union([z.boolean(), z.string().transform(booleanStringTransform)])
.nullable()
.optional(),
in_new_code_period: z
.union([z.boolean(), z.string().transform(booleanStringTransform)])
.nullable()
.optional(),
});

it('should transform multiple boolean string values', () => {
const result = complexSchema.parse({
resolved: 'true',
on_component_only: 'false',
since_leak_period: true,
in_new_code_period: 'true',
});

expect(result).toEqual({
resolved: true,
on_component_only: false,
since_leak_period: true,
in_new_code_period: true,
});
});

it('should handle mix of boolean, string, null and undefined values', () => {
const result = complexSchema.parse({
resolved: true,
on_component_only: 'true',
since_leak_period: null,
});

expect(result).toEqual({
resolved: true,
on_component_only: true,
since_leak_period: null,
});
});
});
});
84 changes: 84 additions & 0 deletions src/__tests__/mocks/sonarqube-client.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {
MeasuresHistoryParams,
PaginationParams,
ProjectQualityGateParams,
ScmBlameParams,
SourceCodeParams,
SonarQubeComponentMeasuresResult,
SonarQubeComponentsMeasuresResult,
SonarQubeHealthStatus,
Expand All @@ -16,6 +18,8 @@ import {
SonarQubeQualityGate,
SonarQubeQualityGateStatus,
SonarQubeQualityGatesResult,
SonarQubeScmBlameResult,
SonarQubeSourceResult,
SonarQubeSystemStatus,
SonarQubeMeasuresHistoryResult,
} from '../../sonarqube.js';
Expand All @@ -37,6 +41,8 @@ export class MockSonarQubeClient implements ISonarQubeClient {
listQualityGatesMock: jest.Mock = jest.fn();
getQualityGateMock: jest.Mock = jest.fn();
getProjectQualityGateStatusMock: jest.Mock = jest.fn();
getSourceCodeMock: jest.Mock = jest.fn();
getScmBlameMock: jest.Mock = jest.fn();

constructor() {
this.setupDefaultMocks();
Expand Down Expand Up @@ -97,6 +103,14 @@ export class MockSonarQubeClient implements ISonarQubeClient {
return this.getProjectQualityGateStatusMock(params) as Promise<SonarQubeQualityGateStatus>;
}

async getSourceCode(params: SourceCodeParams): Promise<SonarQubeSourceResult> {
return this.getSourceCodeMock(params) as Promise<SonarQubeSourceResult>;
}

async getScmBlame(params: ScmBlameParams): Promise<SonarQubeScmBlameResult> {
return this.getScmBlameMock(params) as Promise<SonarQubeScmBlameResult>;
}

// Reset all mocks
reset() {
this.listProjectsMock.mockReset();
Expand All @@ -111,6 +125,8 @@ export class MockSonarQubeClient implements ISonarQubeClient {
this.listQualityGatesMock.mockReset();
this.getQualityGateMock.mockReset();
this.getProjectQualityGateStatusMock.mockReset();
this.getSourceCodeMock.mockReset();
this.getScmBlameMock.mockReset();

// Re-setup default mock implementations
this.setupDefaultMocks();
Expand Down Expand Up @@ -338,5 +354,73 @@ export class MockSonarQubeClient implements ISonarQubeClient {
},
} as SonarQubeQualityGateStatus)
);

// Get source code
this.getSourceCodeMock.mockImplementation(() =>
Promise.resolve({
component: {
key: 'test-component',
path: 'src/test.js',
qualifier: 'FIL',
name: 'test.js',
longName: 'src/test.js',
language: 'js',
},
sources: [
{
line: 1,
code: 'function test() {',
scmAuthor: 'developer',
scmDate: '2023-01-01',
scmRevision: 'abc123',
},
{
line: 2,
code: ' return "test";',
scmAuthor: 'developer',
scmDate: '2023-01-01',
scmRevision: 'abc123',
},
{
line: 3,
code: '}',
scmAuthor: 'developer',
scmDate: '2023-01-01',
scmRevision: 'abc123',
},
],
} as SonarQubeSourceResult)
);

// Get SCM blame
this.getScmBlameMock.mockImplementation(() =>
Promise.resolve({
component: {
key: 'test-component',
path: 'src/test.js',
qualifier: 'FIL',
name: 'test.js',
longName: 'src/test.js',
language: 'js',
},
sources: {
'1': {
author: 'developer',
date: '2023-01-01',
revision: 'abc123',
},
'2': {
author: 'developer',
date: '2023-01-01',
revision: 'abc123',
},
'3': {
author: 'developer',
date: '2023-01-01',
revision: 'abc123',
},
},
} as SonarQubeScmBlameResult)
);
}
}
Loading