@@ -1,5 +1,5 @@ | |||
{ | |||
"name": "@modal-sh/cli", | |||
"name": "@modal-sh/minecraft-uuid-cli", | |||
"version": "0.0.0", | |||
"files": [ | |||
"dist", | |||
@@ -66,7 +66,7 @@ | |||
}, | |||
"dependencies": { | |||
"@clack/prompts": "^0.6.3", | |||
"@modal-sh/core": "workspace:*", | |||
"@modal-sh/minecraft-uuid-core": "workspace:*", | |||
"pino": "^8.14.1", | |||
"yargs": "^17.7.2" | |||
} | |||
@@ -1,22 +1,15 @@ | |||
import { Cli } from './packages/cli-wrapper'; | |||
import { AdderController, AdderControllerImpl } from './modules/adder'; | |||
import { UuidController, AdderControllerImpl } from './modules/uuid'; | |||
export const addCommands = (cli: Cli) => { | |||
const adderController: AdderController = new AdderControllerImpl(); | |||
const uuidController: UuidController = new AdderControllerImpl(); | |||
return cli | |||
.command({ | |||
aliases: ['a'], | |||
command: 'add', | |||
parameters: ['<a> <b>'], | |||
describe: 'Add two numbers', | |||
handler: adderController.addNumbers, | |||
}) | |||
.command({ | |||
aliases: ['s'], | |||
command: 'subtract', | |||
parameters: ['<a> <b>'], | |||
describe: 'Subtract two numbers', | |||
handler: adderController.subtractNumbers, | |||
aliases: ['u'], | |||
command: 'uuid', | |||
parameters: ['<username>'], | |||
describe: 'Get equivalent UUID of username in Minecraft.', | |||
handler: uuidController.getUsernameUuid, | |||
}); | |||
}; |
@@ -1,82 +0,0 @@ | |||
import { | |||
AdderService, | |||
AdderServiceImpl, | |||
ArgumentOutOfRangeError, | |||
InvalidArgumentTypeError, | |||
} from './adder.service'; | |||
import { CommandHandler } from '../../packages/cli-wrapper'; | |||
export interface AdderController { | |||
addNumbers: CommandHandler; | |||
subtractNumbers: CommandHandler; | |||
} | |||
export class AdderControllerImpl implements AdderController { | |||
constructor( | |||
private readonly adderService: AdderService = new AdderServiceImpl(), | |||
) { | |||
// noop | |||
} | |||
readonly addNumbers: CommandHandler = (params) => { | |||
if (!params.interactive) { | |||
const checkArgs = params.args as Record<string, unknown>; | |||
if (typeof checkArgs.a === 'undefined') { | |||
params.logger.error('Missing required argument: a'); | |||
return -1; | |||
} | |||
if (typeof checkArgs.b === 'undefined') { | |||
params.logger.error('Missing required argument: b'); | |||
return -1; | |||
} | |||
} | |||
const { a, b } = params.args; | |||
try { | |||
const response = this.adderService.addNumbers({ a: Number(a), b: Number(b) }); | |||
params.logger.info(response); | |||
} catch (errorRaw) { | |||
const error = errorRaw as Error; | |||
params.logger.error(error.message); | |||
if (error instanceof InvalidArgumentTypeError) { | |||
return -1; | |||
} | |||
if (error instanceof ArgumentOutOfRangeError) { | |||
return -2; | |||
} | |||
return -3; | |||
} | |||
return 0; | |||
} | |||
readonly subtractNumbers: CommandHandler = (params) => { | |||
if (!params.interactive) { | |||
const checkArgs = params.args as Record<string, unknown>; | |||
if (typeof checkArgs.a === 'undefined') { | |||
params.logger.error('Missing required argument: a'); | |||
return -1; | |||
} | |||
if (typeof checkArgs.b === 'undefined') { | |||
params.logger.error('Missing required argument: b'); | |||
return -1; | |||
} | |||
} | |||
const { a, b } = params.args; | |||
try { | |||
const response = this.adderService.addNumbers({ a: Number(a), b: -(Number(b)) }); | |||
params.logger.info(response); | |||
} catch (errorRaw) { | |||
const error = errorRaw as Error; | |||
params.logger.error(error.message); | |||
if (error instanceof InvalidArgumentTypeError) { | |||
return -1; | |||
} | |||
if (error instanceof ArgumentOutOfRangeError) { | |||
return -2; | |||
} | |||
return -3; | |||
} | |||
return 0; | |||
} | |||
} |
@@ -1,21 +0,0 @@ | |||
import { | |||
add, | |||
AddFunctionOptions, | |||
ArgumentOutOfRangeError, | |||
InvalidArgumentTypeError, | |||
} from '@modal-sh/core'; | |||
export interface AdderService { | |||
addNumbers(options: AddFunctionOptions): number; | |||
} | |||
export class AdderServiceImpl implements AdderService { | |||
addNumbers(options: AddFunctionOptions) { | |||
return add(options); | |||
} | |||
} | |||
export { | |||
ArgumentOutOfRangeError, | |||
InvalidArgumentTypeError, | |||
}; |
@@ -1,2 +0,0 @@ | |||
export * from './adder.controller'; | |||
export * from './adder.service'; |
@@ -0,0 +1,2 @@ | |||
export * from './uuid.controller'; | |||
export * from './uuid.service'; |
@@ -0,0 +1,42 @@ | |||
import { | |||
UuidService, | |||
UuidServiceImpl, | |||
InvalidArgumentTypeError, | |||
} from './uuid.service'; | |||
import { CommandHandler } from '@/packages/cli-wrapper'; | |||
export interface UuidController { | |||
getUsernameUuid: CommandHandler; | |||
} | |||
export class AdderControllerImpl implements UuidController { | |||
constructor( | |||
private readonly uuidService: UuidService = new UuidServiceImpl(), | |||
) { | |||
// noop | |||
} | |||
readonly getUsernameUuid: CommandHandler = async (params) => { | |||
if (!params.interactive) { | |||
const checkArgs = params.args as Record<string, unknown>; | |||
if (typeof checkArgs.username === 'undefined') { | |||
params.logger.error('Missing required argument: username'); | |||
return -1; | |||
} | |||
} | |||
const { username, onlineMode } = params.args; | |||
try { | |||
const response = await this.uuidService.getUsernameUuid({ username, onlineMode }); | |||
params.logger.info(response); | |||
} catch (errorRaw) { | |||
const error = errorRaw as Error; | |||
params.logger.error(error.message); | |||
if (error instanceof InvalidArgumentTypeError) { | |||
return -1; | |||
} | |||
return -3; | |||
} | |||
return 0; | |||
} | |||
} |
@@ -0,0 +1,19 @@ | |||
import { | |||
getUsernameUuid, | |||
GetUsernameUuidOptions, | |||
InvalidArgumentTypeError, | |||
} from '@modal-sh/minecraft-uuid-core'; | |||
export interface UuidService { | |||
getUsernameUuid(options: GetUsernameUuidOptions): Promise<string>; | |||
} | |||
export class UuidServiceImpl implements UuidService { | |||
getUsernameUuid(options: GetUsernameUuidOptions) { | |||
return getUsernameUuid(options); | |||
} | |||
} | |||
export { | |||
InvalidArgumentTypeError, | |||
}; |
@@ -1,7 +1,7 @@ | |||
import { describe, it, expect, vi, beforeAll } from 'vitest'; | |||
import { createCli } from '../src/cli'; | |||
import { addCommands } from '../src/commands'; | |||
import { AdderServiceImpl, InvalidArgumentTypeError, ArgumentOutOfRangeError } from '../src/modules/adder'; | |||
import { UuidServiceImpl, InvalidArgumentTypeError } from '../src/modules/uuid'; | |||
import { Cli } from '../src/packages/cli-wrapper'; | |||
vi.mock('process'); | |||
@@ -17,39 +17,30 @@ describe('blah', () => { | |||
}); | |||
it('returns result when successful', async () => { | |||
const response = await cli.test().run(['add', '1', '2']); | |||
const response = await cli.test().run(['uuid', 'username']); | |||
expect(response.exitCode).toBe(0); | |||
}); | |||
it('returns error when given invalid inputs', async () => { | |||
vi.spyOn(AdderServiceImpl.prototype, 'addNumbers').mockImplementationOnce(() => { | |||
vi.spyOn(UuidServiceImpl.prototype, 'getUsernameUuid').mockImplementationOnce(() => { | |||
throw new InvalidArgumentTypeError('Invalid input'); | |||
}); | |||
const response = await cli.test().run(['add', '1', '2']); | |||
const response = await cli.test().run(['uuid', 'username']); | |||
expect(response.exitCode).toBe(-1); | |||
}); | |||
it('returns error when given out-of-range inputs', async () => { | |||
vi.spyOn(AdderServiceImpl.prototype, 'addNumbers').mockImplementationOnce(() => { | |||
throw new ArgumentOutOfRangeError('Out of range'); | |||
}); | |||
const response = await cli.test().run(['add', '1', '2']); | |||
expect(response.exitCode).toBe(-2); | |||
}); | |||
it('returns error when an unexpected error occurs', async () => { | |||
vi.spyOn(AdderServiceImpl.prototype, 'addNumbers').mockImplementationOnce(() => { | |||
vi.spyOn(UuidServiceImpl.prototype, 'getUsernameUuid').mockImplementationOnce(() => { | |||
throw new Error('Unexpected error'); | |||
}); | |||
const response = await cli.test().run(['add', '1', '2']); | |||
const response = await cli.test().run(['uuid', 'username']); | |||
expect(response.exitCode).toBe(-3); | |||
}); | |||
it('returns error when given insufficient arguments', async () => { | |||
const response = await cli.test().run(['add', '1']); | |||
const response = await cli.test().run(['uuid']); | |||
expect(response.exitCode).toBe(-1); | |||
}); | |||
@@ -58,10 +49,9 @@ describe('blah', () => { | |||
const response = await cli | |||
.test() | |||
.promptValue({ | |||
a: '1', | |||
b: '2', | |||
username: 'username', | |||
}) | |||
.run(['add', '-i']); | |||
.run(['uuid', '-i']); | |||
expect(response.exitCode).not.toBe(-1); | |||
}); | |||
}); | |||
@@ -1,5 +1,5 @@ | |||
{ | |||
"name": "@modal-sh/core", | |||
"name": "@modal-sh/minecraft-uuid-core", | |||
"version": "0.0.0", | |||
"files": [ | |||
"dist", | |||
@@ -19,7 +19,7 @@ | |||
"pridepack": "2.4.4", | |||
"tslib": "^2.5.0", | |||
"typescript": "^4.9.5", | |||
"vitest": "^0.28.1" | |||
"vitest": "1.3.1" | |||
}, | |||
"scripts": { | |||
"prepublishOnly": "pridepack clean && pridepack build", | |||
@@ -1,10 +1,13 @@ | |||
export interface AddFunctionOptions { | |||
a: number; | |||
b: number; | |||
import { get } from 'https'; | |||
import { createHash } from 'crypto'; | |||
export interface GetUsernameUuidOptions { | |||
username: string; | |||
onlineMode?: boolean; | |||
} | |||
export interface AddFunction { | |||
(options: AddFunctionOptions): number; | |||
export interface GetUsernameUuid { | |||
(options: GetUsernameUuidOptions): Promise<string>; | |||
} | |||
export class InvalidArgumentTypeError extends TypeError { | |||
@@ -14,21 +17,55 @@ export class InvalidArgumentTypeError extends TypeError { | |||
} | |||
} | |||
export class ArgumentOutOfRangeError extends RangeError { | |||
constructor(message: string) { | |||
super(message); | |||
this.name = 'ArgumentOutOfRangeError'; | |||
} | |||
} | |||
const formatUuidBytes = (bytes: Buffer) => { | |||
return [ | |||
bytes.slice(0, 4), | |||
bytes.slice(4, 6), | |||
bytes.slice(6, 8), | |||
bytes.slice(8, 10), | |||
bytes.slice(10) | |||
] | |||
.map((b) => b.toString('hex')) | |||
.join('-'); | |||
}; | |||
export const getUsernameUuid: GetUsernameUuid = async (options: GetUsernameUuidOptions): Promise<string> => { | |||
const { username, onlineMode = false } = options as unknown as Record<string, unknown>; | |||
export const add: AddFunction = (options: AddFunctionOptions): number => { | |||
const { a, b } = options as unknown as Record<string, unknown>; | |||
if (typeof a !== 'number' || typeof b !== 'number') { | |||
throw new InvalidArgumentTypeError('a and b must be numbers'); | |||
if (typeof username !== 'string') { | |||
throw new InvalidArgumentTypeError('Username must be a string'); | |||
} | |||
if (!Number.isFinite(a) || !Number.isFinite(b)) { | |||
throw new ArgumentOutOfRangeError('a and b must be finite numbers'); | |||
if (!onlineMode) { | |||
const md5 = createHash('md5'); | |||
md5.update(Buffer.from(`OfflinePlayer:${username}`, 'utf-8')); | |||
const bytes = md5.digest(); | |||
bytes[6] &= 0x0f; | |||
bytes[6] |= 0x30; | |||
bytes[8] &= 0x3f; | |||
bytes[8] |= 0x80; | |||
return formatUuidBytes(bytes); | |||
} | |||
return a + b; | |||
return new Promise((resolve, reject) => { | |||
get(`https://api.mojang.com/users/profiles/minecraft/${encodeURIComponent(username)}`, res => { | |||
let uuid = ''; | |||
res.on('data', (c) => { | |||
const json = c.toString('utf-8'); | |||
const data = JSON.parse(json); | |||
const bytes = Buffer.from(data.id, 'hex'); | |||
uuid = formatUuidBytes(bytes); | |||
}); | |||
res.on('end', () => { | |||
resolve(uuid); | |||
}); | |||
}) | |||
.on('error', reject); | |||
}); | |||
}; |
@@ -1,16 +1,61 @@ | |||
import { describe, it, expect } from 'vitest'; | |||
import { add } from '../src'; | |||
import {describe, it, expect, vi} from 'vitest'; | |||
import { getUsernameUuid } from '../src'; | |||
import { EventEmitter } from 'events'; | |||
describe('blah', () => { | |||
it('returns result', () => { | |||
expect(add({ a: 1, b: 1 })).toEqual(2); | |||
describe('minecraft-uuid', () => { | |||
it('returns result (default offline mode)', async () => { | |||
vi.mock('crypto', () => ({ | |||
createHash: (algo) => { | |||
return { | |||
update: () => { | |||
// noop | |||
}, | |||
digest: () => Buffer.alloc(16, 0), | |||
}; | |||
}, | |||
})); | |||
const uuid = await getUsernameUuid({ username: 'username' }); | |||
expect(uuid).toEqual('00000000-0000-3000-8000-000000000000'); | |||
}); | |||
it('throws when given invalid argument types', () => { | |||
expect(() => add({ a: '1' as unknown as number, b: 1 })).toThrow(TypeError); | |||
it('returns result (explicit offline mode)', async () => { | |||
vi.mock('crypto', () => ({ | |||
createHash: (algo) => { | |||
return { | |||
update: () => { | |||
// noop | |||
}, | |||
digest: () => Buffer.alloc(16, 0), | |||
}; | |||
}, | |||
})); | |||
const uuid = await getUsernameUuid({ username: 'username', onlineMode: false }); | |||
expect(uuid).toEqual('00000000-0000-3000-8000-000000000000'); | |||
}); | |||
it('throws when given out-of-range arguments', () => { | |||
expect(() => add({ a: Infinity, b: 1 })).toThrow(RangeError); | |||
it('returns result (explicit online mode)', async () => { | |||
vi.mock('https', () => ({ | |||
get: (url, cb) => { | |||
const emitter = new EventEmitter(); | |||
if (typeof cb === 'function') { | |||
(cb as unknown as (...args: unknown[]) => unknown)(emitter); | |||
} | |||
emitter.emit('data', Buffer.from(JSON.stringify({ | |||
id: '82c683b548333d6b8a2606352cd6f327', | |||
name: 'username' | |||
}))); | |||
emitter.emit('end'); | |||
return emitter; | |||
}, | |||
})); | |||
const uuid = await getUsernameUuid({ username: 'username', onlineMode: true }); | |||
expect(uuid).toEqual('82c683b5-4833-3d6b-8a26-06352cd6f327'); | |||
}); | |||
}); |
@@ -1,5 +1,5 @@ | |||
{ | |||
"name": "@modal-sh/web-api", | |||
"name": "@modal-sh/minecraft-uuid-web-api", | |||
"version": "0.0.0", | |||
"files": [ | |||
"dist", | |||
@@ -23,7 +23,7 @@ | |||
"vitest": "^0.28.1" | |||
}, | |||
"dependencies": { | |||
"@modal-sh/core": "workspace:*", | |||
"@modal-sh/minecraft-uuid-core": "workspace:*", | |||
"fastify": "^4.12.0" | |||
}, | |||
"scripts": { | |||
@@ -1,60 +0,0 @@ | |||
import { RouteHandlerMethod } from 'fastify'; | |||
import { | |||
AdderService, | |||
AdderServiceImpl, | |||
ArgumentOutOfRangeError, | |||
InvalidArgumentTypeError, | |||
} from '@/modules/adder/adder.service'; | |||
import { constants } from 'http2'; | |||
export interface AdderController { | |||
addNumbers: RouteHandlerMethod; | |||
subtractNumbers: RouteHandlerMethod; | |||
} | |||
export class AdderControllerImpl implements AdderController { | |||
constructor( | |||
private readonly adderService: AdderService = new AdderServiceImpl(), | |||
) { | |||
// noop | |||
} | |||
readonly addNumbers: RouteHandlerMethod = async (request, reply) => { | |||
const { a, b } = request.body as { a: number; b: number }; | |||
try { | |||
const response = this.adderService.addNumbers({ a, b }); | |||
reply.send(response); | |||
} catch (errorRaw) { | |||
if (errorRaw instanceof InvalidArgumentTypeError) { | |||
request.log.info(errorRaw); | |||
reply.status(constants.HTTP_STATUS_BAD_REQUEST).send(errorRaw.message); | |||
return; | |||
} | |||
if (errorRaw instanceof ArgumentOutOfRangeError) { | |||
reply.status(constants.HTTP_STATUS_BAD_REQUEST).send(errorRaw.message); | |||
return; | |||
} | |||
const error = errorRaw as Error; | |||
reply.status(constants.HTTP_STATUS_INTERNAL_SERVER_ERROR).send(error.message); | |||
} | |||
} | |||
readonly subtractNumbers: RouteHandlerMethod = async (request, reply) => { | |||
const { a, b } = request.body as { a: number; b: number }; | |||
try { | |||
const response = this.adderService.addNumbers({ a, b: -b }); | |||
reply.send(response); | |||
} catch (errorRaw) { | |||
if (errorRaw instanceof InvalidArgumentTypeError) { | |||
reply.status(constants.HTTP_STATUS_BAD_REQUEST).send(errorRaw.message); | |||
return; | |||
} | |||
if (errorRaw instanceof ArgumentOutOfRangeError) { | |||
reply.status(constants.HTTP_STATUS_BAD_REQUEST).send(errorRaw.message); | |||
return; | |||
} | |||
const error = errorRaw as Error; | |||
reply.status(constants.HTTP_STATUS_INTERNAL_SERVER_ERROR).send(error.message); | |||
} | |||
} | |||
} |
@@ -1,21 +0,0 @@ | |||
import { | |||
add, | |||
AddFunctionOptions, | |||
ArgumentOutOfRangeError, | |||
InvalidArgumentTypeError, | |||
} from '@modal-sh/core'; | |||
export interface AdderService { | |||
addNumbers(options: AddFunctionOptions): number; | |||
} | |||
export class AdderServiceImpl implements AdderService { | |||
addNumbers(options: AddFunctionOptions) { | |||
return add(options); | |||
} | |||
} | |||
export { | |||
ArgumentOutOfRangeError, | |||
InvalidArgumentTypeError, | |||
}; |
@@ -1,2 +0,0 @@ | |||
export * from './adder.controller'; | |||
export * from './adder.service'; |
@@ -0,0 +1,2 @@ | |||
export * from './uuid.controller'; | |||
export * from './uuid.service'; |
@@ -0,0 +1,35 @@ | |||
import { RouteHandlerMethod } from 'fastify'; | |||
import { | |||
UuidService, | |||
UuidServiceImpl, | |||
InvalidArgumentTypeError, | |||
} from '@/modules/uuid/uuid.service'; | |||
import { constants } from 'http2'; | |||
export interface UuidController { | |||
getUsernameUuid: RouteHandlerMethod; | |||
} | |||
export class UuidControllerImpl implements UuidController { | |||
constructor( | |||
private readonly uuidService: UuidService = new UuidServiceImpl(), | |||
) { | |||
// noop | |||
} | |||
readonly getUsernameUuid: RouteHandlerMethod = async (request, reply) => { | |||
const { username, onlineMode } = request.body as { username: string; onlineMode?: boolean }; | |||
try { | |||
const response = this.uuidService.getUsernameUuid({ username, onlineMode }); | |||
reply.send(response); | |||
} catch (errorRaw) { | |||
if (errorRaw instanceof InvalidArgumentTypeError) { | |||
request.log.info(errorRaw); | |||
reply.status(constants.HTTP_STATUS_BAD_REQUEST).send(errorRaw.message); | |||
return; | |||
} | |||
const error = errorRaw as Error; | |||
reply.status(constants.HTTP_STATUS_INTERNAL_SERVER_ERROR).send(error.message); | |||
} | |||
} | |||
} |
@@ -0,0 +1,19 @@ | |||
import { | |||
GetUsernameUuidOptions, | |||
getUsernameUuid, | |||
InvalidArgumentTypeError, | |||
} from '@modal-sh/minecraft-uuid-core'; | |||
export interface UuidService { | |||
getUsernameUuid(options: GetUsernameUuidOptions): Promise<string>; | |||
} | |||
export class UuidServiceImpl implements UuidService { | |||
async getUsernameUuid(options: GetUsernameUuidOptions) { | |||
return getUsernameUuid(options); | |||
} | |||
} | |||
export { | |||
InvalidArgumentTypeError, | |||
}; |
@@ -1,36 +1,23 @@ | |||
import { FastifyInstance } from 'fastify'; | |||
import { AdderController, AdderControllerImpl } from '@/modules/adder'; | |||
import { UuidController, UuidControllerImpl } from '@/modules/uuid'; | |||
export const addRoutes = (server: FastifyInstance) => { | |||
const adderController: AdderController = new AdderControllerImpl(); | |||
const uuidController: UuidController = new UuidControllerImpl(); | |||
return server | |||
.route({ | |||
method: 'POST', | |||
url: '/add', | |||
url: '/api/uuid', | |||
schema: { | |||
body: { | |||
type: 'object', | |||
required: ['username'], | |||
properties: { | |||
a: { type: 'number' }, | |||
b: { type: 'number' }, | |||
username: { type: 'string' }, | |||
onlineMode: { type: 'boolean' }, | |||
} | |||
} | |||
}, | |||
handler: adderController.addNumbers, | |||
}) | |||
.route({ | |||
method: 'POST', | |||
url: '/subtract', | |||
schema: { | |||
body: { | |||
type: 'object', | |||
properties: { | |||
a: { type: 'number' }, | |||
b: { type: 'number' }, | |||
} | |||
} | |||
}, | |||
handler: adderController.subtractNumbers, | |||
handler: uuidController.getUsernameUuid, | |||
}); | |||
}; |
@@ -11,14 +11,13 @@ import { constants } from 'http2'; | |||
import { createServer } from '../src/server'; | |||
import { addRoutes } from '../src/routes'; | |||
import { | |||
AdderServiceImpl, | |||
ArgumentOutOfRangeError, | |||
UuidServiceImpl, | |||
InvalidArgumentTypeError, | |||
} from '../src/modules/adder'; | |||
} from '../src/modules/uuid'; | |||
describe('Example', () => { | |||
let server: FastifyInstance; | |||
const body = { a: 1, b: 2 }; | |||
const body = { username: 'username', onlineMode: false }; | |||
beforeAll(() => { | |||
server = createServer(); | |||
@@ -32,7 +31,7 @@ describe('Example', () => { | |||
it('returns result when successful', async () => { | |||
const response = await server | |||
.inject() | |||
.post('/') | |||
.post('/api/uuid') | |||
.body(body) | |||
.headers({ | |||
'Accept': 'application/json', | |||
@@ -41,28 +40,13 @@ describe('Example', () => { | |||
}); | |||
it('returns error when given invalid inputs', async () => { | |||
vi.spyOn(AdderServiceImpl.prototype, 'addNumbers').mockImplementationOnce(() => { | |||
vi.spyOn(UuidServiceImpl.prototype, 'getUsernameUuid').mockImplementationOnce(() => { | |||
throw new InvalidArgumentTypeError('Invalid input'); | |||
}); | |||
const response = await server | |||
.inject() | |||
.post('/') | |||
.body(body) | |||
.headers({ | |||
'Accept': 'application/json', | |||
}); | |||
expect(response.statusCode).toBe(constants.HTTP_STATUS_BAD_REQUEST); | |||
}); | |||
it('returns error when given out-of-range inputs', async () => { | |||
vi.spyOn(AdderServiceImpl.prototype, 'addNumbers').mockImplementationOnce(() => { | |||
throw new ArgumentOutOfRangeError('Out of range'); | |||
}); | |||
const response = await server | |||
.inject() | |||
.post('/') | |||
.post('/api/uuid') | |||
.body(body) | |||
.headers({ | |||
'Accept': 'application/json', | |||
@@ -71,14 +55,14 @@ describe('Example', () => { | |||
}); | |||
it('returns error when an unexpected error occurs', async () => { | |||
vi.spyOn(AdderServiceImpl.prototype, 'addNumbers').mockImplementationOnce(() => { | |||
vi.spyOn(UuidServiceImpl.prototype, 'getUsernameUuid').mockImplementationOnce(() => { | |||
throw new Error('Unexpected error'); | |||
}); | |||
const response = await server | |||
.inject() | |||
.post('/') | |||
.body({ a: 1, b: 2 }) | |||
.post('/api/uuid') | |||
.body(body) | |||
.headers({ | |||
'Accept': 'application/json', | |||
}); | |||