Skip to content

Commit

Permalink
feat(query-graphql): Added disableFilter and disableSort
Browse files Browse the repository at this point in the history
With these options you can disable the filter and sorting of relations.
  • Loading branch information
TriPSs committed May 27, 2022
1 parent f3ec75c commit 80cc8e9
Show file tree
Hide file tree
Showing 18 changed files with 340 additions and 103 deletions.
1 change: 1 addition & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"rules": {
// airbnb default is 1
"max-classes-per-file": ["error", 5],
"max-len": ["error", { "code": 130 }],
// never allow default export
"import/prefer-default-export": "off",
// never allow default export
Expand Down
2 changes: 1 addition & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"singleQuote": true,
"printWidth": 120,
"printWidth": 130,
"trailingComma": "none"
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,107 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`ReadRelationsResolver many should not add filter argument if disableFilter is true 1`] = `
type TestResolverDTO {
id: ID!
stringField: String!
relations(
"""Limit or page results."""
paging: CursorPaging = {first: 10}
"""Specify to sort results."""
sorting: [TestRelationDTOSort!] = []
): TestResolverDTORelationsConnection!
}
input CursorPaging {
"""Paginate before opaque cursor"""
before: ConnectionCursor
"""Paginate after opaque cursor"""
after: ConnectionCursor
"""Paginate first"""
first: Int
"""Paginate last"""
last: Int
}
"""Cursor for paging through collections"""
scalar ConnectionCursor
input TestRelationDTOSort {
field: TestRelationDTOSortFields!
direction: SortDirection!
nulls: SortNulls
}
enum TestRelationDTOSortFields {
id
testResolverId
}
"""Sort Directions"""
enum SortDirection {
ASC
DESC
}
"""Sort Nulls Options"""
enum SortNulls {
NULLS_FIRST
NULLS_LAST
}
type TestRelationDTO {
id: ID!
testResolverId: String!
}
type TestRelationDTOEdge {
"""The node containing the TestRelationDTO"""
node: TestRelationDTO!
"""Cursor for this node."""
cursor: ConnectionCursor!
}
type PageInfo {
"""true if paging forward and there are more records."""
hasNextPage: Boolean
"""true if paging backwards and there are more records."""
hasPreviousPage: Boolean
"""The cursor of the first returned record."""
startCursor: ConnectionCursor
"""The cursor of the last returned record."""
endCursor: ConnectionCursor
}
type TestResolverDTORelationsConnection {
"""Paging information"""
pageInfo: PageInfo!
"""Array of edges."""
edges: [TestRelationDTOEdge!]!
}
type OffsetPageInfo {
"""true if paging forward and there are more records."""
hasNextPage: Boolean
"""true if paging backwards and there are more records."""
hasPreviousPage: Boolean
}
type Query {
test: TestResolverDTO!
}
`;

exports[`ReadRelationsResolver many should not add read methods if disableRead is true 1`] = `
type TestResolverDTO {
id: ID!
Expand Down Expand Up @@ -50,6 +152,126 @@ type Query {
`;

