Skip to content

Commit

Permalink
Issue #72
Browse files Browse the repository at this point in the history
- make types reusable
  • Loading branch information
doug-martin committed Apr 8, 2020
1 parent 2514bab commit 7141fd7
Show file tree
Hide file tree
Showing 23 changed files with 252 additions and 287 deletions.
4 changes: 4 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# v0.8.0

* Updated all `create`, 'update', and `delete` `InputTypes` to be abstract. [#72](https://github.com/doug-martin/nestjs-query/issues/72)

# v0.7.5

* [FIXED] Tables with composite primary keys are not quoted properly.
Expand Down
12 changes: 12 additions & 0 deletions documentation/blog/2020-04-02-v0.7.4.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
id: v0.7.4
title: v0.7.4
author: Doug Martin
author_title: Creator
author_url: https://github.com/doug-martin
author_image_url: https://avatars1.githubusercontent.com/u/361261?v=4
tags: [releases, patch]
---

* [FIXED] code formatting
* Update root package.json with common dependencies
12 changes: 12 additions & 0 deletions documentation/blog/2020-04-03-v0.7.5.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
id: v0.7.5
title: v0.7.5
author: Doug Martin
author_title: Creator
author_url: https://github.com/doug-martin
author_image_url: https://avatars1.githubusercontent.com/u/361261?v=4
tags: [releases, patch]
---

* [FIXED] Tables with composite primary keys are not quoted properly.
* [DOCS] Added docs for working with multiple connections [#73](https://github.com/doug-martin/nestjs-query/pull/73) - [@johannesschobel](https://github.com/johannesschobel)
11 changes: 11 additions & 0 deletions documentation/blog/2020-04-07-v0.8.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
id: v0.7.5
title: v0.7.5
author: Doug Martin
author_title: Creator
author_url: https://github.com/doug-martin
author_image_url: https://avatars1.githubusercontent.com/u/361261?v=4
tags: [releases, minor]
---

* Updated all `create`, 'update', and `delete` `InputTypes` to be abstract. [#72](https://github.com/doug-martin/nestjs-query/issues/72)
10 changes: 5 additions & 5 deletions documentation/docs/graphql/types.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ export class TodoItemInputDTO {
}

@InputType()
export class CreateOneTodoItemInput extends CreateOneInputType(TodoItemDTO, TodoItemInputDTO) {}
export class CreateOneTodoItemInput extends CreateOneInputType('todoItem', TodoItemInputDTO) {}
```
---

Expand Down Expand Up @@ -540,15 +540,15 @@ export class TodoItemInputDTO {
}

@InputType()
export class CreateManyTodoItemsInput extends CreateManyInputType(TodoItemDTO, TodoItemInputDTO) {}
export class CreateManyTodoItemsInput extends CreateManyInputType('todoItems', TodoItemInputDTO) {}
```

### UpdateOneInputType

InputType type for `updateOne` mutations.

The `UpdateOneInputType` will generate an `InputType` that will require the user to provide two fields.
* `id` - The id of the recrord to update
* `id` - The id of the record to update
* `update` - A record with fields to update.

**NOTE** Dont forget to annotate your DTO with `@InputType()` from `@nestjs/graphql`.
Expand All @@ -563,7 +563,7 @@ import { UpdateOneInputType } from '@nestjs-query/query-graphql';
import { InputType } from '@nestjs/graphql';
import { TodoItemDTO } from './dto/todo-item.dto';

@InputType('TodoItemUpdate')
@InputType('TodoItemUpdateInput')
export class TodoItemUpdateDTO {
@IsOptional()
@IsString()
Expand All @@ -577,7 +577,7 @@ export class TodoItemUpdateDTO {
}

@InputType()
export class UpdateOneTodoItemInput extends UpdateOneInputType(TodoItemDTO, TodoItemUpdateDTO) {}
export class UpdateOneTodoItemInput extends UpdateOneInputType(TodoItemUpdateDTO) {}
```
---

Expand Down
28 changes: 14 additions & 14 deletions packages/query-graphql/__tests__/resolvers/create.resolver.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,12 @@ describe('CreateResolver', () => {
}

it('should use the dtoName if provided', () => {
const CreateOneInput = CreateOneInputType(TestResolverDTO, TestResolverDTO);
class CreateOneInput extends CreateOneInputType('createResolverDTO', TestResolverDTO) {}
jest.clearAllMocks(); // reset
CreateResolver(TestResolverDTO, { dtoName: 'Test', CreateOneInput });

expect(createOneInputTypeSpy).not.toBeCalled();
expect(createManyInputTypeSpy).toBeCalledWith(TestResolverDTO, expect.any(Function));
expect(createManyInputTypeSpy).toBeCalledWith('tests', expect.any(Function));

expect(resolverMutationSpy).toBeCalledTimes(2);
assertResolverMutationCall(0, TestResolverDTO, { name: 'createOneTest' }, {}, {});
Expand All @@ -77,8 +77,8 @@ describe('CreateResolver', () => {
}
CreateResolver(UnnamedTestResolverDTO);

expect(createOneInputTypeSpy).toBeCalledWith(UnnamedTestResolverDTO, expect.any(Function));
expect(createManyInputTypeSpy).toBeCalledWith(UnnamedTestResolverDTO, expect.any(Function));
expect(createOneInputTypeSpy).toBeCalledWith('unnamedTestResolverDTO', expect.any(Function));
expect(createManyInputTypeSpy).toBeCalledWith('unnamedTestResolverDTOS', expect.any(Function));

expect(resolverMutationSpy).toBeCalledTimes(2);
assertResolverMutationCall(0, UnnamedTestResolverDTO, { name: 'createOneUnnamedTestResolverDTO' }, {}, {});
Expand All @@ -89,12 +89,12 @@ describe('CreateResolver', () => {

describe('#createOne', () => {
it('should not create a new type if the CreateOneArgs is supplied', () => {
const CreateOneInput = CreateOneInputType(TestResolverDTO, TestResolverDTO);
class CreateOneInput extends CreateOneInputType('createResolverDTO', TestResolverDTO) {}
jest.clearAllMocks(); // reset
CreateResolver(TestResolverDTO, { CreateOneInput });

expect(createOneInputTypeSpy).not.toBeCalled();
expect(createManyInputTypeSpy).toBeCalledWith(TestResolverDTO, expect.any(Function));
expect(createManyInputTypeSpy).toBeCalledWith('createResolverDTOS', expect.any(Function));

expect(resolverMutationSpy).toBeCalledTimes(2);
assertResolverMutationCall(0, TestResolverDTO, { name: 'createOneCreateResolverDTO' }, {}, {});
Expand All @@ -112,8 +112,8 @@ describe('CreateResolver', () => {
pipes: [],
};
CreateResolver(TestResolverDTO, { one: createOneOpts });
expect(createOneInputTypeSpy).toBeCalledWith(TestResolverDTO, expect.any(Function));
expect(createManyInputTypeSpy).toBeCalledWith(TestResolverDTO, expect.any(Function));
expect(createOneInputTypeSpy).toBeCalledWith('createResolverDTO', expect.any(Function));
expect(createManyInputTypeSpy).toBeCalledWith('createResolverDTOS', expect.any(Function));

expect(resolverMutationSpy).toBeCalledTimes(2);
assertResolverMutationCall(0, TestResolverDTO, { name: 'createOneCreateResolverDTO' }, {}, createOneOpts);
Expand All @@ -124,7 +124,7 @@ describe('CreateResolver', () => {

it('should call the service createOne with the provided input', async () => {
const mockService = mock<QueryService<TestResolverDTO>>();
const args: CreateOneInputType<TestResolverDTO, DeepPartial<TestResolverDTO>> = {
const args: CreateOneInputType<DeepPartial<TestResolverDTO>> = {
input: {
stringField: 'foo',
},
Expand All @@ -142,11 +142,11 @@ describe('CreateResolver', () => {

describe('#createMany', () => {
it('should not create a new type if the CreateManyArgs is supplied', () => {
const CreateManyInput = CreateManyInputType(TestResolverDTO, TestResolverDTO);
class CreateManyInput extends CreateManyInputType('testResolvers', TestResolverDTO) {}
jest.clearAllMocks(); // reset
CreateResolver(TestResolverDTO, { CreateManyInput });

expect(createOneInputTypeSpy).toBeCalledWith(TestResolverDTO, expect.any(Function));
expect(createOneInputTypeSpy).toBeCalledWith('createResolverDTO', expect.any(Function));
expect(createManyInputTypeSpy).not.toBeCalled();

expect(resolverMutationSpy).toBeCalledTimes(2);
Expand All @@ -165,8 +165,8 @@ describe('CreateResolver', () => {
pipes: [],
};
CreateResolver(TestResolverDTO, { many: createManyOpts });
expect(createOneInputTypeSpy).toBeCalledWith(TestResolverDTO, expect.any(Function));
expect(createManyInputTypeSpy).toBeCalledWith(TestResolverDTO, expect.any(Function));
expect(createOneInputTypeSpy).toBeCalledWith('createResolverDTO', expect.any(Function));
expect(createManyInputTypeSpy).toBeCalledWith('createResolverDTOS', expect.any(Function));

expect(resolverMutationSpy).toBeCalledTimes(2);
assertResolverMutationCall(0, TestResolverDTO, { name: 'createOneCreateResolverDTO' }, {}, {});
Expand All @@ -177,7 +177,7 @@ describe('CreateResolver', () => {

it('should call the service createMany with the provided input', async () => {
const mockService = mock<QueryService<TestResolverDTO>>();
const args: CreateManyInputType<TestResolverDTO, Partial<TestResolverDTO>> = {
const args: CreateManyInputType<Partial<TestResolverDTO>> = {
input: [
{
stringField: 'foo',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ describe('UpdateResolver', () => {
it('should create an UpdateResolver with the default DTO', () => {
UpdateResolver(TestResolverDTO);

expect(updateOneInputTypeSpy).toBeCalledWith(TestResolverDTO, expect.any(Function));
expect(updateOneInputTypeSpy).toBeCalledWith(expect.any(Function));
expect(updateManyInputTypeSpy).toBeCalledWith(TestResolverDTO, expect.any(Function));

expect(resolverMutationSpy).toBeCalledTimes(2);
Expand All @@ -72,7 +72,7 @@ describe('UpdateResolver', () => {
});

it('should use the dtoName if provided', () => {
const UpdateOneInput = UpdateOneInputType(TestResolverDTO, TestResolverDTO);
const UpdateOneInput = UpdateOneInputType(TestResolverDTO);
jest.clearAllMocks(); // reset
UpdateResolver(TestResolverDTO, { dtoName: 'Test', UpdateOneInput });

Expand All @@ -88,7 +88,7 @@ describe('UpdateResolver', () => {

describe('#updateOne', () => {
it('should not update a new type if the UpdateOneArgs is supplied', () => {
const UpdateOneInput = UpdateOneInputType(TestResolverDTO, TestResolverDTO);
const UpdateOneInput = UpdateOneInputType(TestResolverDTO);
jest.clearAllMocks(); // reset
UpdateResolver(TestResolverDTO, { UpdateOneInput });

Expand All @@ -111,7 +111,7 @@ describe('UpdateResolver', () => {
pipes: [],
};
UpdateResolver(TestResolverDTO, { one: updateOneOpts });
expect(updateOneInputTypeSpy).toBeCalledWith(TestResolverDTO, expect.any(Function));
expect(updateOneInputTypeSpy).toBeCalledWith(expect.any(Function));
expect(updateManyInputTypeSpy).toBeCalledWith(TestResolverDTO, expect.any(Function));

expect(resolverMutationSpy).toBeCalledTimes(2);
Expand All @@ -123,7 +123,7 @@ describe('UpdateResolver', () => {

it('should call the service updateOne with the provided input', async () => {
const mockService = mock<QueryService<TestResolverDTO>>();
const input: UpdateOneInputType<TestResolverDTO, Partial<TestResolverDTO>> = {
const input: UpdateOneInputType<Partial<TestResolverDTO>> = {
id: 'id-1',
update: {
stringField: 'foo',
Expand All @@ -146,7 +146,7 @@ describe('UpdateResolver', () => {
jest.clearAllMocks(); // reset
UpdateResolver(TestResolverDTO, { UpdateManyInput });

expect(updateOneInputTypeSpy).toBeCalledWith(TestResolverDTO, expect.any(Function));
expect(updateOneInputTypeSpy).toBeCalledWith(expect.any(Function));
expect(updateManyInputTypeSpy).not.toBeCalled();

expect(resolverMutationSpy).toBeCalledTimes(2);
Expand All @@ -165,7 +165,7 @@ describe('UpdateResolver', () => {
pipes: [],
};
UpdateResolver(TestResolverDTO, { many: updateManyOpts });
expect(updateOneInputTypeSpy).toBeCalledWith(TestResolverDTO, expect.any(Function));
expect(updateOneInputTypeSpy).toBeCalledWith(expect.any(Function));
expect(updateManyInputTypeSpy).toBeCalledWith(TestResolverDTO, expect.any(Function));

expect(resolverMutationSpy).toBeCalledTimes(2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,22 @@ describe('CreateManyInputType', (): void => {
}

it('should create an InputType with an array field', () => {
CreateManyInputType(FakeType, FakeType);
expect(inputTypeSpy).toBeCalledWith(`CreateManyFakeTypesInput`);
CreateManyInputType('fakeTypes', FakeType);
expect(inputTypeSpy).toBeCalledWith({ isAbstract: true });
expect(inputTypeSpy).toBeCalledTimes(1);
expect(fieldSpy.mock.calls[0]![0]!()).toEqual([FakeType]);
});

it('should properly assign the input field', () => {
const Type = CreateManyInputType(FakeType, FakeType);
class Type extends CreateManyInputType('fakeTypes', FakeType) {}
const input = [{ field: 'hello' }];
const it = plainToClass(Type, { input });
expect(it.input).toEqual(input);
it.input.forEach((i) => expect(i).toBeInstanceOf(FakeType));
});

it('should assign the typeName to the input field', () => {
const Type = CreateManyInputType(FakeType, FakeType);
class Type extends CreateManyInputType('fakeTypes', FakeType) {}
const input = [{ field: 'hello' }];
const it = plainToClass(Type, { fakeTypes: input });
expect(it.input).toEqual(input);
Expand All @@ -38,7 +38,7 @@ describe('CreateManyInputType', (): void => {

describe('validation', () => {
it('should validate the input property', () => {
const Type = CreateManyInputType(FakeType, FakeType);
class Type extends CreateManyInputType('fakeTypes', FakeType) {}
const input = [{ field: 'hola' }];
const it = plainToClass(Type, { input });
const errors = validateSync(it);
Expand Down Expand Up @@ -72,7 +72,7 @@ describe('CreateManyInputType', (): void => {
});

it('should assign the typeName to the input field', () => {
const Type = CreateManyInputType(FakeType, FakeType);
class Type extends CreateManyInputType('fakeTypes', FakeType) {}
const input = [{ field: 'hola' }];
const it = plainToClass(Type, { fakeTypes: input });
const errors = validateSync(it);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,23 @@ describe('CreateOneInputType', (): void => {
field!: string;
}
it('should create an InputType with the field as the type', () => {
CreateOneInputType(FakeType, FakeType);
expect(inputTypeSpy).toBeCalledWith(`CreateOneFakeTypeInput`);
CreateOneInputType('fakeType', FakeType);
expect(inputTypeSpy).toBeCalledWith({ isAbstract: true });
expect(inputTypeSpy).toBeCalledTimes(1);
expect(fieldSpy).toBeCalledTimes(1);
expect(fieldSpy.mock.calls[0]![0]!()).toEqual(FakeType);
});

it('should properly assign the input field', () => {
const Type = CreateOneInputType(FakeType, FakeType);
class Type extends CreateOneInputType('fakeType', FakeType) {}
const input = { field: 'hello' };
const it = plainToClass(Type, { input });
expect(it.input).toEqual(input);
expect(it.input).toBeInstanceOf(FakeType);
});

it('should assign the typeName to the input field', () => {
const Type = CreateOneInputType(FakeType, FakeType);
class Type extends CreateOneInputType('fakeType', FakeType) {}
const input = { field: 'hello' };
const it = plainToClass(Type, { fakeType: input });
expect(it.input).toEqual(input);
Expand All @@ -38,7 +38,7 @@ describe('CreateOneInputType', (): void => {

describe('validation', () => {
it('should validate the input property', () => {
const Type = CreateOneInputType(FakeType, FakeType);
class Type extends CreateOneInputType('fakeType', FakeType) {}
const input = { field: 'hola' };
const it = plainToClass(Type, { input });
const errors = validateSync(it);
Expand All @@ -63,7 +63,7 @@ describe('CreateOneInputType', (): void => {
});

it('should assign the typeName to the input field', () => {
const Type = CreateOneInputType(FakeType, FakeType);
class Type extends CreateOneInputType('fakeType', FakeType) {}
const input = { field: 'hola' };
const it = plainToClass(Type, { fakeType: input });
const errors = validateSync(it);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ describe('DeleteManyInputType', (): void => {

it('should create an args type with an array field', () => {
DeleteManyInputType(DeleteManyDTO);
expect(inputTypeSpy).toBeCalledWith(`DeleteManyDeleteManyDTOSInput`);
expect(inputTypeSpy).toBeCalledWith({ isAbstract: true });
expect(inputTypeSpy).toBeCalledTimes(1);
expect(fieldSpy).toHaveBeenCalledWith(expect.any(Function), {
description: 'Filter to find records to delete',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ describe('UpdateManyInputType', (): void => {
it('should create an args type with an array field', () => {
UpdateManyInputType(FakeType, FakeType);
expect(inputTypeSpy).toBeCalledTimes(1);
expect(inputTypeSpy).toBeCalledWith('UpdateManyFakeTypesInput');
expect(inputTypeSpy).toBeCalledWith({ isAbstract: true });
expect(fieldSpy).toBeCalledTimes(2);
expect(fieldSpy).toHaveBeenCalledWith(expect.any(Function), {
description: 'Filter used to find fields to update',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@ describe('UpdateOneInputType', (): void => {
name!: string;
}
it('should create an args type with the field as the type', () => {
UpdateOneInputType(FakeType, FakeType);
UpdateOneInputType(FakeType);
expect(inputType).toBeCalledTimes(1);
expect(inputType).toBeCalledWith(`UpdateOneFakeTypeInput`);
expect(inputType).toBeCalledWith({ isAbstract: true });
expect(fieldSpy).toBeCalledTimes(2);
expect(fieldSpy.mock.calls[0]![0]!()).toEqual(nestjsGraphql.ID);
expect(fieldSpy.mock.calls[1]![0]!()).toEqual(FakeType);
});

describe('validation', () => {
it('should validate id is defined is not empty', () => {
const Type = UpdateOneInputType(FakeType, FakeType);
const Type = UpdateOneInputType(FakeType);
const input = { update: { name: 'hello world' } };
const it = plainToClass(Type, input);
const errors = validateSync(it);
Expand All @@ -42,7 +42,7 @@ describe('UpdateOneInputType', (): void => {
});

it('should validate id is not empty is defined is not empty', () => {
const Type = UpdateOneInputType(FakeType, FakeType);
const Type = UpdateOneInputType(FakeType);
const input = { id: '', update: { name: 'hello world' } };
const it = plainToClass(Type, input);
const errors = validateSync(it);
Expand All @@ -60,7 +60,7 @@ describe('UpdateOneInputType', (): void => {
});

it('should validate the update input', () => {
const Type = UpdateOneInputType(FakeType, FakeType);
const Type = UpdateOneInputType(FakeType);
const input = { id: 'id-1', update: {} };
const it = plainToClass(Type, input);
const errors = validateSync(it);
Expand Down
Loading

0 comments on commit 7141fd7

Please sign in to comment.