Skip to content

Commit cfd3189

Browse files
committed
feat: fully working
1 parent 278808d commit cfd3189

File tree

8 files changed

+146
-158
lines changed

8 files changed

+146
-158
lines changed

spec/ParseGraphQLQueryComplexity.spec.js

Lines changed: 44 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ const gql = require('graphql-tag');
44
const { ApolloClient, InMemoryCache, createHttpLink } = require('@apollo/client/core');
55
const { ParseServer } = require('../');
66
const { ParseGraphQLServer } = require('../lib/GraphQL/ParseGraphQLServer');
7+
const Parse = require('parse/node');
8+
const fetch = (...args) => import('node-fetch').then(({ default: fetch }) => fetch(...args));
79

810
describe('ParseGraphQL Query Complexity', () => {
911
let parseServer;
@@ -29,7 +31,11 @@ describe('ParseGraphQL Query Complexity', () => {
2931

3032
const httpLink = createHttpLink({
3133
uri: 'http://localhost:13378/graphql',
32-
fetch: (...args) => import('node-fetch').then(({ default: fetch }) => fetch(...args)),
34+
fetch,
35+
headers: {
36+
'X-Parse-Application-Id': 'test',
37+
'X-Parse-Javascript-Key': 'test',
38+
},
3339
});
3440

3541
apolloClient = new ApolloClient({
@@ -57,20 +63,6 @@ describe('ParseGraphQL Query Complexity', () => {
5763
},
5864
});
5965

60-
const createUserMutation = gql`
61-
mutation {
62-
createUser(input: { fields: { username: "testuser", password: "password123" } }) {
63-
user {
64-
objectId
65-
username
66-
createdAt
67-
}
68-
}
69-
}
70-
`;
71-
72-
await apolloClient.mutate({ mutation: createUserMutation });
73-
7466
const query = gql`
7567
query {
7668
users {
@@ -86,7 +78,7 @@ describe('ParseGraphQL Query Complexity', () => {
8678
`;
8779

8880
const result = await apolloClient.query({ query });
89-
expect(result.data.users.edges.length).toBeGreaterThan(0);
81+
expect(result.data.users).toBeDefined();
9082
});
9183

9284
it('should reject queries exceeding fields limit', async () => {
@@ -115,7 +107,7 @@ describe('ParseGraphQL Query Complexity', () => {
115107
await apolloClient.query({ query });
116108
fail('Should have thrown an error');
117109
} catch (error) {
118-
expect(error.message).toContain('Number of fields selected exceeds maximum allowed');
110+
expect(error.networkError.result.errors[0].message).toContain('Number of fields selected exceeds maximum allowed');
119111
}
120112
});
121113

@@ -130,6 +122,7 @@ describe('ParseGraphQL Query Complexity', () => {
130122
uri: 'http://localhost:13378/graphql',
131123
fetch: (...args) => import('node-fetch').then(({ default: fetch }) => fetch(...args)),
132124
headers: {
125+
'X-Parse-Application-Id': 'test',
133126
'X-Parse-Master-Key': 'test',
134127
},
135128
});
@@ -148,7 +141,7 @@ describe('ParseGraphQL Query Complexity', () => {
148141
username
149142
createdAt
150143
updatedAt
151-
sessionToken
144+
email
152145
}
153146
}
154147
}
@@ -164,45 +157,25 @@ describe('ParseGraphQL Query Complexity', () => {
164157
it('should allow queries within depth limit', async () => {
165158
await reconfigureServer({
166159
maxGraphQLQueryComplexity: {
167-
depth: 3,
168-
},
169-
});
170-
171-
// Create test data with relationships
172-
const createClassMutation = gql`
173-
mutation {
174-
createClass(input: { name: "Post", schemaFields: { addStrings: [{ name: "title" }] } }) {
175-
class {
176-
name
177-
}
178-
}
179-
}
180-
`;
181-
182-
await apolloClient.mutate({
183-
mutation: createClassMutation,
184-
context: {
185-
headers: {
186-
'X-Parse-Master-Key': 'test',
187-
},
160+
depth: 4,
188161
},
189162
});
190163

191164
const query = gql`
192165
query {
193-
posts {
166+
users {
194167
edges {
195168
node {
196169
objectId
197-
title
170+
username
198171
}
199172
}
200173
}
201174
}
202175
`;
203176

204177
const result = await apolloClient.query({ query });
205-
expect(result.data.posts).toBeDefined();
178+
expect(result.data.users).toBeDefined();
206179
});
207180

208181
it('should reject queries exceeding depth limit', async () => {
@@ -229,7 +202,7 @@ describe('ParseGraphQL Query Complexity', () => {
229202
await apolloClient.query({ query });
230203
fail('Should have thrown an error');
231204
} catch (error) {
232-
expect(error.message).toContain('Query depth exceeds maximum allowed depth');
205+
expect(error.networkError.result.errors[0].message).toContain('Query depth exceeds maximum allowed depth');
233206
}
234207
});
235208

@@ -244,6 +217,7 @@ describe('ParseGraphQL Query Complexity', () => {
244217
uri: 'http://localhost:13378/graphql',
245218
fetch: (...args) => import('node-fetch').then(({ default: fetch }) => fetch(...args)),
246219
headers: {
220+
'X-Parse-Application-Id': 'test',
247221
'X-Parse-Master-Key': 'test',
248222
},
249223
});
@@ -283,6 +257,7 @@ describe('ParseGraphQL Query Complexity', () => {
283257
uri: 'http://localhost:13378/graphql',
284258
fetch: (...args) => import('node-fetch').then(({ default: fetch }) => fetch(...args)),
285259
headers: {
260+
'X-Parse-Application-Id': 'test',
286261
'X-Parse-Maintenance-Key': 'maintenanceKey123',
287262
},
288263
});
@@ -315,12 +290,12 @@ describe('ParseGraphQL Query Complexity', () => {
315290
it('should count fields in fragments correctly', async () => {
316291
await reconfigureServer({
317292
maxGraphQLQueryComplexity: {
318-
fields: 5,
293+
fields: 10,
319294
},
320295
});
321296

322297
const query = gql`
323-
fragment UserFields on User {
298+
fragment UserFields1 on User {
324299
objectId
325300
username
326301
createdAt
@@ -330,7 +305,7 @@ describe('ParseGraphQL Query Complexity', () => {
330305
users {
331306
edges {
332307
node {
333-
...UserFields
308+
...UserFields1
334309
}
335310
}
336311
}
@@ -349,7 +324,7 @@ describe('ParseGraphQL Query Complexity', () => {
349324
});
350325

351326
const query = gql`
352-
fragment UserFields on User {
327+
fragment UserFields2 on User {
353328
objectId
354329
username
355330
createdAt
@@ -360,7 +335,7 @@ describe('ParseGraphQL Query Complexity', () => {
360335
users {
361336
edges {
362337
node {
363-
...UserFields
338+
...UserFields2
364339
}
365340
}
366341
}
@@ -371,14 +346,14 @@ describe('ParseGraphQL Query Complexity', () => {
371346
await apolloClient.query({ query });
372347
fail('Should have thrown an error');
373348
} catch (error) {
374-
expect(error.message).toContain('Number of fields selected exceeds maximum allowed');
349+
expect(error.networkError.result.errors[0].message).toContain('Number of fields selected exceeds maximum allowed');
375350
}
376351
});
377352

378353
it('should handle inline fragments correctly', async () => {
379354
await reconfigureServer({
380355
maxGraphQLQueryComplexity: {
381-
fields: 5,
356+
fields: 10,
382357
},
383358
});
384359

@@ -402,41 +377,36 @@ describe('ParseGraphQL Query Complexity', () => {
402377
expect(result.data.users).toBeDefined();
403378
});
404379

405-
it('should handle cyclic fragment references (GraphQL validation prevents actual cycles)', async () => {
380+
it('should reject inline fragments exceeding fields limit', async () => {
406381
await reconfigureServer({
407382
maxGraphQLQueryComplexity: {
408-
fields: 10,
383+
fields: 3,
409384
},
410385
});
411386

412-
// Note: GraphQL's NoFragmentCycles validation rule prevents actual cycles
413-
// This test verifies that our complexity calculation doesn't break when
414-
// fragments reference each other (as long as there's no actual cycle)
415387
const query = gql`
416-
fragment UserBasicInfo on User {
417-
objectId
418-
username
419-
}
420-
421-
fragment UserDetailedInfo on User {
422-
...UserBasicInfo
423-
createdAt
424-
updatedAt
425-
}
426-
427388
query {
428389
users {
429390
edges {
430391
node {
431-
...UserDetailedInfo
392+
... on User {
393+
objectId
394+
username
395+
createdAt
396+
updatedAt
397+
}
432398
}
433399
}
434400
}
435401
}
436402
`;
437403

438-
const result = await apolloClient.query({ query });
439-
expect(result.data.users).toBeDefined();
404+
try {
405+
await apolloClient.query({ query });
406+
fail('Should have thrown an error');
407+
} catch (error) {
408+
expect(error.networkError.result.errors[0].message).toContain('Number of fields selected exceeds maximum allowed');
409+
}
440410
});
441411

442412
it('should reject actual cyclic fragment definitions with GraphQL validation error', async () => {
@@ -446,8 +416,6 @@ describe('ParseGraphQL Query Complexity', () => {
446416
},
447417
});
448418

449-
// This will fail at GraphQL parsing/validation level before our complexity check
450-
// because GraphQL has built-in NoFragmentCycles rule
451419
const queryString = `
452420
fragment FragmentA on User {
453421
objectId
@@ -471,13 +439,11 @@ describe('ParseGraphQL Query Complexity', () => {
471439
`;
472440

473441
try {
474-
// Try to parse the query with cyclic fragments
475442
const query = gql(queryString);
476443
await apolloClient.query({ query });
477444
fail('Should have thrown an error due to cyclic fragments');
478445
} catch (error) {
479-
// GraphQL validation should catch this before complexity calculation
480-
expect(error.message).toMatch(/cycle|Cannot spread fragment/i);
446+
expect(error.networkError?.result?.errors?.[0]?.message).toEqual('Cannot spread fragment "FragmentA" within itself via "FragmentB".');
481447
}
482448
});
483449
});
@@ -486,8 +452,8 @@ describe('ParseGraphQL Query Complexity', () => {
486452
it('should validate both depth and fields limits', async () => {
487453
await reconfigureServer({
488454
maxGraphQLQueryComplexity: {
489-
depth: 3,
490-
fields: 5,
455+
depth: 4,
456+
fields: 10,
491457
},
492458
});
493459

@@ -534,7 +500,7 @@ describe('ParseGraphQL Query Complexity', () => {
534500
await apolloClient.query({ query });
535501
fail('Should have thrown an error');
536502
} catch (error) {
537-
expect(error.message).toContain('Number of fields selected exceeds maximum allowed');
503+
expect(error.networkError.result.errors[0].message).toContain('Number of fields selected exceeds maximum allowed');
538504
}
539505
});
540506
});
@@ -552,9 +518,7 @@ describe('ParseGraphQL Query Complexity', () => {
552518
username
553519
createdAt
554520
updatedAt
555-
sessionToken
556-
authData
557-
ACL
521+
email
558522
}
559523
}
560524
}

0 commit comments

Comments
 (0)