Skip to content

Commit

Permalink
fix(enrich): parsing of literals passed within args on scalar fields (#…
Browse files Browse the repository at this point in the history
…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
  • Loading branch information
schwma authored Mar 5, 2024
1 parent 9ed44e0 commit 38caffe
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 5 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 when the filter operands had a type other than `Int`.

### Removed

## Version 0.10.0 - 2023-01-30
Expand Down
4 changes: 2 additions & 2 deletions lib/resolvers/parse/ast/literal.js
Original file line number Diff line number Diff line change
Expand Up @@ -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, 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]
// Is the next path element an argument? If yes, follow the argument
Expand Down
3 changes: 2 additions & 1 deletion lib/resolvers/parse/ast2cqn/where.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 }]
}

Expand Down
4 changes: 3 additions & 1 deletion test/tests/annotations.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 () => {
Expand Down
21 changes: 20 additions & 1 deletion test/tests/enrich.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 passed as arg on field with sub-selection of fields', async () => {
const query = gql`
{
AdminService {
Expand All @@ -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 passed as arg on field of scalar 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', () => {
Expand Down
29 changes: 29 additions & 0 deletions test/tests/mutations/delete.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,35 @@ describe('graphql - delete mutations', () => {
])
})

test('delete single entry by filtering for 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) {
Expand Down

0 comments on commit 38caffe

Please sign in to comment.