Skip to content

Commit

Permalink
fix(di): remove unused DIContext.runInContext and emit methods
Browse files Browse the repository at this point in the history
BREAKING CHANGE: DIContext.runInContext and DIContext.emit methods are removed. Use runInContext and $emit function instead.
  • Loading branch information
Romakita committed Oct 19, 2024
1 parent 04ecad9 commit b9e0493
Show file tree
Hide file tree
Showing 12 changed files with 85 additions and 211 deletions.
133 changes: 7 additions & 126 deletions packages/di/src/node/domain/DIContext.spec.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import {logger} from "../fn/logger.js";
import {DITest} from "../services/DITest.js";
import {bindContext, getAsyncStore} from "../utils/asyncHookContext.js";
import {DIContext} from "./DIContext.js";

describe("DIContext", () => {
beforeEach(() => DITest.create());
beforeEach(() => {
vi.spyOn(logger(), "info").mockReturnValue(undefined);
});
afterEach(() => DITest.reset());
describe("constructor", () => {
it("should create a new Context and skip log", () => {
const logger = {
info: vi.fn()
};
const context = new DIContext({
event: {
response: {},
Expand All @@ -18,9 +19,7 @@ describe("DIContext", () => {
}
},
id: "id",
logger,
maxStackSize: 0,
injector: DITest.injector
maxStackSize: 0
});

expect(context.id).toEqual("id");
Expand All @@ -31,23 +30,17 @@ describe("DIContext", () => {

context.logger.info("test");

expect(logger.info).toHaveBeenCalled();
expect(logger().info).toHaveBeenCalled();

context.destroy();
});
it("should create a new Context and log event", () => {
const logger = {
info: vi.fn()
};

const context = new DIContext({
id: "id",
event: {
response: {},
request: {url: "/"}
},
logger,
injector: DITest.injector,
maxStackSize: 0,
platform: "OTHER"
});
Expand All @@ -63,7 +56,7 @@ describe("DIContext", () => {
context.next();
context.logger.info("test");

expect(logger.info).toHaveBeenCalled();
expect(logger().info).toHaveBeenCalled();
});
});

Expand All @@ -75,11 +68,7 @@ describe("DIContext", () => {
request: {url: "/admin"}
},
id: "id",
logger: {
info: vi.fn()
},
maxStackSize: 0,
injector: {emit: vi.fn()} as any,
ignoreUrlPatterns: ["/admin", /\/admin2/]
});
const resolver = vi.fn().mockReturnValue("test");
Expand All @@ -100,11 +89,7 @@ describe("DIContext", () => {
request: {url: "/admin"}
},
id: "id",
logger: {
info: vi.fn()
},
maxStackSize: 0,
injector: {emit: vi.fn()} as any,
ignoreUrlPatterns: ["/admin", /\/admin2/]
});
const resolver = vi.fn().mockResolvedValue("test");
Expand All @@ -116,108 +101,4 @@ describe("DIContext", () => {
expect(resolver).toHaveBeenCalledTimes(1);
});
});
describe("emit()", () => {
it("should emit event", async () => {
const context = new DIContext({
event: {
response: {},
request: {url: "/admin"}
},
id: "id",
logger: {
info: vi.fn()
},
maxStackSize: 0,
injector: {emit: vi.fn()} as any,
ignoreUrlPatterns: ["/admin", /\/admin2/]
});

await context.emit("event", "test");

expect(context.injector.emit).toHaveBeenCalledWith("event", "test");
});
});
describe("runInContext()", () => {
it("should run handler in a context", async () => {
const context = new DIContext({
event: {
response: {},
request: {url: "/admin"}
},
id: "id",
logger: {
info: vi.fn()
},
maxStackSize: 0,
injector: {
alterAsync: vi.fn().mockImplementation((event, fn, $ctx) => {
return fn;
})
} as any,
ignoreUrlPatterns: ["/admin", /\/admin2/]
});

const stub = vi.fn();

await context.runInContext(stub);

expect(stub).toHaveBeenCalledWith();
expect(context.injector.alterAsync).toHaveBeenCalledWith("$alterRunInContext", stub);
});
it("should run handler in a context + bind", async () => {
const context = new DIContext({
event: {
response: {},
request: {url: "/admin"}
},
id: "id",
logger: {
info: vi.fn()
},
maxStackSize: 0,
injector: {
alterAsync: vi.fn().mockImplementation((event, fn, $ctx) => {
return fn;
})
} as any,
ignoreUrlPatterns: ["/admin", /\/admin2/]
});

const stub = vi.fn();

await context.runInContext(() => {
bindContext(stub)();
expect(getAsyncStore().getStore()).toEqual({current: context});
});

expect(stub).toHaveBeenCalledWith();
expect(context.injector.alterAsync).toHaveBeenCalledWith("$alterRunInContext", expect.any(Function));
});
it("should run handler in a context and fallback to next", async () => {
const context = new DIContext({
event: {
response: {},
request: {url: "/admin"}
},
id: "id",
logger: {
info: vi.fn()
},
maxStackSize: 0,
injector: {
alterAsync: vi.fn().mockImplementation((event, fn, $ctx) => {
return null;
})
} as any,
ignoreUrlPatterns: ["/admin", /\/admin2/]
});

const stub = vi.fn();

await context.runInContext(stub);

expect(stub).toHaveBeenCalledWith();
expect(context.injector.alterAsync).toHaveBeenCalledWith("$alterRunInContext", stub);
});
});
});
27 changes: 16 additions & 11 deletions packages/di/src/node/domain/DIContext.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import {InjectorService, LocalsContainer} from "../../common/index.js";
import {injector, InjectorService, LocalsContainer} from "../../common/index.js";
import {logger} from "../fn/logger.js";
import {runInContext} from "../utils/asyncHookContext.js";
import {ContextLogger, ContextLoggerOptions} from "./ContextLogger.js";

export interface DIContextOptions extends Omit<ContextLoggerOptions, "dateStart"> {
id: string;
injector: InjectorService;
logger: any;
platform?: string;
}

export class DIContext {
[x: string]: any;

readonly PLATFORM: string = "DI";
#container?: LocalsContainer;
#cache?: Map<any, any>;
Expand All @@ -24,7 +24,12 @@ export class DIContext {
* Logger attached to the context request.
*/
get logger() {
this.#logger = this.#logger || new ContextLogger(this.opts);
this.#logger =
this.#logger ||
new ContextLogger({
...this.opts,
logger: logger()
});
return this.#logger;
}

Expand Down Expand Up @@ -61,7 +66,7 @@ export class DIContext {
}

get injector(): InjectorService {
return this.opts.injector!;
return injector();
}

get env() {
Expand All @@ -79,13 +84,13 @@ export class DIContext {
return Promise.all([this.#container?.destroy(), this.#logger?.flush(true)]);
}

emit(eventName: string, ...args: any[]) {
return this.injector?.emit(eventName, ...args);
}
// emit(eventName: string, ...args: any[]) {
// return $emit(eventName, ...args);
// }

runInContext<Result = unknown>(next: (...args: unknown[]) => Result): Promise<Result> {
return runInContext<Result>(this, next);
}
// runInContext<Result = unknown>(next: (...args: unknown[]) => Result): Promise<Result> {
// return runInContext<Result>(this, next);
// }

cache<Value = any>(key: string, cb: () => Value): Value {
if (!this.has(key)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,52 +1,33 @@
import {OptimisticLockError} from "@mikro-orm/core";
import {Logger} from "@tsed/logger";
import {PlatformContext} from "@tsed/platform-http";
import {PlatformTest} from "@tsed/platform-http/testing";
import {instance, mock, objectContaining, reset, spy, verify} from "ts-mockito";

import {OptimisticLockErrorFilter} from "./OptimisticLockErrorFilter.js";

describe("OptimisticLockErrorFilter", () => {
const mockedLogger: Logger = mock<Logger>();
let optimisticLockErrorFilter!: OptimisticLockErrorFilter;

beforeEach(() => {
optimisticLockErrorFilter = new OptimisticLockErrorFilter();

return PlatformTest.create();
});

afterEach(() => {
reset(mockedLogger);

return PlatformTest.reset();
});
beforeEach(() => PlatformTest.create());
afterEach(() => PlatformTest.reset());

describe("catch", () => {
it("should set HTTP status to 409", () => {
it("should set HTTP status to 409", async () => {
const optimisticLockErrorFilter = await PlatformTest.invoke(OptimisticLockErrorFilter);

// arrange
const exception = OptimisticLockError.lockFailed("entity");
const response = PlatformTest.createResponse();
const request = PlatformTest.createRequest({
url: "/admin"
});
const context = new PlatformContext({
event: {
response,
request
},
id: "id",
logger: instance(mockedLogger),
maxStackSize: 0,
injector: PlatformTest.injector
});
const spiedResponse = spy(response);
const context = PlatformTest.createRequestContext();

vi.spyOn(context.logger, "error").mockReturnThis();

// act
optimisticLockErrorFilter.catch(exception, context);

verify(mockedLogger.error(objectContaining({exception}))).once();
verify(spiedResponse.status(409)).once();
expect(context.logger.error).toHaveBeenCalledWith({
event: "MIKRO_ORM_OPTIMISTIC_LOCK_ERROR",
error_name: exception.name,
error_message: exception.message,
stack: exception.stack
});
expect(context.response.getBody()).toEqual("Update refused. The resource has changed on the server. Please try again later");
expect(context.response.statusCode).toEqual(409);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ export class OptimisticLockErrorFilter implements ExceptionFilterMethods<Optimis
const {response, logger} = ctx;

logger.error({
exception
event: "MIKRO_ORM_OPTIMISTIC_LOCK_ERROR",
error_name: exception.name,
error_message: exception.message,
stack: exception.stack
});

response.status(409).body(`Update refused. The resource has changed on the server. Please try again later`);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {DIContext, DIContextOptions} from "@tsed/di";
import {$emit, DIContext, DIContextOptions} from "@tsed/di";
import {PlatformHandlerMetadata} from "@tsed/platform-router";
import {EndpointMetadata} from "@tsed/schema";
import {IncomingMessage, ServerResponse} from "http";
Expand Down Expand Up @@ -81,11 +81,11 @@ export class PlatformContext<
}

start() {
return this.emit("$onRequest", this);
return $emit("$onRequest", this);
}

async finish() {
await Promise.all([this.emit("$onResponse", this), this.destroy()]);
await Promise.all([$emit("$onResponse", this), this.destroy()]);
this.#isFinished = true;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Injectable} from "@tsed/di";
import {Injectable, runInContext} from "@tsed/di";
import {PlatformHandlerMetadata, PlatformHandlerType} from "@tsed/platform-router";
import {EndpointMetadata, Get, View} from "@tsed/schema";

Expand Down Expand Up @@ -86,7 +86,7 @@ describe("PlatformHandler", () => {

expect(result).toBeInstanceOf(Function);

await $ctx.runInContext(() => result($ctx));
await runInContext($ctx, () => result($ctx));

expect($ctx.data).toEqual("hello");
expect(testService.use).toHaveBeenCalledWith($ctx);
Expand Down
Loading

0 comments on commit b9e0493

Please sign in to comment.