Skip to content

Commit

Permalink
feat(graphql,hooks): Provide support for injectable hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
doug-martin committed Feb 26, 2021
1 parent 13e251b commit d100de8
Show file tree
Hide file tree
Showing 22 changed files with 456 additions and 262 deletions.
145 changes: 108 additions & 37 deletions packages/query-graphql/__tests__/decorators/hook.decorator.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// eslint-disable-next-line max-classes-per-file
import { Class } from '@nestjs-query/core';
import {
BeforeCreateMany,
BeforeCreateOne,
Expand All @@ -8,26 +9,19 @@ import {
BeforeDeleteMany,
BeforeQueryMany,
BeforeFindOne,
Hook,
} from '../../src';
import {
getCreateManyHook,
getCreateOneHook,
getUpdateOneHook,
getUpdateManyHook,
getDeleteOneHook,
getDeleteManyHook,
getQueryManyHook,
getFindOneHook,
} from '../../src/decorators';
import { getHookForType } from '../../src/decorators';
import { createDefaultHook, HookTypes } from '../../src/hooks';

describe('hook decorators', () => {
describe('@BeforeCreateOne', () => {
it('should store the hook', () => {
const hookFn = jest.fn();
@BeforeCreateOne(hookFn)
class Test {}

expect(getCreateOneHook(Test)).toBe(hookFn);
const Stored: Class<Hook<any>> = getHookForType(HookTypes.BEFORE_CREATE_ONE, Test)!;
expect(new Stored()).toEqual({ run: hookFn });
});

it('should return a hook from the base class', () => {
Expand All @@ -37,7 +31,8 @@ describe('hook decorators', () => {

class Test extends Base {}

expect(getCreateOneHook(Test)).toBe(hookFn);
const Stored: Class<Hook<any>> = getHookForType(HookTypes.BEFORE_CREATE_ONE, Test)!;
expect(new Stored()).toEqual({ run: hookFn });
});

it('should return a hook from the child class if there is a hook on both the base and child', () => {
Expand All @@ -49,7 +44,15 @@ describe('hook decorators', () => {
@BeforeCreateOne(childHookFn)
class Test extends Base {}

expect(getCreateOneHook(Test)).toBe(childHookFn);
const Stored: Class<Hook<any>> = getHookForType(HookTypes.BEFORE_CREATE_ONE, Test)!;
expect(new Stored()).toEqual({ run: childHookFn });
});

it('should return the hook class', () => {
const MockHook = createDefaultHook(jest.fn());
@BeforeCreateOne(MockHook)
class Test {}
expect(getHookForType(HookTypes.BEFORE_CREATE_ONE, Test)).toBe(MockHook);
});
});

Expand All @@ -59,7 +62,8 @@ describe('hook decorators', () => {
@BeforeCreateMany(hookFn)
class Test {}

expect(getCreateManyHook(Test)).toBe(hookFn);
const Stored: Class<Hook<any>> = getHookForType(HookTypes.BEFORE_CREATE_MANY, Test)!;
expect(new Stored()).toEqual({ run: hookFn });
});

it('should return a hook from the base class', () => {
Expand All @@ -69,7 +73,8 @@ describe('hook decorators', () => {

class Test extends Base {}

expect(getCreateManyHook(Test)).toBe(hookFn);
const Stored: Class<Hook<any>> = getHookForType(HookTypes.BEFORE_CREATE_MANY, Test)!;
expect(new Stored()).toEqual({ run: hookFn });
});

it('should return a hook from the child class if there is a hook on both the base and child', () => {
Expand All @@ -81,7 +86,15 @@ describe('hook decorators', () => {
@BeforeCreateMany(childHookFn)
class Test extends Base {}

expect(getCreateManyHook(Test)).toBe(childHookFn);
const Stored: Class<Hook<any>> = getHookForType(HookTypes.BEFORE_CREATE_MANY, Test)!;
expect(new Stored()).toEqual({ run: childHookFn });
});

it('should return the hook class', () => {
const MockHook = createDefaultHook(jest.fn());
@BeforeCreateMany(MockHook)
class Test {}
expect(getHookForType(HookTypes.BEFORE_CREATE_MANY, Test)).toBe(MockHook);
});
});

Expand All @@ -90,8 +103,8 @@ describe('hook decorators', () => {
const hookFn = jest.fn();
@BeforeUpdateOne(hookFn)
class Test {}

expect(getUpdateOneHook(Test)).toBe(hookFn);
const Stored: Class<Hook<any>> = getHookForType(HookTypes.BEFORE_UPDATE_ONE, Test)!;
expect(new Stored()).toEqual({ run: hookFn });
});

it('should return a hook from the base class', () => {
Expand All @@ -100,8 +113,8 @@ describe('hook decorators', () => {
class Base {}

class Test extends Base {}

expect(getUpdateOneHook(Test)).toBe(hookFn);
const Stored: Class<Hook<any>> = getHookForType(HookTypes.BEFORE_UPDATE_ONE, Test)!;
expect(new Stored()).toEqual({ run: hookFn });
});

it('should return a hook from the child class if there is a hook on both the base and child', () => {
Expand All @@ -113,7 +126,15 @@ describe('hook decorators', () => {
@BeforeUpdateOne(childHookFn)
class Test extends Base {}

expect(getUpdateOneHook(Test)).toBe(childHookFn);
const Stored: Class<Hook<any>> = getHookForType(HookTypes.BEFORE_UPDATE_ONE, Test)!;
expect(new Stored()).toEqual({ run: childHookFn });
});

it('should return the hook class', () => {
const MockHook = createDefaultHook(jest.fn());
@BeforeUpdateOne(MockHook)
class Test {}
expect(getHookForType(HookTypes.BEFORE_UPDATE_ONE, Test)).toBe(MockHook);
});
});

Expand All @@ -123,7 +144,8 @@ describe('hook decorators', () => {
@BeforeUpdateMany(hookFn)
class Test {}

expect(getUpdateManyHook(Test)).toBe(hookFn);
const Stored: Class<Hook<any>> = getHookForType(HookTypes.BEFORE_UPDATE_MANY, Test)!;
expect(new Stored()).toEqual({ run: hookFn });
});

it('should return a hook from the base class', () => {
Expand All @@ -133,7 +155,8 @@ describe('hook decorators', () => {

class Test extends Base {}

expect(getUpdateManyHook(Test)).toBe(hookFn);
const Stored: Class<Hook<any>> = getHookForType(HookTypes.BEFORE_UPDATE_MANY, Test)!;
expect(new Stored()).toEqual({ run: hookFn });
});

it('should return a hook from the child class if there is a hook on both the base and child', () => {
Expand All @@ -145,7 +168,15 @@ describe('hook decorators', () => {
@BeforeUpdateMany(childHookFn)
class Test extends Base {}

expect(getUpdateManyHook(Test)).toBe(childHookFn);
const Stored: Class<Hook<any>> = getHookForType(HookTypes.BEFORE_UPDATE_MANY, Test)!;
expect(new Stored()).toEqual({ run: childHookFn });
});

it('should return the hook class', () => {
const MockHook = createDefaultHook(jest.fn());
@BeforeUpdateMany(MockHook)
class Test {}
expect(getHookForType(HookTypes.BEFORE_UPDATE_MANY, Test)).toBe(MockHook);
});
});

Expand All @@ -155,7 +186,8 @@ describe('hook decorators', () => {
@BeforeDeleteOne(hookFn)
class Test {}

expect(getDeleteOneHook(Test)).toBe(hookFn);
const Stored: Class<Hook<any>> = getHookForType(HookTypes.BEFORE_DELETE_ONE, Test)!;
expect(new Stored()).toEqual({ run: hookFn });
});

it('should return a hook from the base class', () => {
Expand All @@ -165,7 +197,8 @@ describe('hook decorators', () => {

class Test extends Base {}

expect(getDeleteOneHook(Test)).toBe(hookFn);
const Stored: Class<Hook<any>> = getHookForType(HookTypes.BEFORE_DELETE_ONE, Test)!;
expect(new Stored()).toEqual({ run: hookFn });
});

it('should return a hook from the child class if there is a hook on both the base and child', () => {
Expand All @@ -177,7 +210,15 @@ describe('hook decorators', () => {
@BeforeDeleteOne(childHookFn)
class Test extends Base {}

expect(getDeleteOneHook(Test)).toBe(childHookFn);
const Stored: Class<Hook<any>> = getHookForType(HookTypes.BEFORE_DELETE_ONE, Test)!;
expect(new Stored()).toEqual({ run: childHookFn });
});

it('should return the hook class', () => {
const MockHook = createDefaultHook(jest.fn());
@BeforeDeleteOne(MockHook)
class Test {}
expect(getHookForType(HookTypes.BEFORE_DELETE_ONE, Test)).toBe(MockHook);
});
});

Expand All @@ -187,7 +228,8 @@ describe('hook decorators', () => {
@BeforeDeleteMany(hookFn)
class Test {}

expect(getDeleteManyHook(Test)).toBe(hookFn);
const Stored: Class<Hook<any>> = getHookForType(HookTypes.BEFORE_DELETE_MANY, Test)!;
expect(new Stored()).toEqual({ run: hookFn });
});

it('should return a hook from the base class', () => {
Expand All @@ -197,7 +239,8 @@ describe('hook decorators', () => {

class Test extends Base {}

expect(getDeleteManyHook(Test)).toBe(hookFn);
const Stored: Class<Hook<any>> = getHookForType(HookTypes.BEFORE_DELETE_MANY, Test)!;
expect(new Stored()).toEqual({ run: hookFn });
});

it('should return a hook from the child class if there is a hook on both the base and child', () => {
Expand All @@ -209,7 +252,15 @@ describe('hook decorators', () => {
@BeforeDeleteMany(childHookFn)
class Test extends Base {}

expect(getDeleteManyHook(Test)).toBe(childHookFn);
const Stored: Class<Hook<any>> = getHookForType(HookTypes.BEFORE_DELETE_MANY, Test)!;
expect(new Stored()).toEqual({ run: childHookFn });
});

it('should return the hook class', () => {
const MockHook = createDefaultHook(jest.fn());
@BeforeDeleteMany(MockHook)
class Test {}
expect(getHookForType(HookTypes.BEFORE_DELETE_MANY, Test)).toBe(MockHook);
});
});

Expand All @@ -219,7 +270,8 @@ describe('hook decorators', () => {
@BeforeQueryMany(hookFn)
class Test {}

expect(getQueryManyHook(Test)).toBe(hookFn);
const Stored: Class<Hook<any>> = getHookForType(HookTypes.BEFORE_QUERY_MANY, Test)!;
expect(new Stored()).toEqual({ run: hookFn });
});

it('should return a hook from the base class', () => {
Expand All @@ -229,7 +281,8 @@ describe('hook decorators', () => {

class Test extends Base {}

expect(getQueryManyHook(Test)).toBe(hookFn);
const Stored: Class<Hook<any>> = getHookForType(HookTypes.BEFORE_QUERY_MANY, Test)!;
expect(new Stored()).toEqual({ run: hookFn });
});

it('should return a hook from the child class if there is a hook on both the base and child', () => {
Expand All @@ -241,7 +294,15 @@ describe('hook decorators', () => {
@BeforeQueryMany(childHookFn)
class Test extends Base {}

expect(getQueryManyHook(Test)).toBe(childHookFn);
const Stored: Class<Hook<any>> = getHookForType(HookTypes.BEFORE_QUERY_MANY, Test)!;
expect(new Stored()).toEqual({ run: childHookFn });
});

it('should return the hook class', () => {
const MockHook = createDefaultHook(jest.fn());
@BeforeQueryMany(MockHook)
class Test {}
expect(getHookForType(HookTypes.BEFORE_QUERY_MANY, Test)).toBe(MockHook);
});
});

Expand All @@ -251,7 +312,8 @@ describe('hook decorators', () => {
@BeforeFindOne(hookFn)
class Test {}

expect(getFindOneHook(Test)).toBe(hookFn);
const Stored: Class<Hook<any>> = getHookForType(HookTypes.BEFORE_FIND_ONE, Test)!;
expect(new Stored()).toEqual({ run: hookFn });
});

it('should return a hook from the base class', () => {
Expand All @@ -261,7 +323,8 @@ describe('hook decorators', () => {

class Test extends Base {}

expect(getFindOneHook(Test)).toBe(hookFn);
const Stored: Class<Hook<any>> = getHookForType(HookTypes.BEFORE_FIND_ONE, Test)!;
expect(new Stored()).toEqual({ run: hookFn });
});

it('should return a hook from the child class if there is a hook on both the base and child', () => {
Expand All @@ -273,7 +336,15 @@ describe('hook decorators', () => {
@BeforeFindOne(childHookFn)
class Test extends Base {}

expect(getFindOneHook(Test)).toBe(childHookFn);
const Stored: Class<Hook<any>> = getHookForType(HookTypes.BEFORE_FIND_ONE, Test)!;
expect(new Stored()).toEqual({ run: childHookFn });
});

it('should return the hook class', () => {
const MockHook = createDefaultHook(jest.fn());
@BeforeFindOne(MockHook)
class Test {}
expect(getHookForType(HookTypes.BEFORE_FIND_ONE, Test)).toBe(MockHook);
});
});
});
12 changes: 0 additions & 12 deletions packages/query-graphql/src/decorators/constants.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,3 @@
export const BEFORE_CREATE_ONE_KEY = 'nestjs-query:before-create-one';
export const BEFORE_CREATE_MANY_KEY = 'nestjs-query:before-create-many';

export const BEFORE_UPDATE_ONE_KEY = 'nestjs-query:before-update-one';
export const BEFORE_UPDATE_MANY_KEY = 'nestjs-query:before-update-many';

export const BEFORE_DELETE_ONE_KEY = 'nestjs-query:before-delete-one';
export const BEFORE_DELETE_MANY_KEY = 'nestjs-query:before-delete-many';

export const BEFORE_QUERY_MANY_KEY = 'nestjs-query:before-query-many';
export const BEFORE_FIND_ONE_KEY = 'nestjs-query:before-find-one';

export const FILTERABLE_FIELD_KEY = 'nestjs-query:filterable-field';
export const RELATION_KEY = 'nestjs-query:relation';
export const REFERENCE_KEY = 'nestjs-query:reference';
Expand Down
Loading

0 comments on commit d100de8

Please sign in to comment.