exports[`ReadRelationsResolver many should not add sorting argument if disableSorting is true 1`] = `
type TestResolverDTO {
id: ID!
stringField: String!
relations(
"""Limit or page results."""
paging: CursorPaging = {first: 10}
"""Specify to filter the records returned."""
filter: TestRelationDTOFilter = {}
): TestResolverDTORelationsConnection!
}
input CursorPaging {
"""Paginate before opaque cursor"""
before: ConnectionCursor
"""Paginate after opaque cursor"""
after: ConnectionCursor
"""Paginate first"""
first: Int
"""Paginate last"""
last: Int
}
"""Cursor for paging through collections"""
scalar ConnectionCursor
input TestRelationDTOFilter {
and: [TestRelationDTOFilter!]
or: [TestRelationDTOFilter!]
id: IDFilterComparison
testResolverId: StringFieldComparison
}
input IDFilterComparison {
is: Boolean
isNot: Boolean
eq: ID
neq: ID
gt: ID
gte: ID
lt: ID
lte: ID
like: ID
notLike: ID
iLike: ID
notILike: ID
in: [ID!]
notIn: [ID!]
}
input StringFieldComparison {
is: Boolean
isNot: Boolean
eq: String
neq: String
gt: String
gte: String
lt: String
lte: String
like: String
notLike: String
iLike: String
notILike: String
in: [String!]
notIn: [String!]
}
type TestRelationDTO {
id: ID!
testResolverId: String!
}
type TestRelationDTOEdge {
"""The node containing the TestRelationDTO"""
node: TestRelationDTO!
"""Cursor for this node."""
cursor: ConnectionCursor!
}
type PageInfo {
"""true if paging forward and there are more records."""
hasNextPage: Boolean
"""true if paging backwards and there are more records."""
hasPreviousPage: Boolean
"""The cursor of the first returned record."""
startCursor: ConnectionCursor
"""The cursor of the last returned record."""
endCursor: ConnectionCursor
}
type TestResolverDTORelationsConnection {
"""Paging information"""
pageInfo: PageInfo!
"""Array of edges."""
edges: [TestRelationDTOEdge!]!
}
type OffsetPageInfo {
"""true if paging forward and there are more records."""
hasNextPage: Boolean
"""true if paging backwards and there are more records."""
hasPreviousPage: Boolean
}
type Query {
test: TestResolverDTO!
}
`;

