describe("$onInit()", () => {
    before(
      inject([TypeORMModule, ServerSettingsService], (service: TypeORMModule, settings: ServerSettingsService) => {
        this.service = service;
        settings.set("typeorm", {
          db1: {
            config: "config"
          }
        });

        this.createConnectionStub = Sinon.stub(this.service.typeORMService, "createConnection").resolves("connection" as any);

        return (this.result = this.service.$onInit());
      })
    );

    after(
      inject([ServerSettingsService], (settings: ServerSettingsService) => {
        settings.set("typeorm", {});
        this.createConnectionStub.restore();
        TestContext.reset();
      })
    );

    it("should call the connect method", () => {
      this.createConnectionStub.should.have.been.calledWithExactly("db1", {config: "config"});
    });

    it("should return a promise", () => {
      this.result.should.eventually.deep.eq(["connection"]);
    });
  });
describe("ParseService :", () => {
  it("should clone object", () => {
    const source = {};

    expect(ParseService.clone(source)).not.to.be.equal(source);
  });

  it("should not clone object", inject([ParseService], (parserService: ParseService) => {
    const source = {test: {}};

    expect(parserService.eval(undefined!, source, false)).to.equal(source);
    expect(parserService.eval("test", source, false)).to.equal(source.test);
  }));

  it("should eval expression with a scope and return value", inject([ParseService], (parserService: ParseService) => {
    expect(
      parserService.eval(undefined!, {
        test: "yes"
      }).test
    ).to.equal("yes");

    expect(parserService.eval(undefined!, "test")).to.equal("test");
  }));

  it("should eval expression with a scope and return value", inject([ParseService], (parserService: ParseService) => {
    expect(
      parserService.eval("test", {
        test: "yes"
      })
    ).to.equal("yes");
  }));

  it("should eval expression with a scope and return value", inject([ParseService], (parserService: ParseService) => {
    expect(
      parserService.eval("test.foo", {
        test: "yes"
      })
    ).to.equal(undefined);
  }));

  it("should eval expression with a scope and return a new object", inject([ParseService], (parserService: ParseService) => {
    const scope = {
      test: {
        foo: "yes"
      }
    };

    const value = parserService.eval("test", scope);

    expect(value.foo).to.equal("yes");

    value.foo = "test";

    expect(value.foo).to.not.equal(scope.test.foo); // New instance
  }));
});
    describe("middleware error", () => {
      class Test {
      }

      before(
        inject([InjectorService], (injector: InjectorService) => {
          Sinon.stub(injector as any, "getProvider");
        })
      );
      after(inject([InjectorService], (injector: InjectorService) => {
        // @ts-ignore
        injector.getProvider.restore();
      }));

      it("should call build handler from metadata", inject([InjectorService], async (injector: InjectorService) => {
        // GIVEN
        const instance = new Test();
        const provider = {
          store: {
            get: Sinon.stub()
          }
        };

        Store.from(Test).set("socketIO", {
          type: ProviderType.MIDDLEWARE,
          error: true,
          handlers: {
            use: "use"
          }
        });

        // @ts-ignore
        injector.getProvider.returns({
          instance,
          type: ProviderType.MIDDLEWARE
        });

        const scope = {scope: "scope", args: undefined};
        const error = new Error("test");
        const builder: any = new SocketHandlersBuilder(provider as any, {} as any, injector);
        Sinon.stub(builder, "invoke").returns({result: "result"});

        // WHEN
        await builder.bindMiddleware({target: "target"}, scope, Promise.reject(error));

        // THEN
        injector.getProvider.should.have.been.calledWithExactly({target: "target"});
        builder.invoke.should.have.been.calledWithExactly(instance, "use", {error, ...scope});
      }));
    });
describe("RouteService", () => {
  it("should inject RouteService and return routes", inject([RouteService], (routeService: RouteService) => {
    const routes = routeService.getAll();

    expect(routes).to.be.an("array");
  }));

  it("should inject RouteService and print routes", inject([InjectorService, RouteService], (injector: InjectorService, routeService: RouteService) => {
    (injector.logger.info as any).resetHistory();
    // tslint:disable-next-line: no-unused-variable
    routeService.printRoutes();

    injector.logger.info.should.have.been.calledWithExactly(Sinon.match.string);
  }));
});
  describe("when error", () => {
    before(
      inject([AcceptMimesMiddleware], (middleware: AcceptMimesMiddleware) => {
        this.middleware = middleware;

        const acceptStub = Sinon.stub();
        acceptStub.withArgs("application/xml").returns(false);
        acceptStub.withArgs("application/json").returns(false);

        this.request = {
          accepts: acceptStub
        };
        this.endpoint = {
          get: () => {
            return ["application/json", "application/xml"];
          }
        };

        try {
          this.result = this.middleware.use(this.endpoint, this.request);
        } catch (er) {
          this.error = er;
        }
      })
    );

    it("should call request.accepts methods", () => {
      this.request.accepts.should.have.been.calledWithExactly("application/json").and.calledWithExactly("application/xml");
    });

    it("shouldn't emit error", () => {
      expect(this.error.message).to.equal("You must accept content-type application/json, application/xml");
    });
  });
    describe("when didn't use converter", () => {
      before(
        inject([InjectorService], (injector: InjectorService) => {
          this.pipeStub = Sinon.stub(FilterBuilder as any, "pipe");
          this.pipeStub.returns("filter2");

          this.injectorStub = Sinon.stub(injector, "get");
          this.injectorStub.returns({
            deserialize: () => {
            }
          });

          this.result = (new FilterBuilder(injector) as any).appendConverterFilter("filter", {
            useValidation: false,
            type: "type",
            collectionType: "collection"
          });
        })
      );
      after(() => {
        this.injectorStub.restore();
        this.pipeStub.restore();
      });
      it("should not have been called pipe method", () => {
        return this.pipeStub.should.not.be.called;
      });
      it("shouldn't have called injector.get method", () => {
        return this.injectorStub.should.not.be.called;
      });
      it("should return a filter wrapped", () => {
        expect(this.result).to.eq("filter");
      });
    });
