Skip to content

Commit 38caffe

Browse files
authored
fix(enrich): parsing of literals passed within args on scalar fields (#158)
* Add enrich test with input object containing literal value on scalar field * Add test for delete by non-key field * Improve test title * Use index vs existence of `parseLiteral` fn to check if field is a leaf * Add changelog entry * Prettier format * Improve test titles * Improve changelog wording * Improve comment wording
1 parent 9ed44e0 commit 38caffe

File tree

6 files changed

+58
-5
lines changed

6 files changed

+58
-5
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1313

1414
### Fixed
1515

16+
- 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`.
17+
1618
### Removed
1719

1820
## Version 0.10.0 - 2023-01-30

lib/resolvers/parse/ast/literal.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ const _getTypeFrom_fields = (_fields, path, index = 0) => {
1212
const _field = _fields[name]
1313
const type = _getTypeFrom_fieldOr_arg(_field)
1414

15-
// If type has the parseLiteral function it is a scalar type -> leaf -> end of path
16-
if (type.parseLiteral) return type
15+
// If we are at the end of the path, this field is a leaf and therefore is of scalar type with a parseLiteral function
16+
if (index === path.length) return type
1717

1818
const next = path[index]
1919
// Is the next path element an argument? If yes, follow the argument

lib/resolvers/parse/ast2cqn/where.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ const _objectFieldTo_xpr = (objectField, columnName) => {
3434
const operand = objectField.value
3535

3636
if (gqlOperator === LOGICAL_OPERATORS.in) {
37-
const list = operand.kind === Kind.LIST ? operand.values.map(value => ({ val: value.value })) : [{ val: operand.value }]
37+
const list =
38+
operand.kind === Kind.LIST ? operand.values.map(value => ({ val: value.value })) : [{ val: operand.value }]
3839
return [ref, _gqlOperatorToCdsOperator(gqlOperator), { list }]
3940
}
4041

test/tests/annotations.test.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ describe('graphql - annotations', () => {
3939
}
4040
`
4141
const response = await POST(path, { query })
42-
expect(response.data.errors[0].message).toMatch(/^Cannot query field "AnnotatedWithAtProtocolNone" on type "Query"\./)
42+
expect(response.data.errors[0].message).toMatch(
43+
/^Cannot query field "AnnotatedWithAtProtocolNone" on type "Query"\./
44+
)
4345
})
4446

4547
test('service annotated with non-GraphQL protocol is not served', async () => {

test/tests/enrich.test.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ describe('graphql - enrich AST ', () => {
179179
expect(value).toEqual(2)
180180
})
181181

182-
test('parsing of literal value in nested input value', async () => {
182+
test('parsing of literal value in nested input value passed as arg on field with sub-selection of fields', async () => {
183183
const query = gql`
184184
{
185185
AdminService {
@@ -198,6 +198,25 @@ describe('graphql - enrich AST ', () => {
198198
const value = enrichedAST[0].selectionSet.selections[0].arguments[0].value.fields[0].value.fields[0].value.value
199199
expect(value).toEqual(201)
200200
})
201+
202+
test('parsing of literal value in nested input value passed as arg on field of scalar type', async () => {
203+
const query = gql`
204+
mutation {
205+
AdminService {
206+
Authors {
207+
delete(filter: { dateOfBirth: { eq: "1818-07-30T00:00:00.000Z" } })
208+
}
209+
}
210+
}
211+
`
212+
const document = parse(query)
213+
const fakeInfo = fakeInfoObject(document, bookshopSchema, 'Mutation')
214+
const enrichedAST = enrich(fakeInfo)
215+
const value =
216+
enrichedAST[0].selectionSet.selections[0].selectionSet.selections[0].arguments[0].value.fields[0].value
217+
.fields[0].value.value
218+
expect(value).toEqual('1818-07-30')
219+
})
201220
})
202221

203222
describe('variable values are substituted into the AST', () => {

test/tests/mutations/delete.test.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,35 @@ describe('graphql - delete mutations', () => {
100100
])
101101
})
102102

103+
test('delete single entry by filtering for non-key field', async () => {
104+
const query = gql`
105+
mutation {
106+
AdminService {
107+
Books {
108+
delete(filter: { title: { eq: "Jane Eyre" } })
109+
}
110+
}
111+
}
112+
`
113+
const data = {
114+
AdminService: {
115+
Books: {
116+
delete: 1
117+
}
118+
}
119+
}
120+
const response = await POST('/graphql', { query })
121+
expect(response.data).toEqual({ data })
122+
123+
const result = await SELECT.from('sap.capire.bookshop.Books').columns('ID', 'title')
124+
expect(result).toEqual([
125+
{ ID: 201, title: 'Wuthering Heights' },
126+
{ ID: 251, title: 'The Raven' },
127+
{ ID: 252, title: 'Eleonora' },
128+
{ ID: 271, title: 'Catweazle' }
129+
])
130+
})
131+
103132
test('delete multiple entries', async () => {
104133
const query = gql`
105134
mutation ($filter: AdminService_Books_filter) {

0 commit comments

Comments
 (0)