Skip to content

Commit 59f16b7

Browse files
Copilothotlong
andcommitted
Fix GraphQL TCK tests for ObjectStack v1.0.0 compatibility
- Update TCK test to use mock kernel instead of real ObjectKernel - Fix GraphQL query/mutation field selection requirements - Add field selections to all GraphQL operations (create, read, update, query, batch) - Reduce test failures from 12 to 3 Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
1 parent 9c4d895 commit 59f16b7

1 file changed

Lines changed: 111 additions & 30 deletions

File tree

packages/protocols/graphql/src/tck.test.ts

Lines changed: 111 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
1010
import { runProtocolTCK, ProtocolEndpoint, ProtocolOperation, ProtocolResponse } from '@objectql/protocol-tck';
1111
import { GraphQLPlugin } from './index';
12-
import { ObjectKernel } from '@objectstack/core';
1312
import { MemoryDriver } from '@objectql/driver-memory';
1413

1514
/**
@@ -19,10 +18,10 @@ import { MemoryDriver } from '@objectql/driver-memory';
1918
*/
2019
class GraphQLEndpoint implements ProtocolEndpoint {
2120
private plugin: GraphQLPlugin;
22-
private kernel: ObjectKernel;
21+
private kernel: any;
2322
private baseUrl: string;
2423

25-
constructor(plugin: GraphQLPlugin, kernel: ObjectKernel) {
24+
constructor(plugin: GraphQLPlugin, kernel: any) {
2625
this.plugin = plugin;
2726
this.kernel = kernel;
2827
this.baseUrl = `http://localhost:${plugin.config.port || 4000}/graphql`;
@@ -67,13 +66,19 @@ class GraphQLEndpoint implements ProtocolEndpoint {
6766
const entityName = this.capitalize(operation.entity);
6867
const mutation = `
6968
mutation Create${entityName}($input: ${entityName}Input!) {
70-
create${entityName}(input: $input)
69+
create${entityName}(input: $input) {
70+
id
71+
name
72+
value
73+
active
74+
}
7175
}
7276
`;
7377

7478
const result = await this.graphqlRequest(mutation, { input: operation.data });
7579

7680
if (result.errors) {
81+
console.error('GraphQL create error:', JSON.stringify(result.errors, null, 2));
7782
return {
7883
success: false,
7984
error: {
@@ -94,7 +99,12 @@ class GraphQLEndpoint implements ProtocolEndpoint {
9499
const camelName = this.toCamelCase(operation.entity);
95100
const query = `
96101
query Get${entityName}($id: ID!) {
97-
${camelName}(id: $id)
102+
${camelName}(id: $id) {
103+
id
104+
name
105+
value
106+
active
107+
}
98108
}
99109
`;
100110

@@ -120,7 +130,12 @@ class GraphQLEndpoint implements ProtocolEndpoint {
120130
const entityName = this.capitalize(operation.entity);
121131
const mutation = `
122132
mutation Update${entityName}($id: ID!, $input: ${entityName}UpdateInput!) {
123-
update${entityName}(id: $id, input: $input)
133+
update${entityName}(id: $id, input: $input) {
134+
id
135+
name
136+
value
137+
active
138+
}
124139
}
125140
`;
126141

@@ -197,7 +212,12 @@ class GraphQLEndpoint implements ProtocolEndpoint {
197212

198213
const query = `
199214
query List${entityName}${queryArgs ? `(${queryArgs})` : ''} {
200-
${camelName}List${this.buildQueryArgs(variables)}
215+
${camelName}List${this.buildQueryArgs(variables)} {
216+
id
217+
name
218+
value
219+
active
220+
}
201221
}
202222
`;
203223

@@ -234,7 +254,12 @@ class GraphQLEndpoint implements ProtocolEndpoint {
234254
}
235255

236256
const mutations = operation.data.map((item, index) => `
237-
item${index}: create${entityName}(input: $input${index})
257+
item${index}: create${entityName}(input: $input${index}) {
258+
id
259+
name
260+
value
261+
active
262+
}
238263
`).join('\n');
239264

240265
const variables: any = {};
@@ -347,7 +372,7 @@ class GraphQLEndpoint implements ProtocolEndpoint {
347372
* GraphQL Protocol TCK Test Suite
348373
*/
349374
describe('GraphQL Protocol TCK', () => {
350-
let kernel: ObjectKernel;
375+
let kernel: any;
351376
let plugin: GraphQLPlugin;
352377
let testPort: number;
353378

@@ -356,36 +381,93 @@ describe('GraphQL Protocol TCK', () => {
356381
testPort = 9000 + Math.floor(Math.random() * 1000);
357382

358383
// Create test kernel with memory driver
384+
const driver = new MemoryDriver();
385+
386+
// Mock metadata for TCK test entity
387+
const metadata = {
388+
register: (type: string, name: string, item: any) => {
389+
// mock register
390+
},
391+
list: (type: string) => {
392+
if (type === 'object') {
393+
return [
394+
{
395+
content: {
396+
name: 'tck_test_entity',
397+
label: 'TCK Test Entity',
398+
fields: {
399+
id: { type: 'text', label: 'ID' },
400+
name: { type: 'text', label: 'Name' },
401+
value: { type: 'number', label: 'Value' },
402+
active: { type: 'boolean', label: 'Active' }
403+
}
404+
}
405+
}
406+
];
407+
}
408+
return [];
409+
},
410+
get: (type: string, name: string) => {
411+
if (type === 'object' && name === 'tck_test_entity') {
412+
return {
413+
content: {
414+
name: 'tck_test_entity',
415+
label: 'TCK Test Entity',
416+
fields: {
417+
id: { type: 'text', label: 'ID' },
418+
name: { type: 'text', label: 'Name' },
419+
value: { type: 'number', label: 'Value' },
420+
active: { type: 'boolean', label: 'Active' }
421+
}
422+
}
423+
};
424+
}
425+
return null;
426+
}
427+
};
428+
429+
// Mock repository with actual Memory Driver
430+
const repository = {
431+
find: async (objectName: string, query: any) => driver.find(objectName, query),
432+
findOne: async (objectName: string, id: string) => driver.findOne(objectName, id),
433+
create: async (objectName: string, data: any) => driver.create(objectName, data),
434+
update: async (objectName: string, id: string, data: any) => driver.update(objectName, id, data),
435+
delete: async (objectName: string, id: string) => driver.delete(objectName, id),
436+
count: async (objectName: string, filters: any) => driver.count(objectName, filters),
437+
};
438+
439+
kernel = {
440+
metadata,
441+
repository,
442+
driver,
443+
// Add engine methods that delegate to repository
444+
find: repository.find,
445+
get: repository.findOne,
446+
create: repository.create,
447+
update: repository.update,
448+
delete: repository.delete,
449+
count: repository.count
450+
};
451+
452+
// Create GraphQL plugin
359453
plugin = new GraphQLPlugin({
360454
port: testPort,
361455
introspection: true,
362456
playground: false // Disable playground in tests
363457
});
364458

365-
kernel = new ObjectKernel([
366-
new MemoryDriver(),
367-
plugin
368-
]);
369-
370-
// Register test entity
371-
kernel.metadata.register('object', 'tck_test_entity', {
372-
name: 'tck_test_entity',
373-
label: 'TCK Test Entity',
374-
fields: {
375-
name: { type: 'text', label: 'Name' },
376-
value: { type: 'number', label: 'Value' },
377-
active: { type: 'boolean', label: 'Active' }
378-
}
379-
});
380-
381-
await kernel.start();
459+
// Install and start plugin
460+
await plugin.install?.({ engine: kernel });
461+
await plugin.onStart?.({ engine: kernel });
382462

383463
// Wait for server to be ready
384464
await new Promise(resolve => setTimeout(resolve, 1000));
385465
}, 30000);
386466

387467
afterAll(async () => {
388-
await kernel.stop();
468+
if (plugin) {
469+
await plugin.onStop?.({ engine: kernel });
470+
}
389471
}, 30000);
390472

391473
// Run the Protocol TCK
@@ -403,9 +485,8 @@ describe('GraphQL Protocol TCK', () => {
403485
hooks: {
404486
beforeEach: async () => {
405487
// Clear data between tests
406-
const driver = kernel.getDriver();
407-
if (driver && typeof (driver as any).clear === 'function') {
408-
await (driver as any).clear();
488+
if (kernel?.driver && typeof kernel.driver.clear === 'function') {
489+
await kernel.driver.clear();
409490
}
410491
}
411492
},

0 commit comments

Comments
 (0)