describe("GlobalAcceptMimesMiddleware", () => {
  before(
    inject([], () => {
      const settings = new ServerSettingsService();
      settings.acceptMimes = ["application/json"];

      this.middleware = new GlobalAcceptMimesMiddleware(settings);
      this.request = new FakeRequest();
    })
  );

  describe("accept", () => {
    before(() => {
      this.request.mime = "application/json";
    });
    it("should return nothing", () => {
      expect(this.middleware.use(this.request)).to.eq(undefined);
    });
  });

  describe("not accept", () => {
    before(() => {
      this.request.mime = "text/html";
    });

    it("should throws NotAcceptable", () => {
      assert.throws(() => {
        this.middleware.use(this.request);
      }, "You must accept content-type application/json");
    });
  });
});
      describe("when required but not empty", () => {
        before(
          inject([InjectorService], (injector: InjectorService) => {
            this.pipeStub = Sinon.stub(FilterBuilder as any, "pipe");
            this.pipeStub.returns("filter2");
            this.isRequiredStub = Sinon.stub().returns(false);

            this.result = (new FilterBuilder(injector) as any).appendRequiredFilter("filter", {
              required: true,
              name: "name",
              expression: "expression",
              isRequired: this.isRequiredStub
            });
            this.result2 = this.pipeStub.getCall(0).args[1]("value");
          })
        );
        after(() => {
          this.pipeStub.restore();
        });
        it("should call pipe method", () => {
          this.pipeStub.should.be.calledWithExactly("filter", Sinon.match.any);
        });
        it("should return a filter wrapped", () => {
          expect(this.result).to.eq("filter2");
        });
        it("should called isRequiredStub", () => {
          this.isRequiredStub.should.calledWithExactly("value");
        });
        it("should return a value", () => {
          expect(this.result2).to.eq("value");
        });
      });
describe("SymbolConverter", () => {
  before(
    inject([ConverterService], (converterService: ConverterService) => {
      this.symbolConverter = converterService.getConverter(Symbol);
    })
  );
  after(TestContext.reset);

  it("should do something", () => {
    expect(!!this.symbolConverter).to.be.true;
  });

  describe("deserialize()", () => {
    it("should deserialize data as symbol when a string is given", () => {
      expect(this.symbolConverter.deserialize("testSymbol")).to.be.a("symbol");
    });
  });

  describe("serialize()", () => {
    before(() => {
      this.symbolTest = this.symbolConverter.serialize(Symbol("testSymbol2"));
    });

    it("should serialize data to a string", () => {
      expect(this.symbolTest).to.be.a("string");
    });
    it("should serialize data to a string that equals to testSymbol2", () => {
      expect(this.symbolTest).to.be.equal("testSymbol2");
    });
  });
});
  describe("via InjectorService to mock other service", () => {
    before(inject([ControllerService], (controllerService: ControllerService) => {

      this.calendarsService = {
        find: Sinon.stub().returns(Promise.resolve({id: "1"}))
      };

      const locals = new Map<any, any>();
      locals.set(CalendarsService, this.calendarsService);

      this.CalendarsCtrl = controllerService.invoke<CalendarsCtrl>(CalendarsCtrl, locals);
      this.result = this.CalendarsCtrl.get("1");
      return this.result;
    }));

    it("should get the service from InjectorService", () => {
      expect(this.CalendarsCtrl).to.be.an.instanceof(CalendarsCtrl);
    });

    it("should have a fake memoryStorage", () => {
      expect(this.CalendarsCtrl.calendarsService).to.equal(this.calendarsService);
    });

    it("should have been called the CalendarService.find() method", () => {
      this.calendarsService.find.should.be.calledWithExactly("1");
    });

    it("should return the calendar", () => {
      return this.result.should.eventually.deep.equal({id: "1"});
    });
  });