From 00efacd98e9c030708fcbedcd15d5b5672999f4a Mon Sep 17 00:00:00 2001 From: Marcel Schwarz Date: Mon, 4 Mar 2024 17:40:44 +0100 Subject: [PATCH 1/9] Add enrich test with input object containing literal value on scalar field --- test/tests/enrich.test.js | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/test/tests/enrich.test.js b/test/tests/enrich.test.js index 168e73ff..dca02573 100644 --- a/test/tests/enrich.test.js +++ b/test/tests/enrich.test.js @@ -179,7 +179,7 @@ describe('graphql - enrich AST ', () => { expect(value).toEqual(2) }) - test('parsing of literal value in nested input value', async () => { + test('parsing of literal value in nested input value of a query with sub-selection of fields', async () => { const query = gql` { AdminService { @@ -198,6 +198,25 @@ describe('graphql - enrich AST ', () => { const value = enrichedAST[0].selectionSet.selections[0].arguments[0].value.fields[0].value.fields[0].value.value expect(value).toEqual(201) }) + + test('parsing of literal value in nested input value of a mutation with a scalar return type', async () => { + const query = gql` + mutation { + AdminService { + Authors { + delete(filter: { dateOfBirth: { eq: "1818-07-30T00:00:00.000Z" } }) + } + } + } + ` + const document = parse(query) + const fakeInfo = fakeInfoObject(document, bookshopSchema, 'Mutation') + const enrichedAST = enrich(fakeInfo) + const value = + enrichedAST[0].selectionSet.selections[0].selectionSet.selections[0].arguments[0].value.fields[0].value + .fields[0].value.value + expect(value).toEqual('1818-07-30') + }) }) describe('variable values are substituted into the AST', () => { From 984ffa8f376686cf8a212a1f154e5193f545d2c0 Mon Sep 17 00:00:00 2001 From: Marcel Schwarz Date: Mon, 4 Mar 2024 18:14:45 +0100 Subject: [PATCH 2/9] Add test for delete by non-key field --- test/tests/mutations/delete.test.js | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/test/tests/mutations/delete.test.js b/test/tests/mutations/delete.test.js index 919a19c0..aec52831 100644 --- a/test/tests/mutations/delete.test.js +++ b/test/tests/mutations/delete.test.js @@ -100,6 +100,35 @@ describe('graphql - delete mutations', () => { ]) }) + test('delete single entry by non-key field', async () => { + const query = gql` + mutation { + AdminService { + Books { + delete(filter: { title: { eq: "Jane Eyre" } }) + } + } + } + ` + const data = { + AdminService: { + Books: { + delete: 1 + } + } + } + const response = await POST('/graphql', { query }) + expect(response.data).toEqual({ data }) + + const result = await SELECT.from('sap.capire.bookshop.Books').columns('ID', 'title') + expect(result).toEqual([ + { ID: 201, title: 'Wuthering Heights' }, + { ID: 251, title: 'The Raven' }, + { ID: 252, title: 'Eleonora' }, + { ID: 271, title: 'Catweazle' } + ]) + }) + test('delete multiple entries', async () => { const query = gql` mutation ($filter: AdminService_Books_filter) { From b011146e1aaabd40c5c7354f1825ddd217c42056 Mon Sep 17 00:00:00 2001 From: Marcel Schwarz Date: Mon, 4 Mar 2024 18:17:13 +0100 Subject: [PATCH 3/9] Improve test title --- test/tests/mutations/delete.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/tests/mutations/delete.test.js b/test/tests/mutations/delete.test.js index aec52831..50bfbc1b 100644 --- a/test/tests/mutations/delete.test.js +++ b/test/tests/mutations/delete.test.js @@ -100,7 +100,7 @@ describe('graphql - delete mutations', () => { ]) }) - test('delete single entry by non-key field', async () => { + test('delete single entry by filtering for non-key field', async () => { const query = gql` mutation { AdminService { From 78856552100b502e6e21cfaf78f99fc1823a9187 Mon Sep 17 00:00:00 2001 From: Marcel Schwarz Date: Mon, 4 Mar 2024 18:17:31 +0100 Subject: [PATCH 4/9] Use index vs existence of `parseLiteral` fn to check if field is a leaf --- lib/resolvers/parse/ast/literal.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/resolvers/parse/ast/literal.js b/lib/resolvers/parse/ast/literal.js index 653a360f..a03d4113 100644 --- a/lib/resolvers/parse/ast/literal.js +++ b/lib/resolvers/parse/ast/literal.js @@ -12,8 +12,8 @@ const _getTypeFrom_fields = (_fields, path, index = 0) => { const _field = _fields[name] const type = _getTypeFrom_fieldOr_arg(_field) - // If type has the parseLiteral function it is a scalar type -> leaf -> end of path - if (type.parseLiteral) return type + // If we are at the end of the path, it is a leaf -> scalar type with parseLiteral function + if (index === path.length) return type const next = path[index] // Is the next path element an argument? If yes, follow the argument From b66e1c058b2cb7ae6f9baf919d0fe8342eeb83e3 Mon Sep 17 00:00:00 2001 From: Marcel Schwarz Date: Mon, 4 Mar 2024 18:27:07 +0100 Subject: [PATCH 5/9] Add changelog entry --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a720d5b..521c10f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- Type parsing error for literal values passed within arguments on fields of scalar type differing from the literal type. This case occurred for delete mutations where the filter operands have a type other than `Int`. + ### Removed ## Version 0.10.0 - 2023-01-30 From 536aa19d5cdfb56494a66652e22d48ccf753a9b4 Mon Sep 17 00:00:00 2001 From: Marcel Schwarz Date: Mon, 4 Mar 2024 18:28:27 +0100 Subject: [PATCH 6/9] Prettier format --- lib/resolvers/parse/ast2cqn/where.js | 3 ++- test/tests/annotations.test.js | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/resolvers/parse/ast2cqn/where.js b/lib/resolvers/parse/ast2cqn/where.js index 3004c3a1..ed3ef4c9 100644 --- a/lib/resolvers/parse/ast2cqn/where.js +++ b/lib/resolvers/parse/ast2cqn/where.js @@ -34,7 +34,8 @@ const _objectFieldTo_xpr = (objectField, columnName) => { const operand = objectField.value if (gqlOperator === LOGICAL_OPERATORS.in) { - const list = operand.kind === Kind.LIST ? operand.values.map(value => ({ val: value.value })) : [{ val: operand.value }] + const list = + operand.kind === Kind.LIST ? operand.values.map(value => ({ val: value.value })) : [{ val: operand.value }] return [ref, _gqlOperatorToCdsOperator(gqlOperator), { list }] } diff --git a/test/tests/annotations.test.js b/test/tests/annotations.test.js index df1d4806..696174ba 100644 --- a/test/tests/annotations.test.js +++ b/test/tests/annotations.test.js @@ -39,7 +39,9 @@ describe('graphql - annotations', () => { } ` const response = await POST(path, { query }) - expect(response.data.errors[0].message).toMatch(/^Cannot query field "AnnotatedWithAtProtocolNone" on type "Query"\./) + expect(response.data.errors[0].message).toMatch( + /^Cannot query field "AnnotatedWithAtProtocolNone" on type "Query"\./ + ) }) test('service annotated with non-GraphQL protocol is not served', async () => { From 43b318a3f16800059e6162a951ed1939152b3cd5 Mon Sep 17 00:00:00 2001 From: Marcel Schwarz Date: Mon, 4 Mar 2024 18:39:45 +0100 Subject: [PATCH 7/9] Improve test titles --- test/tests/enrich.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/tests/enrich.test.js b/test/tests/enrich.test.js index dca02573..311329e7 100644 --- a/test/tests/enrich.test.js +++ b/test/tests/enrich.test.js @@ -179,7 +179,7 @@ describe('graphql - enrich AST ', () => { expect(value).toEqual(2) }) - test('parsing of literal value in nested input value of a query with sub-selection of fields', async () => { + test('parsing of literal value in nested input value passed as arg on field with sub-selection of fields', async () => { const query = gql` { AdminService { @@ -199,7 +199,7 @@ describe('graphql - enrich AST ', () => { expect(value).toEqual(201) }) - test('parsing of literal value in nested input value of a mutation with a scalar return type', async () => { + test('parsing of literal value in nested input value passed as arg on field of scalar type', async () => { const query = gql` mutation { AdminService { From 1c3519158ed780966da19cf794917cdc158f2b89 Mon Sep 17 00:00:00 2001 From: Marcel Schwarz Date: Tue, 5 Mar 2024 14:47:48 +0100 Subject: [PATCH 8/9] Improve changelog wording --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 521c10f8..48931262 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed -- Type parsing error for literal values passed within arguments on fields of scalar type differing from the literal type. This case occurred for delete mutations where the filter operands have a type other than `Int`. +- Type parsing error for literal values passed within arguments on fields of scalar type differing from the literal type. This case occurred for delete mutations when the filter operands had a type other than `Int`. ### Removed From c647a08fba0d263b190cf9dbde42fa380ce0c413 Mon Sep 17 00:00:00 2001 From: Marcel Schwarz Date: Tue, 5 Mar 2024 14:52:20 +0100 Subject: [PATCH 9/9] Improve comment wording --- lib/resolvers/parse/ast/literal.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/resolvers/parse/ast/literal.js b/lib/resolvers/parse/ast/literal.js index a03d4113..aedb46f2 100644 --- a/lib/resolvers/parse/ast/literal.js +++ b/lib/resolvers/parse/ast/literal.js @@ -12,7 +12,7 @@ const _getTypeFrom_fields = (_fields, path, index = 0) => { const _field = _fields[name] const type = _getTypeFrom_fieldOr_arg(_field) - // If we are at the end of the path, it is a leaf -> scalar type with parseLiteral function + // If we are at the end of the path, this field is a leaf and therefore is of scalar type with a parseLiteral function if (index === path.length) return type const next = path[index]