Improve tests a little bit
This commit is contained in:
		@@ -54,9 +54,7 @@ export class ListenerRss extends EventEmitter {
 | 
			
		||||
   * @return return a promise with the received data
 | 
			
		||||
   */
 | 
			
		||||
  fetchRSS(): Promise<Parser.Output<any>> {
 | 
			
		||||
    return this.parser.parseURL(this.address).catch((err) => {
 | 
			
		||||
      throw new Error("bad address or no access : " + err);
 | 
			
		||||
    });
 | 
			
		||||
    return this.parser.parseURL(this.address);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
@@ -69,7 +67,7 @@ export class ListenerRss extends EventEmitter {
 | 
			
		||||
    const fun: () => void = () => {
 | 
			
		||||
      this.fetchRSS()
 | 
			
		||||
        .then((obj: { [key: string]: any }) => this.emit("update", obj))
 | 
			
		||||
        .catch((err) => this.emit("update_err", err));
 | 
			
		||||
        .catch((err) => this.emit("error", err));
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    (async () => {
 | 
			
		||||
 
 | 
			
		||||
@@ -8,12 +8,12 @@ import {
 | 
			
		||||
} from "./../src/index";
 | 
			
		||||
 | 
			
		||||
// Unit test
 | 
			
		||||
import assert from "assert";
 | 
			
		||||
import * as chai from "chai";
 | 
			
		||||
import * as sinon from "ts-sinon";
 | 
			
		||||
import sinon from "ts-sinon";
 | 
			
		||||
import sinonChai from "sinon-chai";
 | 
			
		||||
import { ImportMock, InPlaceMockManager } from "ts-mock-imports";
 | 
			
		||||
 | 
			
		||||
const sinonChai = require("sinon-chai");
 | 
			
		||||
 | 
			
		||||
chai.use(sinonChai);
 | 
			
		||||
 | 
			
		||||
const expect = chai.expect;
 | 
			
		||||
@@ -29,9 +29,7 @@ describe("test class RSS: jsonfile", function () {
 | 
			
		||||
    },
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const mockedRSSOutput: Parser.Output<{
 | 
			
		||||
    "media:group": { [key: string]: string | [any] };
 | 
			
		||||
  }> = {
 | 
			
		||||
  const mockedRSSOutput: Parser.Output<any> = {
 | 
			
		||||
    items: [
 | 
			
		||||
      {
 | 
			
		||||
        title: "my title 00",
 | 
			
		||||
@@ -70,8 +68,8 @@ describe("test class RSS: jsonfile", function () {
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  describe("Building Ytb listener", function () {
 | 
			
		||||
    it("The build without issues (infosListener parameters)", function () {
 | 
			
		||||
      let myListener = new Listeners(infosListener);
 | 
			
		||||
    it("builds without issues (infosListener parameters)", function () {
 | 
			
		||||
      const myListener = new Listeners(infosListener);
 | 
			
		||||
 | 
			
		||||
      // assertions
 | 
			
		||||
      // myListener data
 | 
			
		||||
@@ -90,8 +88,9 @@ describe("test class RSS: jsonfile", function () {
 | 
			
		||||
          item: ["media:group", "media:group"],
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    it("The build without issues (raw infos : 4 params)", function () {
 | 
			
		||||
      let myListener = new Listeners({
 | 
			
		||||
 | 
			
		||||
    it("builds without issues (raw infos : 4 params)", function () {
 | 
			
		||||
      const myListener = new Listeners({
 | 
			
		||||
        name: "my-test-service",
 | 
			
		||||
        address: "fake.rss.service",
 | 
			
		||||
        timeloop: 15,
 | 
			
		||||
@@ -118,8 +117,9 @@ describe("test class RSS: jsonfile", function () {
 | 
			
		||||
          item: ["media:group", "media:group"],
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    it("The build without issues (raw infos : just 2 params)", function () {
 | 
			
		||||
      let myListener = new Listeners({
 | 
			
		||||
 | 
			
		||||
    it("builds without issues (raw infos : just 2 params)", function () {
 | 
			
		||||
      const myListener = new Listeners({
 | 
			
		||||
        name: "my-test-service",
 | 
			
		||||
        address: "fake.rss.service",
 | 
			
		||||
      });
 | 
			
		||||
@@ -139,8 +139,9 @@ describe("test class RSS: jsonfile", function () {
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
  it("The build without issues (raw infos : just 3 params (no custom fields))", function () {
 | 
			
		||||
    let myListener = new Listeners({
 | 
			
		||||
 | 
			
		||||
  it("builds without issues (raw infos: just 3 params (no custom fields))", function () {
 | 
			
		||||
    const myListener = new Listeners({
 | 
			
		||||
      name: "my-test-service",
 | 
			
		||||
      address: "fake.rss.service",
 | 
			
		||||
      timeloop: 15,
 | 
			
		||||
@@ -160,8 +161,9 @@ describe("test class RSS: jsonfile", function () {
 | 
			
		||||
        item: [],
 | 
			
		||||
      });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it("The build without issues (raw infos : just 3 params (no timeloop))", function () {
 | 
			
		||||
    let myListener = new Listeners({
 | 
			
		||||
    const myListener = new Listeners({
 | 
			
		||||
      name: "my-test-service",
 | 
			
		||||
      address: "fake.rss.service",
 | 
			
		||||
      customfields: {
 | 
			
		||||
@@ -188,44 +190,36 @@ describe("test class RSS: jsonfile", function () {
 | 
			
		||||
      });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe("fetch some data", function () {
 | 
			
		||||
    it("fetch without issues", function () {
 | 
			
		||||
  describe("data fetching", function () {
 | 
			
		||||
    it("fetches without issues", async function () {
 | 
			
		||||
      // given
 | 
			
		||||
      const mockManager: InPlaceMockManager<Parser> = ImportMock.mockClassInPlace<Parser>(
 | 
			
		||||
        Parser
 | 
			
		||||
      );
 | 
			
		||||
      let stubTest = mockManager.mock("parseURL");
 | 
			
		||||
      stubTest.withArgs(infosListener.address).resolves(mockedRSSOutput);
 | 
			
		||||
      stubTest
 | 
			
		||||
        .withArgs("bad.rss.service")
 | 
			
		||||
        .rejects(new Error("connect ECONNREFUSED 127.0.0.1:80"));
 | 
			
		||||
      const stubParser = mockManager.mock("parseURL");
 | 
			
		||||
      stubParser.resolves(mockedRSSOutput);
 | 
			
		||||
 | 
			
		||||
      const myListener = new Listeners(infosListener);
 | 
			
		||||
 | 
			
		||||
      // fetch
 | 
			
		||||
      let res = myListener.fetchRSS();
 | 
			
		||||
      // when
 | 
			
		||||
      const res = await myListener.fetchRSS();
 | 
			
		||||
 | 
			
		||||
      //assertion
 | 
			
		||||
      // calls
 | 
			
		||||
      return res
 | 
			
		||||
        .then((obj: any) => {
 | 
			
		||||
          expect(obj).to.be.eql(mockedRSSOutput);
 | 
			
		||||
        })
 | 
			
		||||
        .catch((err) => {
 | 
			
		||||
          expect(err).to.be.undefined;
 | 
			
		||||
        });
 | 
			
		||||
      // then
 | 
			
		||||
      expect(stubParser).to.have.been.calledOnce;
 | 
			
		||||
      expect(stubParser).to.have.been.calledWith(infosListener.address);
 | 
			
		||||
      expect(res).to.be.eql(mockedRSSOutput);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it("fetch with bad address", function () {
 | 
			
		||||
    it("rejects when fetching fails", async function () {
 | 
			
		||||
      // given
 | 
			
		||||
      const mockManager: InPlaceMockManager<Parser> = ImportMock.mockClassInPlace<Parser>(
 | 
			
		||||
        Parser
 | 
			
		||||
      );
 | 
			
		||||
      let stubParser = mockManager.mock("parseURL");
 | 
			
		||||
      stubParser.withArgs(infosListener.address).resolves(mockedRSSOutput);
 | 
			
		||||
      stubParser
 | 
			
		||||
        .withArgs("bad.rss.service")
 | 
			
		||||
        .rejects(new Error("connect ECONNREFUSED 127.0.0.1:80"));
 | 
			
		||||
      const stubParser = mockManager.mock("parseURL");
 | 
			
		||||
      const err = new Error("connect ECONNREFUSED 127.0.0.1:80");
 | 
			
		||||
      stubParser.rejects(err);
 | 
			
		||||
 | 
			
		||||
      let myListener = new Listeners({
 | 
			
		||||
      const myListener = new Listeners({
 | 
			
		||||
        name: "my-test-service",
 | 
			
		||||
        address: "bad.rss.service",
 | 
			
		||||
        customfields: {
 | 
			
		||||
@@ -233,98 +227,120 @@ describe("test class RSS: jsonfile", function () {
 | 
			
		||||
          icon: ["media:group", "media:thumbnail"],
 | 
			
		||||
        },
 | 
			
		||||
      });
 | 
			
		||||
      // fetch
 | 
			
		||||
      let res = myListener.fetchRSS();
 | 
			
		||||
 | 
			
		||||
      //assertion
 | 
			
		||||
      // calls
 | 
			
		||||
      expect(stubParser).to.have.been.calledOnce;
 | 
			
		||||
      expect(stubParser).to.have.been.calledWith("bad.rss.service");
 | 
			
		||||
      // Promise
 | 
			
		||||
      res
 | 
			
		||||
        .then((obj: any) => {
 | 
			
		||||
          expect(obj).to.be.undefined;
 | 
			
		||||
        })
 | 
			
		||||
        .catch((err) => {
 | 
			
		||||
          expect(err).to.be.eql(new Error("connect ECONNREFUSED 127.0.0.1:80"));
 | 
			
		||||
        });
 | 
			
		||||
      // when
 | 
			
		||||
      await assert.rejects(() => myListener.fetchRSS(), err);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  describe("start", function () {
 | 
			
		||||
    it("Let's start the timer", async function () {
 | 
			
		||||
      let clock: sinon.default.SinonFakeTimers = sinon.default.useFakeTimers();
 | 
			
		||||
    it("fetches immediately the RSS information", async function () {
 | 
			
		||||
      // given
 | 
			
		||||
      const clock = sinon.useFakeTimers();
 | 
			
		||||
 | 
			
		||||
      const mockManager: InPlaceMockManager<Parser> = ImportMock.mockClassInPlace<Parser>(
 | 
			
		||||
        Parser
 | 
			
		||||
      );
 | 
			
		||||
      let stubParser = mockManager.mock("parseURL");
 | 
			
		||||
      stubParser.withArgs(infosListener.address).resolves(mockedRSSOutput);
 | 
			
		||||
      stubParser
 | 
			
		||||
        .withArgs("bad.rss.service")
 | 
			
		||||
        .rejects(new Error("connect ECONNREFUSED 127.0.0.1:80"));
 | 
			
		||||
      const stubParser = mockManager.mock("parseURL");
 | 
			
		||||
      stubParser.resolves(mockedRSSOutput);
 | 
			
		||||
 | 
			
		||||
      // classic build
 | 
			
		||||
      let myListener = new Listeners({
 | 
			
		||||
        name: "my-test-service",
 | 
			
		||||
        address: "fake.rss.service",
 | 
			
		||||
        timeloop: 60,
 | 
			
		||||
        customfields: {
 | 
			
		||||
          description: ["media:group", "media:description"],
 | 
			
		||||
          icon: ["media:group", "media:thumbnail"],
 | 
			
		||||
        },
 | 
			
		||||
      const myListener = new Listeners(infosListener);
 | 
			
		||||
 | 
			
		||||
      //spy
 | 
			
		||||
      const updateListenerSpy = sinon.spy();
 | 
			
		||||
 | 
			
		||||
      // start timer
 | 
			
		||||
      myListener.on("update", updateListenerSpy);
 | 
			
		||||
 | 
			
		||||
      myListener.start();
 | 
			
		||||
 | 
			
		||||
      // when
 | 
			
		||||
      await clock.tickAsync(1);
 | 
			
		||||
 | 
			
		||||
      // then
 | 
			
		||||
      expect(updateListenerSpy).to.have.been.calledOnce;
 | 
			
		||||
      expect(updateListenerSpy).to.have.been.calledWith(mockedRSSOutput);
 | 
			
		||||
      expect(stubParser).to.have.calledWith(myListener.address);
 | 
			
		||||
      myListener.stop();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it("has fetched multiple times after a while", async function () {
 | 
			
		||||
      // given
 | 
			
		||||
      const clock = sinon.useFakeTimers();
 | 
			
		||||
 | 
			
		||||
      const mockManager: InPlaceMockManager<Parser> = ImportMock.mockClassInPlace<Parser>(
 | 
			
		||||
        Parser
 | 
			
		||||
      );
 | 
			
		||||
      const stubParser = mockManager.mock("parseURL");
 | 
			
		||||
      stubParser.resolves(mockedRSSOutput);
 | 
			
		||||
 | 
			
		||||
      // classic build
 | 
			
		||||
      const myListener = new Listeners({
 | 
			
		||||
        ...infosListener,
 | 
			
		||||
        timeloop: 15,
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      //spy
 | 
			
		||||
      const fun_spy: sinon.default.SinonSpy = sinon.default.spy((obj) => {
 | 
			
		||||
        expect(obj).to.be.eql(mockedRSSOutput);
 | 
			
		||||
      });
 | 
			
		||||
      const updateListenerSpy: sinon.SinonSpy = sinon.spy();
 | 
			
		||||
      const newRSSOutput = {
 | 
			
		||||
        ...mockedRSSOutput,
 | 
			
		||||
        items: mockedRSSOutput.items.concat({
 | 
			
		||||
          title: "my title 03",
 | 
			
		||||
          "media:group": {
 | 
			
		||||
            "media:description": "my description 03",
 | 
			
		||||
            "media:thumbnail": [
 | 
			
		||||
              { $: { height: 360, width: 420, url: "my_image03.jpg" } },
 | 
			
		||||
            ],
 | 
			
		||||
          },
 | 
			
		||||
          link: "my_url_03.com",
 | 
			
		||||
          pubDate: "myDate03",
 | 
			
		||||
        }),
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      // start timer
 | 
			
		||||
      myListener.on("update", (obj) => fun_spy(obj));
 | 
			
		||||
      myListener.on("update", updateListenerSpy);
 | 
			
		||||
 | 
			
		||||
      myListener.start();
 | 
			
		||||
 | 
			
		||||
      // wait and assertion
 | 
			
		||||
      // After 1ms
 | 
			
		||||
      // when
 | 
			
		||||
      await clock.tickAsync(1);
 | 
			
		||||
      expect(fun_spy).to.have.been.calledOnce;
 | 
			
		||||
      stubParser.resolves(newRSSOutput);
 | 
			
		||||
      await clock.tickAsync(60000);
 | 
			
		||||
 | 
			
		||||
      // After 60s
 | 
			
		||||
      await clock.tickAsync(59999);
 | 
			
		||||
      expect(fun_spy).to.have.been.calledTwice;
 | 
			
		||||
      // then
 | 
			
		||||
      expect(updateListenerSpy).to.have.been.callCount(5);
 | 
			
		||||
      expect(updateListenerSpy.firstCall).to.have.been.calledWith(
 | 
			
		||||
        mockedRSSOutput
 | 
			
		||||
      );
 | 
			
		||||
      expect(updateListenerSpy.secondCall).to.have.been.calledWith(
 | 
			
		||||
        newRSSOutput
 | 
			
		||||
      );
 | 
			
		||||
 | 
			
		||||
      myListener.stop();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it("Let's start the timer (with a bad address)", async function () {
 | 
			
		||||
      let clock: sinon.default.SinonFakeTimers = sinon.default.useFakeTimers();
 | 
			
		||||
    it("notifies with a 'error' when fetching fails", async function () {
 | 
			
		||||
      const clock = sinon.useFakeTimers();
 | 
			
		||||
 | 
			
		||||
      const mockManager: InPlaceMockManager<Parser> = ImportMock.mockClassInPlace<Parser>(
 | 
			
		||||
        Parser
 | 
			
		||||
      );
 | 
			
		||||
      let stubParser = mockManager.mock("parseURL");
 | 
			
		||||
      stubParser.withArgs(infosListener.address).resolves(mockedRSSOutput);
 | 
			
		||||
      stubParser
 | 
			
		||||
        .withArgs("bad.rss.service")
 | 
			
		||||
        .rejects(new Error("connect ECONNREFUSED 127.0.0.1:80"));
 | 
			
		||||
      const stubParser = mockManager.mock("parseURL");
 | 
			
		||||
      const expectedErr = new Error("connect ECONNREFUSED 127.0.0.1:80");
 | 
			
		||||
      stubParser.rejects(expectedErr);
 | 
			
		||||
 | 
			
		||||
      // classic build
 | 
			
		||||
      let myListener = new Listeners({
 | 
			
		||||
        name: "my-test-service",
 | 
			
		||||
        address: "bad.rss.service",
 | 
			
		||||
      const myListener = new Listeners({
 | 
			
		||||
        ...infosListener,
 | 
			
		||||
        timeloop: 60,
 | 
			
		||||
        customfields: {
 | 
			
		||||
          description: ["media:group", "media:description"],
 | 
			
		||||
          icon: ["media:group", "media:thumbnail"],
 | 
			
		||||
        },
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      //spy
 | 
			
		||||
      let fun_spy_err: sinon.default.SinonSpy = sinon.default.spy((err) => {
 | 
			
		||||
        expect(err).to.not.be.eql(undefined);
 | 
			
		||||
      });
 | 
			
		||||
      const updateListenerSpy = sinon.spy();
 | 
			
		||||
      const updateErrorListenerSpy = sinon.spy();
 | 
			
		||||
 | 
			
		||||
      myListener.on("update_err", fun_spy_err);
 | 
			
		||||
      myListener.on("error", updateErrorListenerSpy);
 | 
			
		||||
      myListener.on("update", updateListenerSpy);
 | 
			
		||||
 | 
			
		||||
      // start timer
 | 
			
		||||
      myListener.start();
 | 
			
		||||
@@ -332,13 +348,21 @@ describe("test class RSS: jsonfile", function () {
 | 
			
		||||
      // wait and assertion
 | 
			
		||||
      // After 1ms
 | 
			
		||||
      await clock.tickAsync(1);
 | 
			
		||||
      // expect(stubListener.fetchRSS).to.have.been.calledOnce;
 | 
			
		||||
      expect(fun_spy_err).to.have.been.calledOnce;
 | 
			
		||||
      expect(updateErrorListenerSpy).to.have.been.calledOnce;
 | 
			
		||||
      expect(updateListenerSpy).to.not.have.been.called;
 | 
			
		||||
      expect(updateErrorListenerSpy).to.have.been.calledWith(expectedErr);
 | 
			
		||||
 | 
			
		||||
      // After 60s
 | 
			
		||||
      await clock.tickAsync(59999);
 | 
			
		||||
      // expect(stubListener.fetchRSS).to.have.been.calledTwice;
 | 
			
		||||
      expect(fun_spy_err).to.have.been.calledTwice;
 | 
			
		||||
      await clock.tickAsync(60000);
 | 
			
		||||
      expect(updateErrorListenerSpy).to.have.been.calledTwice;
 | 
			
		||||
      expect(updateListenerSpy).to.not.have.been.called;
 | 
			
		||||
 | 
			
		||||
      // When the service is back
 | 
			
		||||
      stubParser.resolves(mockedRSSOutput);
 | 
			
		||||
      await clock.tickAsync(60000);
 | 
			
		||||
 | 
			
		||||
      expect(updateListenerSpy).to.have.been.calledOnce;
 | 
			
		||||
      expect(updateListenerSpy).to.have.been.calledWith(mockedRSSOutput);
 | 
			
		||||
 | 
			
		||||
      myListener.stop();
 | 
			
		||||
    });
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user