Improve tests a little bit
This commit is contained in:
parent
f6d98e472e
commit
dd4bf59e41
|
@ -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();
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue
Block a user