Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,48 +13,54 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

- Added explicit check for when both `genericMetadata` and `methodMetadata` are `undefined` in the `getControllerMethodMetadata` function, preventing potential errors when no metadata is available.

## [6.5.0]

### Added

### Changed

- Updated `BaseMiddleware.handler` to allow async handlers.
- Updated `Middleware` to allow include any `ServiceIdentifier`.
- Updated `JsonContent` with no generic.

### Fixed

- Updated `BaseController.ok` to no longer return `text/plain` responses when non string content is passed.

## [6.4.10]

### Fixed
- Fixed `Controller` without wrong constraints (#417).

- Fixed `Controller` without wrong constraints (#417).

## [6.4.9]

### Fixed
- Fixed wrong emited typescript delclaration files (#1668).

- Fixed wrong emited typescript delclaration files (#1668).

## [6.4.8]

### Fixed

- Fixed can't set headers after they are sent (#255 / #412).
- Fixed can't set headers after they are sent (#255 / #412).

## [6.4.7]

### Fixed

- Updated `inversify` and `express` dependencies to be peer dependnecies as stated in the docs.
- Updated `inversify` and `express` dependencies to be peer dependnecies as stated in the docs.

## [6.4.4]

### Added

### Changed

- Update dependencies (`minimist`, `json5`, `@babel/traverse`, `tough-cookie`, `ansi-regex`, `cookiejar`, `express`, `decode-uri-component`).
- Update dependencies (`minimist`, `json5`, `@babel/traverse`, `tough-cookie`, `ansi-regex`, `cookiejar`, `express`, `decode-uri-component`).

### Fixed

- Change JsonContent to return object rather than string (#379 / #378).
- Change JsonContent to return object rather than string (#379 / #378).
24 changes: 24 additions & 0 deletions src/test/debug.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,28 @@ describe('Debug utils', () => {
expect(routeInfo[0]?.endpoints[1]?.route).toBe('POST /api/order/');
expect(routeInfo[0]?.endpoints[1]?.args).toBeUndefined();
});

it('should handle controllers without methods', () => {
const container: Container = new Container();

@controller('/api/empty')
class EmptyController extends BaseHttpController {
// empty Controller
}

// eslint-disable-next-line @typescript-eslint/typedef
const TYPES = {
EmptyController: EmptyController.name,
};

const server: InversifyExpressServer = new InversifyExpressServer(
container,
);
server.build();

const routeInfo: RouteInfo[] = getRouteInfo(container);

expect(routeInfo[0]?.controller).toBe(TYPES.EmptyController);
expect(routeInfo[0]?.endpoints).toEqual([]);
});
});
112 changes: 112 additions & 0 deletions src/test/utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/* eslint-disable @typescript-eslint/typedef */
import { describe, expect, it } from '@jest/globals';

import { METADATA_KEY } from '../constants';
import { getControllerMethodMetadata } from '../utils';

describe('Utils', () => {
describe('getControllerMethodMetadata', () => {
it('should return an empty array when controller has no methods', () => {
class EmptyController {}

const result = getControllerMethodMetadata(EmptyController);

expect(result).toEqual([]);
});

it('should return metadata from controller own methods', () => {
class TestController {}
const methodMetadata = [
{
key: 'get',
method: 'testMethod',
middleware: [],
path: '/test',
target: TestController,
},
];

Reflect.defineMetadata(
METADATA_KEY.controllerMethod,
methodMetadata,
TestController,
);

const result = getControllerMethodMetadata(TestController);

expect(result).toEqual(methodMetadata);
});

it('should return metadata from inherited methods', () => {
class BaseController {}
class ChildController extends BaseController {}

const genericMetadata = [
{
key: 'get',
method: 'baseMethod',
middleware: [],
path: '/base',
target: BaseController,
},
];

Reflect.defineMetadata(
METADATA_KEY.controllerMethod,
genericMetadata,
BaseController,
);

const result = getControllerMethodMetadata(ChildController);

expect(result).toEqual(genericMetadata);
});

it('should concatenate own and inherited metadata', () => {
class BaseController {}
class ChildController extends BaseController {}

const ownMetadata = [
{
key: 'post',
method: 'childMethod',
middleware: [],
path: '/child',
target: ChildController,
},
];

const genericMetadata = [
{
key: 'get',
method: 'baseMethod',
middleware: [],
path: '/base',
target: BaseController,
},
];

Reflect.defineMetadata(
METADATA_KEY.controllerMethod,
ownMetadata,
ChildController,
);

Reflect.defineMetadata(
METADATA_KEY.controllerMethod,
genericMetadata,
BaseController,
);

const result = getControllerMethodMetadata(ChildController);

expect(result).toEqual([...ownMetadata, ...genericMetadata]);
});

it('should handle undefined metadata correctly', () => {
class TestController {}
const result = getControllerMethodMetadata(TestController);
expect(result).toEqual([]);
});
});
});
4 changes: 4 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ export function getControllerMethodMetadata(
Reflect.getPrototypeOf(constructor) as NewableFunction,
) as ControllerMethodMetadata[];

// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (genericMetadata === undefined && methodMetadata === undefined) {
return [];
}
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
if (genericMetadata !== undefined && methodMetadata !== undefined) {
return methodMetadata.concat(genericMetadata);
Expand Down