Improve tests a little bit

This commit is contained in:
Florent 2021-03-06 17:32:59 +01:00 committed by Florent F
parent f6d98e472e
commit dd4bf59e41
2 changed files with 129 additions and 107 deletions

View File

@ -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 () => {

View File

@ -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();
});