diff --git a/docs/modules/nats.md b/docs/modules/nats.md index 7f8bfb497..c17f279c4 100644 --- a/docs/modules/nats.md +++ b/docs/modules/nats.md @@ -21,3 +21,7 @@ npm install @testcontainers/nats --save-dev [Set credentials:](../../packages/modules/nats/src/nats-container.test.ts) inside_block:credentials + + +[Enable JetStream:](../../packages/modules/nats/src/nats-container.test.ts) inside_block:JetStream + diff --git a/packages/modules/nats/src/nats-container.test.ts b/packages/modules/nats/src/nats-container.test.ts index 927eb24aa..9d65ceba3 100644 --- a/packages/modules/nats/src/nats-container.test.ts +++ b/packages/modules/nats/src/nats-container.test.ts @@ -67,6 +67,43 @@ describe("NatsContainer", () => { }); // } + // JetStream { + it("should start with JetStream ", async () => { + // enable JS + const container = await new NatsContainer().withJS().start(); + + const nc = await connect(container.getConnectionOptions()); + + // just take manager for check js + await nc.jetstream().jetstreamManager() + + // close the connection + await nc.close(); + // check if the close was OK + const err = await nc.closed(); + expect(err).toBe(undefined); + + await container.stop(); + }); + + it("should fail without JetStream ", async () => { + const container = await new NatsContainer().start(); + + const nc = await connect(container.getConnectionOptions()); + + // just take manager for check js + await expect(nc.jetstream().jetstreamManager()).rejects.toThrowError('503') + + // close the connection + await nc.close(); + // check if the close was OK + const err = await nc.closed(); + expect(err).toBe(undefined); + + await container.stop(); + }); + // } + it("should immediately end when started with version argument ", async () => { // for the complete list of available arguments see: // See Command Line Options section inside [NATS docker image documentation](https://hub.docker.com/_/nats) diff --git a/packages/modules/nats/src/nats-container.ts b/packages/modules/nats/src/nats-container.ts index bc93eaa42..f979f67bd 100755 --- a/packages/modules/nats/src/nats-container.ts +++ b/packages/modules/nats/src/nats-container.ts @@ -7,25 +7,14 @@ const HTTP_MANAGEMENT_PORT = 8222; const USER_ARGUMENT_KEY = "--user"; const PASS_ARGUMENT_KEY = "--pass"; -function buildCmdsFromArgs(args: { [p: string]: string }): string[] { - const result: string[] = []; - result.push("nats-server"); - - for (const argsKey in args) { - result.push(argsKey); - result.push(args[argsKey]); - } - return result; -} - export class NatsContainer extends GenericContainer { - private args: { [name: string]: string } = {}; + private args = new Set() + private values = new Map() constructor(image = "nats:2.8.4-alpine") { super(image); - - this.args[USER_ARGUMENT_KEY] = "test"; - this.args[PASS_ARGUMENT_KEY] = "test"; + this.withUsername('test') + this.withPass('test') this.withExposedPorts(CLIENT_PORT, ROUTING_PORT_FOR_CLUSTERING, HTTP_MANAGEMENT_PORT) .withWaitStrategy(Wait.forLogMessage(/.*Server is ready.*/)) @@ -33,18 +22,33 @@ export class NatsContainer extends GenericContainer { } public withUsername(user: string): this { - this.args[USER_ARGUMENT_KEY] = user; + this.withArg(USER_ARGUMENT_KEY, user) + return this; + } + + /** + * Enable JetStream + * @returns {this} + */ + public withJS(): this { + this.withArg('-js') return this; } public withPass(pass: string): this { - this.args[PASS_ARGUMENT_KEY] = pass; + this.withArg(PASS_ARGUMENT_KEY, pass) return this; } - public withArg(name: string, value: string) { + public withArg(name: string, value: string): this + public withArg(name: string): this + public withArg(...args: [string, string] | [string]): this { + let [name, value] = args name = NatsContainer.ensureDashInFrontOfArgumentName(name); - this.args[name] = value; + this.args.add(name) + if (args.length === 2) { + this.values.set(name, value!) + } return this; } @@ -61,16 +65,27 @@ export class NatsContainer extends GenericContainer { } public override async start(): Promise { - this.withCommand(buildCmdsFromArgs(this.args)); + this.withCommand(this.getNormalizedCommand()); return new StartedNatsContainer(await super.start(), this.getUser(), this.getPass()); } private getUser(): string { - return this.args[USER_ARGUMENT_KEY]; + return this.values.get(USER_ARGUMENT_KEY)!; } private getPass(): string { - return this.args[PASS_ARGUMENT_KEY]; + return this.values.get(PASS_ARGUMENT_KEY)!; + } + + private getNormalizedCommand(): string[] { + const result: string[] = ['nats-server'] + for (const arg of this.args) { + result.push(arg) + if (this.values.has(arg)) { + result.push(this.values.get(arg)!) + } + } + return result } }