const ServiceBroker = require("../../src/service-broker");

describe("Test RPC", () => {

	let b1 = new ServiceBroker({
		transporter: "Fake",
		logger: false,
		nodeID: "node-1"
	});

	let eventHandler = jest.fn();

	b1.createService({
		name: "greeter",
		actions: {
			hello(ctx) {
				return `Hello ${ctx.params.name}`;
			}
		},

		events: {
			"emitter.**": eventHandler
		}
	});

	let b2 = new ServiceBroker({
		transporter: "Fake",
		logger: false,
		nodeID: "node-2"
	});

	let b2ReplyHandler = jest.fn(ctx => ctx.params);
	b2.createService({
		name: "echo",
		actions: {
			reply: b2ReplyHandler,

			helloProxy(ctx) {
				return ctx.call("greeter.hello", ctx.params).then(res => res + " (proxied)");
			},

			emitter(ctx) {
				ctx.emit("emitter.hello.event", ctx.params);
			},

			slow() {
				return new this.Promise(resolve => {
					setTimeout(() => {
						resolve("OK");
					}, 1000);
				});
			}
		}
	});

	beforeAll(() => Promise.all([b1.start(), b2.start()]));
	afterAll(() => Promise.all([b1.stop(), b2.stop()]));

	it("should call echo.reply on b2", () => {
		return b1.call("echo.reply", { data: 100 }).then(res => {
			expect(res).toEqual({ data: 100 });

			expect(b2ReplyHandler).toHaveBeenCalledTimes(1);
		});
	});

	it("should call double RPC (b1 -> b2 -> b1 -> b2 -> b1) & emit an event to b1", () => {
		return b1.call("echo.helloProxy", { name: "Icebob" }).then(res => {
			expect(res).toEqual("Hello Icebob (proxied)");
		});
	});

	it("should emit & receive an event via transporter", () => {
		return b1.call("echo.emitter", { a: 5 }).then(() => {
			expect(eventHandler).toHaveBeenCalledTimes(1);
			expect(eventHandler).toHaveBeenCalledWith({ a: 5 }, "node-2", "emitter.hello.event", expect.any(b1.ContextFactory));
		});
	});

	it("should return with RequestTimeout", () => {
		return b1.call("echo.slow", null, { timeout: 100 }).catch(err => {
			expect(err.name).toBe("RequestTimeoutError");
			expect(err.data.nodeID).toBe("node-2");
			expect(err.data.action).toBe("echo.slow");
		});
	});

	it("should return with fallbackResponse", () => {
		let fallbackResponse = "MAYBE";
		return b1.call("echo.slow", null, { timeout: 100, fallbackResponse }).then(res => {
			expect(res).toBe("MAYBE");
		});
	});
});

@@ -2241,13 +2241,915 @@
 %7D);%0A%09%7D);
+%0A%0A%09it(%22should have event listener for emitter.some.thing%22, () =%3E %7B%0A%09%09expect(b1.hasEventListener(%22emitter.some.thing%22)).toBe(true);%0A%09%09expect(b2.hasEventListener(%22emitter.some.thing%22)).toBe(true);%0A%0A%09%09let res = b1.getEventListeners(%22emitter.some.thing%22);%0A%09%09expect(res.length).toBe(1);%0A%09%09expect(res%5B0%5D.id).toBe(%22node-1%22);%0A%09%09expect(res%5B0%5D.event.name).toBe(%22emitter.**%22);%0A%0A%09%09res = b2.getEventListeners(%22emitter.some.thing%22);%0A%09%09expect(res.length).toBe(1);%0A%09%09expect(res%5B0%5D.id).toBe(%22node-1%22);%0A%09%09expect(res%5B0%5D.event.name).toBe(%22emitter.**%22);%0A%09%7D);%0A%0A%09it(%22should not have event listener for other.some.thing%22, () =%3E %7B%0A%09%09expect(b1.hasEventListener(%22other.some.thing%22)).toBe(false);%0A%09%09expect(b2.hasEventListener(%22other.some.thing%22)).toBe(false);%0A%0A%09%09let res = b1.getEventListeners(%22other.some.thing%22);%0A%09%09expect(res.length).toBe(0);%0A%0A%09%09res = b2.getEventListeners(%22other.some.thing%22);%0A%09%09expect(res.length).toBe(0);%0A%09%7D);
 %0A%7D);%0A

add tests