exports[`ReadRelationsResolver many should set the field to nullable if set to true 1`] = `
type TestResolverDTO {
id: ID!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,7 @@ import {
PagingStrategies
} from '@ptc-org/nestjs-query-graphql';
import { ReadRelationsResolver, RelationsOpts } from '../../../src/resolvers/relations';
import {
generateSchema,
createResolverFromNest,
TestResolverDTO,
TestService,
TestRelationDTO
} from '../../__fixtures__';
import { generateSchema, createResolverFromNest, TestResolverDTO, TestService, TestRelationDTO } from '../../__fixtures__';

describe('ReadRelationsResolver', () => {
const expectResolverSDL = async (opts?: RelationsOpts) => {
Expand All @@ -30,6 +24,7 @@ describe('ReadRelationsResolver', () => {
};

it('should not add read methods if one and many are empty', () => expectResolverSDL());

describe('one', () => {
@Resolver(() => TestResolverDTO)
class TestResolver extends ReadRelationsResolver(TestResolverDTO, {
Expand Down Expand Up @@ -161,6 +156,12 @@ describe('ReadRelationsResolver', () => {
it('should not add read methods if disableRead is true', () =>
expectResolverSDL({ many: { relations: { DTO: TestRelationDTO, disableRead: true } } }));

it('should not add filter argument if disableFilter is true', () =>
expectResolverSDL({ many: { relation: { DTO: TestRelationDTO, disableFilter: true } } }));

it('should not add sorting argument if disableSorting is true', () =>
expectResolverSDL({ many: { relation: { DTO: TestRelationDTO, disableSort: true } } }));

describe('many connection query', () => {
@Resolver(() => TestResolverDTO)
class TestResolver extends ReadRelationsResolver(TestResolverDTO, {
Expand Down Expand Up @@ -442,9 +443,9 @@ describe('ReadRelationsResolver', () => {
testResolverId: dto.id
}
];
when(
mockService.queryRelations(TestRelationDTO, 'others', deepEqual([dto]), objectContaining(query))
).thenResolve(new Map([[dto, output]]));
when(mockService.queryRelations(TestRelationDTO, 'others', deepEqual([dto]), objectContaining(query))).thenResolve(
new Map([[dto, output]])
);
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
const result = await resolver.queryCustoms(dto, query, {});
Expand Down
24 changes: 6 additions & 18 deletions packages/query-graphql/__tests__/types/query/filter.type.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,7 @@ describe('filter types', (): void => {
@ObjectType('TestNoFields')
class TestInvalidFilter {}

expect(() => FilterType(TestInvalidFilter)).toThrow(
'No fields found to create GraphQLFilter for TestInvalidFilter'
);
expect(() => FilterType(TestInvalidFilter)).toThrow('No fields found to create GraphQLFilter for TestInvalidFilter');
});

it('should throw an error when the field type is unknown', () => {
Expand Down Expand Up @@ -411,9 +409,7 @@ describe('filter types', (): void => {
@ObjectType('TestNoFields')
class TestInvalidFilter {}

expect(() => UpdateFilterType(TestInvalidFilter)).toThrow(
'No fields found to create GraphQLFilter for TestInvalidFilter'
);
expect(() => UpdateFilterType(TestInvalidFilter)).toThrow('No fields found to create GraphQLFilter for TestInvalidFilter');
});

it('should throw an error when the field type is unknown', () => {
Expand All @@ -427,9 +423,7 @@ describe('filter types', (): void => {
fakeType!: EnumField;
}

expect(() => UpdateFilterType(TestInvalidFilter)).toThrow(
'Unable to create filter comparison for {"ONE":"one"}.'
);
expect(() => UpdateFilterType(TestInvalidFilter)).toThrow('Unable to create filter comparison for {"ONE":"one"}.');
});

it('should convert and filters to filter class', () => {
Expand Down Expand Up @@ -481,9 +475,7 @@ describe('filter types', (): void => {
@ObjectType('TestNoFields')
class TestInvalidFilter {}

expect(() => DeleteFilterType(TestInvalidFilter)).toThrow(
'No fields found to create GraphQLFilter for TestInvalidFilter'
);
expect(() => DeleteFilterType(TestInvalidFilter)).toThrow('No fields found to create GraphQLFilter for TestInvalidFilter');
});

it('should throw an error when the field type is unknown', () => {
Expand All @@ -497,9 +489,7 @@ describe('filter types', (): void => {
fakeType!: EnumField;
}

expect(() => DeleteFilterType(TestInvalidFilter)).toThrow(
'Unable to create filter comparison for {"ONE":"one"}.'
);
expect(() => DeleteFilterType(TestInvalidFilter)).toThrow('Unable to create filter comparison for {"ONE":"one"}.');
});

it('should convert and filters to filter class', () => {
Expand Down Expand Up @@ -567,9 +557,7 @@ describe('filter types', (): void => {
fakeType!: EnumField;
}

expect(() => SubscriptionFilterType(TestInvalidFilter)).toThrow(
'Unable to create filter comparison for {"ONE":"one"}.'
);
expect(() => SubscriptionFilterType(TestInvalidFilter)).toThrow('Unable to create filter comparison for {"ONE":"one"}.');
});

it('should convert and filters to filter class', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,22 @@ describe('SortingType', (): void => {
return 1;
}
}

const schema = await generateSchema([SortingTypeSpec]);
expect(schema).toMatchSnapshot();
});

it('should throw an error if the class is not annotated with @ObjectType', () => {
class BadTestSort {}

expect(() => getOrCreateSortType(BadTestSort)).toThrow(
'Unable to make SortType. Ensure BadTestSort is annotated with @nestjs/graphql @ObjectType'
);
});
it('should throw an error if no fields are found', () => {
@ObjectType()
class BadTestSort {}

expect(() => getOrCreateSortType(BadTestSort)).toThrow(
'No fields found to create SortType for BadTestSort. Ensure fields are annotated with @FilterableField'
);
Expand Down
2 changes: 1 addition & 1 deletion packages/query-graphql/src/decorators/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export {
FilterableUnPagedRelation,
Relation,
FilterableRelation,
RelationDecoratorOpts,
RelationOneDecoratorOpts,
RelationTypeFunc,
getRelations
} from './relation.decorator';
Expand Down
Loading

0 comments on commit 80cc8e9

Please sign in to comment.