Skip to main content
Glama
query-builder.test.ts8.81 kB
/** * @fileoverview Tests for GraphQL Query Builder */ import { describe, it, expect } from 'vitest'; import { GraphQLQueryBuilder } from '../query-builder.js'; import { asProjectKey, asRunId } from '../../../types/branded.js'; describe('GraphQLQueryBuilder', () => { describe('Basic Query Building', () => { it('should build a simple query', () => { const builder = new GraphQLQueryBuilder(); const { query, variables } = builder.select('id').select('name').build(); expect(query).toBe('query {\n id\n name\n}'); expect(variables).toEqual({}); }); it('should build a named query', () => { const builder = new GraphQLQueryBuilder(); const { query } = builder.withName('GetUser').select('id').select('name').build(); expect(query).toBe('query GetUser {\n id\n name\n}'); }); it('should build a mutation', () => { const builder = new GraphQLQueryBuilder('mutation'); const { query } = builder.withName('UpdateUser').select('id').build(); expect(query).toBe('mutation UpdateUser {\n id\n}'); }); }); describe('Variables', () => { it('should handle variables', () => { const builder = new GraphQLQueryBuilder(); const { query, variables } = builder .withName('GetUser') .withVariable('id', 'ID!', '123') .selectNested('user', ['id', 'name'], { id: '$id' }) .build(); expect(query).toContain('query GetUser($id: ID!)'); expect(query).toContain('user(id: $id)'); expect(variables).toEqual({ id: '123' }); }); it('should handle multiple variables', () => { const builder = new GraphQLQueryBuilder(); const { query, variables } = builder .withVariable('first', 'Int', 10) .withVariable('after', 'String', 'cursor123') .selectNested('items', ['id'], { first: '$first', after: '$after' }) .build(); expect(query).toContain('$first: Int, $after: String'); expect(variables).toEqual({ first: 10, after: 'cursor123' }); }); }); describe('Nested Fields', () => { it('should handle nested field selections', () => { const builder = new GraphQLQueryBuilder(); const { query } = builder .selectNested('user', [ 'id', 'name', { name: 'profile', fields: [{ name: 'bio' }, { name: 'avatar' }], }, ]) .build(); expect(query).toContain('user {'); expect(query).toContain('id'); expect(query).toContain('name'); expect(query).toContain('profile {'); expect(query).toContain('bio'); expect(query).toContain('avatar'); }); it('should handle deeply nested fields', () => { const builder = new GraphQLQueryBuilder(); const { query } = builder .selectNested('repository', [ 'id', { name: 'issues', args: { first: 10 }, fields: [ { name: 'edges', fields: [ { name: 'node', fields: [{ name: 'id' }, { name: 'title' }], }, ], }, ], }, ]) .build(); expect(query).toContain('repository {'); expect(query).toContain('issues(first: 10) {'); expect(query).toContain('edges {'); expect(query).toContain('node {'); expect(query).toContain('title'); }); }); describe('Field Aliases', () => { it('should handle field aliases', () => { const builder = new GraphQLQueryBuilder(); const { query } = builder .select({ name: 'id', alias: 'userId' }) .select({ name: 'name', alias: 'userName' }) .build(); expect(query).toContain('userId: id'); expect(query).toContain('userName: name'); }); }); describe('Fragments', () => { it('should handle fragment definitions and usage', () => { const fragment = { name: 'UserFields', type: 'User', fields: [{ name: 'id' }, { name: 'name' }, { name: 'email' }], }; const builder = new GraphQLQueryBuilder(); const { query } = builder .withFragment(fragment) .selectNested('user', []) .useFragment('UserFields') .build(); expect(query).toContain('fragment UserFields on User {'); expect(query).toContain('...UserFields'); }); }); describe('selectMany', () => { it('should handle multiple selections at once', () => { const builder = new GraphQLQueryBuilder(); const { query } = builder .selectMany('id', 'name', 'email', { name: 'age', alias: 'userAge' }) .build(); expect(query).toContain('id'); expect(query).toContain('name'); expect(query).toContain('email'); expect(query).toContain('userAge: age'); }); }); describe('Static Factory Methods', () => { it('should create a projects query', () => { const { query } = GraphQLQueryBuilder.projects().build(); expect(query).toContain('query GetProjects'); expect(query).toContain('viewer {'); expect(query).toContain('accounts {'); expect(query).toContain('repositories {'); }); it('should create a run query', () => { const projectKey = asProjectKey('test-project'); const runId = asRunId('run-123'); const { query, variables } = GraphQLQueryBuilder.run(projectKey, runId).build(); expect(query).toContain('query GetRun($projectKey: String!, $runId: ID!)'); expect(query).toContain('run(projectKey: $projectKey, runUid: $runId)'); expect(variables).toEqual({ projectKey: 'test-project', runId: 'run-123', }); }); it('should create a quality metrics query', () => { const projectKey = asProjectKey('test-project'); const { query, variables } = GraphQLQueryBuilder.qualityMetrics(projectKey).build(); expect(query).toContain('query GetQualityMetrics($projectKey: String!)'); expect(query).toContain('repository(key: $projectKey)'); expect(query).toContain('metrics {'); expect(query).toContain('items {'); expect(variables).toEqual({ projectKey: 'test-project' }); }); }); describe('Fragments Factory Methods', () => { it('should create issue fields fragment', () => { const fragment = GraphQLQueryBuilder.issueFieldsFragment(); expect(fragment.name).toBe('IssueFields'); expect(fragment.type).toBe('Issue'); expect(fragment.fields).toContainEqual({ name: 'id' }); expect(fragment.fields).toContainEqual({ name: 'title' }); expect(fragment.fields).toContainEqual({ name: 'issueCode' }); }); it('should create run fields fragment', () => { const fragment = GraphQLQueryBuilder.runFieldsFragment(); expect(fragment.name).toBe('RunFields'); expect(fragment.type).toBe('Run'); expect(fragment.fields).toContainEqual({ name: 'runUid' }); expect(fragment.fields).toContainEqual({ name: 'commitOid' }); expect(fragment.fields).toContainEqual({ name: 'status' }); }); }); describe('Complex Query Example', () => { it('should build a complex query with all features', () => { const issueFragment = GraphQLQueryBuilder.issueFieldsFragment(); const builder = new GraphQLQueryBuilder(); const { query, variables } = builder .withName('GetRepositoryData') .withVariable('projectKey', 'String!', 'my-project') .withVariable('first', 'Int', 50) .withFragment(issueFragment) .selectNested( 'repository', [ 'id', 'name', { name: 'issues', args: { first: '$first' }, fields: [ { name: 'edges', fields: [ { name: 'node', fields: [{ name: '...IssueFields' }], }, ], }, { name: 'pageInfo', fields: [{ name: 'hasNextPage' }, { name: 'endCursor' }], }, ], }, ], { key: '$projectKey' } ) .build(); expect(query).toContain('query GetRepositoryData($projectKey: String!, $first: Int)'); expect(query).toContain('repository(key: $projectKey)'); expect(query).toContain('issues(first: $first)'); expect(query).toContain('...IssueFields'); expect(query).toContain('fragment IssueFields on Issue'); expect(variables).toEqual({ projectKey: 'my-project', first: 50, }); }); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sapientpants/deepsource-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server