diff --git a/libs/users/presentation/README.md b/libs/users/presentation/README.md new file mode 100644 index 0000000..255bbba --- /dev/null +++ b/libs/users/presentation/README.md @@ -0,0 +1,7 @@ +# users-presentation + +This library was generated with [Nx](https://nx.dev). + +## Running unit tests + +Run `nx test users-presentation` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/users/presentation/eslint.config.js b/libs/users/presentation/eslint.config.js new file mode 100644 index 0000000..07e518f --- /dev/null +++ b/libs/users/presentation/eslint.config.js @@ -0,0 +1,3 @@ +const baseConfig = require('../../../eslint.config.js'); + +module.exports = [...baseConfig]; diff --git a/libs/users/presentation/jest.config.ts b/libs/users/presentation/jest.config.ts new file mode 100644 index 0000000..9fb66bd --- /dev/null +++ b/libs/users/presentation/jest.config.ts @@ -0,0 +1,10 @@ +export default { + displayName: 'users-presentation', + preset: '../../../jest.preset.js', + testEnvironment: 'node', + transform: { + '^.+\\.[tj]s$': ['ts-jest', { tsconfig: '/tsconfig.spec.json' }], + }, + moduleFileExtensions: ['ts', 'js', 'html'], + coverageDirectory: '../../../coverage/libs/users/presentation', +}; diff --git a/libs/users/presentation/project.json b/libs/users/presentation/project.json new file mode 100644 index 0000000..b60d286 --- /dev/null +++ b/libs/users/presentation/project.json @@ -0,0 +1,9 @@ +{ + "name": "users-presentation", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/users/presentation/src", + "projectType": "library", + "tags": [], + "// targets": "to see all targets run: nx show project users-presentation --web", + "targets": {} +} diff --git a/libs/users/presentation/src/index.ts b/libs/users/presentation/src/index.ts new file mode 100644 index 0000000..281b820 --- /dev/null +++ b/libs/users/presentation/src/index.ts @@ -0,0 +1 @@ +export * from './lib/users.resolver'; diff --git a/libs/users/presentation/src/lib/users.resolver.spec.ts b/libs/users/presentation/src/lib/users.resolver.spec.ts new file mode 100644 index 0000000..c306133 --- /dev/null +++ b/libs/users/presentation/src/lib/users.resolver.spec.ts @@ -0,0 +1,68 @@ +import { Test, TestingModule } from '@nestjs/testing'; +import { UsersResolver } from './users.resolver'; +import { UsersService } from '../../../application/src/lib/users.service'; +import { User } from '@user/domain'; + +describe('UsersResolver', () => { + let resolver: UsersResolver; + let service: UsersService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + providers: [ + UsersResolver, + { + provide: UsersService, + useValue: { + findById: jest.fn(), + }, + }, + ], + }).compile(); + + resolver = module.get(UsersResolver); + service = module.get(UsersService); + }); + + it('should be defined', () => { + expect(resolver).toBeDefined(); + }); + + describe('getUser', () => { + it('should return a user by id', () => { + const user: User = { id: '1', name: 'John Doe' }; + jest.spyOn(service, 'findById').mockReturnValue(user); + + expect(resolver.getUser('1')).toEqual(user); + expect(service.findById).toHaveBeenCalledWith('1'); + }); + + it('should return undefined if user not found', () => { + jest.spyOn(service, 'findById').mockReturnValue(undefined); + + expect(resolver.getUser('2')).toBeUndefined(); + expect(service.findById).toHaveBeenCalledWith('2'); + }); + }); + + describe('resolveReference', () => { + it('should return a user by reference id', () => { + const user: User = { id: '1', name: 'John Doe' }; + jest.spyOn(service, 'findById').mockReturnValue(user); + + expect( + resolver.resolveReference({ __typename: 'User', id: '1' }), + ).toEqual(user); + expect(service.findById).toHaveBeenCalledWith('1'); + }); + + it('should return undefined if user not found by reference id', () => { + jest.spyOn(service, 'findById').mockReturnValue(undefined); + + expect( + resolver.resolveReference({ __typename: 'User', id: '2' }), + ).toBeUndefined(); + expect(service.findById).toHaveBeenCalledWith('2'); + }); + }); +}); diff --git a/libs/users/presentation/src/lib/users.resolver.ts b/libs/users/presentation/src/lib/users.resolver.ts new file mode 100644 index 0000000..25a13fd --- /dev/null +++ b/libs/users/presentation/src/lib/users.resolver.ts @@ -0,0 +1,22 @@ +import { Args, ID, Query, Resolver, ResolveReference } from '@nestjs/graphql'; +import { User } from '@user/domain'; + +import { UsersService } from '../../../application/src/lib/users.service'; + +@Resolver(() => User) +export class UsersResolver { + constructor(private usersService: UsersService) {} + + @Query(() => User, { nullable: true }) + getUser(@Args({ name: 'id', type: () => ID }) id: string): User | undefined { + return this.usersService.findById(id); + } + + @ResolveReference() + resolveReference(reference: { + __typename: string; + id: string; + }): User | undefined { + return this.usersService.findById(reference.id); + } +} diff --git a/libs/users/presentation/tsconfig.json b/libs/users/presentation/tsconfig.json new file mode 100644 index 0000000..0dc79ca --- /dev/null +++ b/libs/users/presentation/tsconfig.json @@ -0,0 +1,22 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "module": "commonjs", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "noPropertyAccessFromIndexSignature": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/libs/users/presentation/tsconfig.lib.json b/libs/users/presentation/tsconfig.lib.json new file mode 100644 index 0000000..e583571 --- /dev/null +++ b/libs/users/presentation/tsconfig.lib.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "commonjs", + "outDir": "../../../dist/out-tsc", + "declaration": true, + "types": ["node"] + }, + "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"], + "include": ["src/**/*.ts"] +} diff --git a/libs/users/presentation/tsconfig.spec.json b/libs/users/presentation/tsconfig.spec.json new file mode 100644 index 0000000..69a251f --- /dev/null +++ b/libs/users/presentation/tsconfig.spec.json @@ -0,0 +1,14 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": [ + "jest.config.ts", + "src/**/*.test.ts", + "src/**/*.spec.ts", + "src/**/*.d.ts" + ] +} diff --git a/tsconfig.base.json b/tsconfig.base.json index 32783aa..7c2161d 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -18,7 +18,8 @@ "@libs/config": ["libs/config/src/index.ts"], "@prompt/domain": ["libs/prompt/domain/src/index.ts"], "@user/domain": ["libs/user/domain/src/index.ts"], - "@users/application": ["libs/users/application/src/index.ts"] + "@users/application": ["libs/users/application/src/index.ts"], + "@users/presentation": ["libs/users/presentation/src/index.ts"] } }, "exclude": ["node_modules", "tmp"]