youtube-listener-rss/tests/index-spec.ts

342 lines
10 KiB
TypeScript
Raw Permalink Normal View History

// tested class
2021-03-23 13:50:31 +01:00
import { YoutubeListenerRss } from "../";
// Unit test
2021-03-23 13:50:31 +01:00
import path from "path";
import events from "events";
import nock from "nock";
import * as chai from "chai";
import sinon from "ts-sinon";
import sinonChai from "sinon-chai";
chai.use(sinonChai);
const expect = chai.expect;
// default value (more easy when it's aliases)
2021-03-23 13:50:31 +01:00
const defaultChannelID = "UCh2YBKhYIy-_LtfCIn2Jycg";
const defaultTimeloop = 15;
const defaultHistory = ["https://www.youtube.com/watch?v=OYoZgsyu7tw"];
// expected value during my test
2021-03-23 13:50:31 +01:00
const expectedChannelAddress = `https://www.youtube.com/feeds/videos.xml?channel_id=${defaultChannelID}`;
const expectedCustomFields = {
description: ["media:group", "media:description"],
icon: ["media:group", "media:thumbnail"],
};
2021-03-23 13:50:31 +01:00
const expectedElmts = require("./RessourcesTest/expectedElmts.json");
const expectedFirstElmt = expectedElmts[0];
const expectedLastElmt = expectedElmts[1];
// let's test
describe("test ytbListener_RSS class", function () {
describe("test constructor", function () {
2021-03-23 13:50:31 +01:00
it("construct with 3 params", function () {
// given
const listener = new YoutubeListenerRss(
2021-03-23 13:50:31 +01:00
defaultChannelID,
defaultTimeloop, // 15 sec
defaultHistory
);
// assertions
2021-03-23 13:50:31 +01:00
expect(listener.address).to.be.eql(expectedChannelAddress);
expect(listener.timeloop).to.be.eql(defaultTimeloop);
expect(listener.customfields).to.be.eql(expectedCustomFields);
expect(listener.lastEntriesLinks).to.be.eql(defaultHistory);
});
2021-03-23 13:50:31 +01:00
it("construct with 2 params (without history)", function () {
// given
const listener = new YoutubeListenerRss(
2021-03-23 13:50:31 +01:00
defaultChannelID,
defaultTimeloop // 15 sec
);
// assertions
2021-03-23 13:50:31 +01:00
expect(listener.address).to.be.eql(expectedChannelAddress);
expect(listener.timeloop).to.be.eql(defaultTimeloop);
expect(listener.customfields).to.be.eql(expectedCustomFields);
});
it("construct with 1 params (without history and timeloop)", function () {
// given
const listener = new YoutubeListenerRss(defaultChannelID);
// assertions
expect(listener.address).to.be.eql(expectedChannelAddress);
expect(listener.timeloop).to.be.eql(5 * 60);
2021-03-23 13:50:31 +01:00
expect(listener.customfields).to.be.eql(expectedCustomFields);
});
});
2021-03-23 13:50:31 +01:00
describe("integration test", function () {
beforeEach(function () {
nock.disableNetConnect();
2021-03-23 13:50:31 +01:00
});
2021-03-23 13:50:31 +01:00
afterEach(function () {
nock.cleanAll();
});
it("fetches", async function () {
// given
nock("https://www.youtube.com")
.get("/feeds/videos.xml?channel_id=UCh2YBKhYIy-_LtfCIn2Jycg")
2021-03-23 13:50:31 +01:00
.replyWithFile(
200,
path.join(__dirname, "RessourcesTest/youtube_feed.rss"),
{
"content-type": "text/xml",
charset: "UTF-8",
}
);
const listener = new YoutubeListenerRss(
2021-03-23 13:50:31 +01:00
defaultChannelID,
defaultTimeloop
);
//when
const res = await listener.fetchRSS();
// assertion
2021-03-23 13:50:31 +01:00
expect(res.items[0]).to.be.eql(expectedFirstElmt);
expect(res.items[res.items.length - 1]).to.be.eql(expectedLastElmt);
});
2021-03-23 13:50:31 +01:00
/**
* This test will test the usage of the librairie with, in the order
* - 1 fetch of the original document (here trigger update and new_entries events)
* - 1 fetch with the original document and a new entry (here trigger update and new_entries events)
* - 1 fetch of the previous document (here trigger update events)
*/
it("fetches with start loop in 3 times", async function () {
// given
const clock = sinon.useFakeTimers();
2021-03-23 13:50:31 +01:00
nock("https://www.youtube.com")
.get("/feeds/videos.xml?channel_id=UCh2YBKhYIy-_LtfCIn2Jycg")
.replyWithFile(
200,
path.join(__dirname, "RessourcesTest/youtube_feed.rss"),
{
"content-type": "text/xml",
charset: "UTF-8",
}
);
const listener = new YoutubeListenerRss(
defaultChannelID,
defaultTimeloop
);
// spy
const updateListenerSpy = sinon.spy();
const newEntriesListenerSpy = sinon.spy();
// start timer
listener.on("update", updateListenerSpy);
listener.on("newEntries", newEntriesListenerSpy);
listener.start();
// when
await events.once(listener, "update");
// assertion
expect(updateListenerSpy).to.have.been.calledOnce;
expect(updateListenerSpy.firstCall.args[0])
.to.have.property("items")
.that.deep.include.members([expectedFirstElmt, expectedLastElmt]);
expect(newEntriesListenerSpy).to.have.been.called;
expect(
newEntriesListenerSpy.firstCall.args[0]
).that.deep.include.members([expectedFirstElmt, expectedLastElmt]);
expect(updateListenerSpy.firstCall.args[0].items.length).to.be.eql(
newEntriesListenerSpy.firstCall.args[0].length
);
// todo update the rss feed
// Fake RSS entry to simulate an update
const newEntry = expectedElmts[2];
nock("https://www.youtube.com")
.get("/feeds/videos.xml?channel_id=UCh2YBKhYIy-_LtfCIn2Jycg")
.replyWithFile(
200,
path.join(__dirname, "RessourcesTest/youtube_feed_new_entries.rss"),
{
"content-type": "text/xml",
charset: "UTF-8",
}
);
// when
await clock.tickAsync(15000);
await events.once(listener, "update");
2021-03-23 13:50:31 +01:00
// assertion
expect(updateListenerSpy).to.have.been.calledTwice;
expect(updateListenerSpy.secondCall.args[0])
.to.have.property("items")
.that.deep.include.members([
expectedFirstElmt,
expectedLastElmt,
newEntry,
]);
expect(newEntriesListenerSpy).to.have.been.calledTwice;
expect(updateListenerSpy.secondCall.args[0])
.to.have.property("items")
.that.deep.include.members([newEntry]);
// when
nock("https://www.youtube.com")
.get("/feeds/videos.xml?channel_id=UCh2YBKhYIy-_LtfCIn2Jycg")
2021-03-23 13:50:31 +01:00
.replyWithFile(
200,
path.join(__dirname, "RessourcesTest/youtube_feed_new_entries.rss"),
{
"content-type": "text/xml",
charset: "UTF-8",
}
);
await clock.tickAsync(15000);
await events.once(listener, "update");
// assertion
expect(updateListenerSpy).to.have.been.calledThrice;
expect(updateListenerSpy.secondCall.args[0])
.to.have.property("items")
.that.deep.include.members([
expectedFirstElmt,
expectedLastElmt,
newEntry,
]);
expect(newEntriesListenerSpy).to.not.have.been.calledThrice;
// then
listener.stop();
});
/**
* This test will test the usage of the librairie with, in the order
* - 1 fetch of the original document (here trigger update and new_entries events)
* - 1 fetch with the original document and a new entry (here trigger update and new_entries events)
* - 1 fetch of the previous document (here trigger update events)
*/
it("fetches with start loop in 3 times and history is initialize", async function () {
// given
const clock = sinon.useFakeTimers();
nock("https://www.youtube.com")
.get("/feeds/videos.xml?channel_id=UCh2YBKhYIy-_LtfCIn2Jycg")
.replyWithFile(
200,
path.join(__dirname, "RessourcesTest/youtube_feed.rss"),
{
"content-type": "text/xml",
charset: "UTF-8",
}
);
const listener = new YoutubeListenerRss(
2021-03-23 13:50:31 +01:00
defaultChannelID,
defaultTimeloop,
defaultHistory
);
// spy
const updateListenerSpy = sinon.spy();
const newEntriesListenerSpy = sinon.spy();
// start timer
listener.on("update", updateListenerSpy);
2021-03-23 13:50:31 +01:00
listener.on("newEntries", newEntriesListenerSpy);
listener.start();
// when
2021-03-23 13:50:31 +01:00
await events.once(listener, "update");
// assertion
expect(updateListenerSpy).to.have.been.calledOnce;
2021-03-23 13:50:31 +01:00
expect(updateListenerSpy.firstCall.args[0])
.to.have.property("items")
.that.deep.include.members([expectedFirstElmt, expectedLastElmt]);
expect(newEntriesListenerSpy).to.have.been.called;
expect(newEntriesListenerSpy.firstCall.args[0])
.that.deep.include.members([expectedLastElmt])
.and.that.not.deep.include.members([expectedFirstElmt]);
expect(updateListenerSpy.firstCall.args[0].items.length).to.be.eql(
newEntriesListenerSpy.firstCall.args[0].length + 1
);
// todo update the rss feed
2021-03-23 13:50:31 +01:00
// Fake RSS entry to simulate an update
const newEntry = expectedElmts[2];
nock("https://www.youtube.com")
.get("/feeds/videos.xml?channel_id=UCh2YBKhYIy-_LtfCIn2Jycg")
.replyWithFile(
200,
path.join(__dirname, "RessourcesTest/youtube_feed_new_entries.rss"),
{
"content-type": "text/xml",
charset: "UTF-8",
}
);
// when
2021-03-23 13:50:31 +01:00
await clock.tickAsync(15000);
await events.once(listener, "update");
// assertion
expect(updateListenerSpy).to.have.been.calledTwice;
2021-03-23 13:50:31 +01:00
expect(updateListenerSpy.secondCall.args[0])
.to.have.property("items")
.that.deep.include.members([
expectedFirstElmt,
expectedLastElmt,
newEntry,
]);
expect(newEntriesListenerSpy).to.have.been.calledTwice;
expect(updateListenerSpy.secondCall.args[0])
.to.have.property("items")
.that.deep.include.members([newEntry]);
// when
nock("https://www.youtube.com")
.get("/feeds/videos.xml?channel_id=UCh2YBKhYIy-_LtfCIn2Jycg")
.replyWithFile(
200,
path.join(__dirname, "RessourcesTest/youtube_feed_new_entries.rss"),
{
"content-type": "text/xml",
charset: "UTF-8",
}
);
await clock.tickAsync(15000);
await events.once(listener, "update");
// assertion
expect(updateListenerSpy).to.have.been.calledThrice;
expect(updateListenerSpy.secondCall.args[0])
.to.have.property("items")
.that.deep.include.members([
expectedFirstElmt,
expectedLastElmt,
newEntry,
]);
expect(newEntriesListenerSpy).to.not.have.been.calledThrice;
// then
listener.stop();
});
});
});