forked from Outils-PeerTube/listener-rss-aggregator
		
	implementation @database/sqlite + test addapted
This commit is contained in:
		
							
								
								
									
										10496
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										10496
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -25,16 +25,17 @@
 | 
			
		||||
    "eslint-plugin-import": "^2.22.1",
 | 
			
		||||
    "eslint-plugin-mocha": "8.0.0",
 | 
			
		||||
    "eslint-plugin-prettier": "3.3.1",
 | 
			
		||||
    "mocha": "8.2.1",
 | 
			
		||||
    "mocha": "^8.2.1",
 | 
			
		||||
    "nock": "^13.0.11",
 | 
			
		||||
    "prettier": "2.2.1",
 | 
			
		||||
    "sinon-chai": "^3.5.0",
 | 
			
		||||
    "tmp-promise": "^3.0.2",
 | 
			
		||||
    "ts-node": "9.1.1",
 | 
			
		||||
    "ts-sinon": "2.0.1",
 | 
			
		||||
    "typescript": "^4.1.3"
 | 
			
		||||
  },
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "listener-rss": "file:../listener-rss",
 | 
			
		||||
    "sqlite3": "^5.0.2"
 | 
			
		||||
    "@databases/sqlite": "^3.0.0",
 | 
			
		||||
    "listener-rss": "file:../listener-rss"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,7 @@
 | 
			
		||||
import EventEmitter from "events";
 | 
			
		||||
 | 
			
		||||
import { ListenerRss, ListenerRSSInfos } from "listener-rss";
 | 
			
		||||
 | 
			
		||||
interface ManageListenerInfo {
 | 
			
		||||
  timeloop?: number;
 | 
			
		||||
  path?: string;
 | 
			
		||||
}
 | 
			
		||||
import { SqliteTools } from "./sqlite-tools";
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Permit to manage a ListenerRSS array, data storage and event aggregation
 | 
			
		||||
@@ -14,83 +10,48 @@ export class ManageListener extends EventEmitter {
 | 
			
		||||
  listenerArray: ListenerRss[] = [];
 | 
			
		||||
  looprunning: boolean = false;
 | 
			
		||||
 | 
			
		||||
  // manage aggregation
 | 
			
		||||
  timeloop?: number;
 | 
			
		||||
  buffUpdates: any[] = [];
 | 
			
		||||
  buffNewEntries: any[] = [];
 | 
			
		||||
  sqliteDb: SqliteTools;
 | 
			
		||||
 | 
			
		||||
  constructor(info?: ManageListenerInfo) {
 | 
			
		||||
  constructor(path: string) {
 | 
			
		||||
    super();
 | 
			
		||||
    if (info) {
 | 
			
		||||
      if (info.timeloop) {
 | 
			
		||||
        this.timeloop = info.timeloop;
 | 
			
		||||
      }
 | 
			
		||||
      if (info.path) {
 | 
			
		||||
        const fs = require("fs");
 | 
			
		||||
        const tmp = fs.readFileSync(info.path);
 | 
			
		||||
        const configs: ListenerRSSInfos[] = JSON.parse(tmp);
 | 
			
		||||
        configs.forEach((config) => this.addNewListener(config));
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    this.sqliteDb = new SqliteTools(path);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async load() {
 | 
			
		||||
    await this.sqliteDb.ensureTableExists();
 | 
			
		||||
    const configs: ListenerRSSInfos[] = await this.sqliteDb.fetchAll();
 | 
			
		||||
 | 
			
		||||
    configs.forEach((config) => {
 | 
			
		||||
      const newListener = new ListenerRss(config);
 | 
			
		||||
      this.listenerArray.push(newListener);
 | 
			
		||||
      this.settingEvents(newListener);
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  settingEvents(newListener: ListenerRss): void {
 | 
			
		||||
    if (this.timeloop !== undefined) {
 | 
			
		||||
      newListener.on("update", (obj) => this.buffUpdates.push(obj));
 | 
			
		||||
      newListener.on("newEntries", (obj) => this.buffNewEntries.push(obj));
 | 
			
		||||
      // /!\ todo /!\ threat error with aggregation
 | 
			
		||||
      // newListener.on("error", (err) => this.emit("error", err));
 | 
			
		||||
    } else {
 | 
			
		||||
      newListener.on("update", (obj) => this.emit("update", obj));
 | 
			
		||||
      newListener.on("newEntries", (obj) => this.emit("newEntries", obj));
 | 
			
		||||
      newListener.on("error", (err) => this.emit("error", err));
 | 
			
		||||
    }
 | 
			
		||||
    newListener.on("update", (obj) => this.emit("update", obj));
 | 
			
		||||
    newListener.on("newEntries", (obj) => this.emit("newEntries", obj));
 | 
			
		||||
    newListener.on("error", (err) => this.emit("error", err));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  addNewListener(info: ListenerRSSInfos): void {
 | 
			
		||||
  async addNewListener(info: ListenerRSSInfos) {
 | 
			
		||||
    const newListener = new ListenerRss(info);
 | 
			
		||||
    this.listenerArray.push(newListener);
 | 
			
		||||
    this.settingEvents(newListener);
 | 
			
		||||
 | 
			
		||||
    await this.sqliteDb.insertListener(newListener);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  save(path: string): void {
 | 
			
		||||
    if (path.endsWith(".json")) {
 | 
			
		||||
      const fs = require("fs");
 | 
			
		||||
      fs.writeFileSync(
 | 
			
		||||
        path,
 | 
			
		||||
        JSON.stringify(
 | 
			
		||||
          this.listenerArray.map((listener) => listener.getProperty())
 | 
			
		||||
        )
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
  async save() {
 | 
			
		||||
    await this.sqliteDb.updateAll(
 | 
			
		||||
      this.listenerArray.map((listener) => listener.getProperty())
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  startAll(): void {
 | 
			
		||||
    if (!this.looprunning) {
 | 
			
		||||
      this.looprunning = true;
 | 
			
		||||
      this.listenerArray.forEach((listener) => listener.start());
 | 
			
		||||
 | 
			
		||||
      if (this.timeloop) {
 | 
			
		||||
        const fun: () => void = async () => {
 | 
			
		||||
          this.emit("update", this.buffUpdates);
 | 
			
		||||
          if (this.buffNewEntries.length) {
 | 
			
		||||
            console.log(this.buffNewEntries.length);
 | 
			
		||||
            this.emit("newEntries", this.buffNewEntries);
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          this.buffUpdates = [];
 | 
			
		||||
          this.buffNewEntries = [];
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        (async () => {
 | 
			
		||||
          while (this.looprunning) {
 | 
			
		||||
            await fun();
 | 
			
		||||
            await new Promise((res) =>
 | 
			
		||||
              setTimeout(res, this.timeloop ? this.timeloop * 1000 : 0)
 | 
			
		||||
            );
 | 
			
		||||
          }
 | 
			
		||||
        })();
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										71
									
								
								src/sqlite-tools.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								src/sqlite-tools.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,71 @@
 | 
			
		||||
import { ListenerRSSInfos } from "listener-rss";
 | 
			
		||||
 | 
			
		||||
import connect, { sql } from "@databases/sqlite";
 | 
			
		||||
 | 
			
		||||
export class SqliteTools {
 | 
			
		||||
  path?: string;
 | 
			
		||||
 | 
			
		||||
  constructor(path?: string) {
 | 
			
		||||
    this.path = path;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async ensureTableExists() {
 | 
			
		||||
    const db = connect(this.path);
 | 
			
		||||
 | 
			
		||||
    let req = sql`CREATE TABLE IF NOT EXISTS listeners
 | 
			
		||||
                  (
 | 
			
		||||
                    address TEXT NOT NULL UNIQUE,
 | 
			
		||||
                    customfields TEXT DEFAULT '[]',
 | 
			
		||||
                    timeloop INTEGER DEFAULT 300,
 | 
			
		||||
                    last_entries_links TEXT DEFAULT '[]',
 | 
			
		||||
                    PRIMARY KEY (address),
 | 
			
		||||
                    CHECK(timeloop >= 0)
 | 
			
		||||
                  );`;
 | 
			
		||||
 | 
			
		||||
    await db.query(req);
 | 
			
		||||
    await db.dispose();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async fetchAll(): Promise<ListenerRSSInfos[]> {
 | 
			
		||||
    const db = connect(this.path);
 | 
			
		||||
 | 
			
		||||
    let req = sql`SELECT *
 | 
			
		||||
                  FROM listeners`;
 | 
			
		||||
    const rows = await db.query(req);
 | 
			
		||||
    await db.dispose();
 | 
			
		||||
    return rows.map((row: any) => ({
 | 
			
		||||
      address: row["address"],
 | 
			
		||||
      customfields: JSON.parse(row["customfields"]),
 | 
			
		||||
      timeloop: row["timeloop"],
 | 
			
		||||
      lastEntriesLinks: JSON.parse(row["last_entries_links"]),
 | 
			
		||||
    }));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async insertListener(listener: ListenerRSSInfos) {
 | 
			
		||||
    const db = connect(this.path);
 | 
			
		||||
 | 
			
		||||
    let req = sql`INSERT INTO listeners (address, timeloop, customfields, last_entries_links)
 | 
			
		||||
                  VALUES (${listener.address},
 | 
			
		||||
                    ${listener.timeloop},
 | 
			
		||||
                    ${JSON.stringify(listener.customfields)},
 | 
			
		||||
                    ${JSON.stringify(listener.lastEntriesLinks)})`;
 | 
			
		||||
    await db.query(req);
 | 
			
		||||
    await db.dispose();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async updateAll(listeners: ListenerRSSInfos[]) {
 | 
			
		||||
    const db = connect(this.path);
 | 
			
		||||
 | 
			
		||||
    await db.tx(async (transaction) => {
 | 
			
		||||
      for (const listener of listeners) {
 | 
			
		||||
        let req = sql`UPDATE listeners
 | 
			
		||||
                    SET last_entries_links = ${JSON.stringify(
 | 
			
		||||
                      listener.lastEntriesLinks
 | 
			
		||||
                    )}
 | 
			
		||||
                    WHERE address = ${listener.address}`;
 | 
			
		||||
        await transaction.query(req);
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
    await db.dispose();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,20 +0,0 @@
 | 
			
		||||
[
 | 
			
		||||
  {
 | 
			
		||||
    "address": "https://www.youtube.com/feeds/videos.xml?channel_id=UCOuIgj0CYCXCvjWywjDbauw",
 | 
			
		||||
    "customfields": { "media:group": ["media:group"] },
 | 
			
		||||
    "lastEntriesLinks": [],
 | 
			
		||||
    "timeloop": 10
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "address": "https://www.youtube.com/feeds/videos.xml?channel_id=UCh2YBKhYIy-_LtfCIn2Jycg",
 | 
			
		||||
    "customfields": { "media:group": ["media:group"] },
 | 
			
		||||
    "lastEntriesLinks": [],
 | 
			
		||||
    "timeloop": 20
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "address": "https://www.youtube.com/feeds/videos.xml?channel_id=UCY7klexd1qEqxgqYK6W7BVQ",
 | 
			
		||||
    "customfields": { "media:group": ["media:group"] },
 | 
			
		||||
    "lastEntriesLinks": [],
 | 
			
		||||
    "timeloop": 30
 | 
			
		||||
  }
 | 
			
		||||
]
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								tests/RessourcesTest/db/tmp.db
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								tests/RessourcesTest/db/tmp.db
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							@@ -2,84 +2,48 @@
 | 
			
		||||
import { ListenerRss, ListenerRSSInfos } from "listener-rss";
 | 
			
		||||
 | 
			
		||||
// local lib
 | 
			
		||||
import { ManageListener } from "../";
 | 
			
		||||
import { ManageListener } from "../src/";
 | 
			
		||||
 | 
			
		||||
// Unit test
 | 
			
		||||
import path from "path";
 | 
			
		||||
import { join as joinPath } 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";
 | 
			
		||||
 | 
			
		||||
import { withFile } from "tmp-promise";
 | 
			
		||||
 | 
			
		||||
chai.use(sinonChai);
 | 
			
		||||
 | 
			
		||||
const expect = chai.expect;
 | 
			
		||||
 | 
			
		||||
describe("test class GestionListener", function () {
 | 
			
		||||
  describe("test constructor", function () {
 | 
			
		||||
    it("should create a new manageListener object without params", function () {
 | 
			
		||||
      // when
 | 
			
		||||
      const ml = new ManageListener();
 | 
			
		||||
 | 
			
		||||
      // expect
 | 
			
		||||
      expect(ml.listenerArray).to.be.empty;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it("should create a new manageListener object with a param file", function () {
 | 
			
		||||
      // given
 | 
			
		||||
      const tmp = require("./RessourcesTest/FakeRessources/save.json");
 | 
			
		||||
 | 
			
		||||
      // when
 | 
			
		||||
      const ml = new ManageListener({
 | 
			
		||||
        path: "tests/RessourcesTest/FakeRessources/save.json",
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      // expect
 | 
			
		||||
      expect(tmp).to.be.eql(ml.listenerArray.map((item) => item.getProperty()));
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
const dataWithHistory: ListenerRSSInfos[] = require("./RessourcesTest/RealRessources/save.json");
 | 
			
		||||
const dataWithoutHistory = dataWithHistory.map((data) => ({
 | 
			
		||||
  ...data,
 | 
			
		||||
  lastEntriesLinks: [],
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
describe("test class ManageListener", function () {
 | 
			
		||||
  describe("test saving", function () {
 | 
			
		||||
    beforeEach("Clean old files if exist", function () {
 | 
			
		||||
      const fs = require("fs");
 | 
			
		||||
      if (fs.existsSync("tests/RessourcesTest/FakeRessources/fake_save.json"))
 | 
			
		||||
        fs.unlinkSync("tests/RessourcesTest/FakeRessources/fake_save.json");
 | 
			
		||||
    });
 | 
			
		||||
    it("should save the inserted objects", async function () {
 | 
			
		||||
      await withFile(async ({ path }) => {
 | 
			
		||||
        // given
 | 
			
		||||
        const ml = new ManageListener(path);
 | 
			
		||||
        await ml.load();
 | 
			
		||||
 | 
			
		||||
    afterEach("Clean old files if exist", function () {
 | 
			
		||||
      const fs = require("fs");
 | 
			
		||||
      if (fs.existsSync("tests/RessourcesTest/FakeRessources/fake_save.json"))
 | 
			
		||||
        fs.unlinkSync("tests/RessourcesTest/FakeRessources/fake_save.json");
 | 
			
		||||
    });
 | 
			
		||||
        for (const item of dataWithoutHistory) await ml.addNewListener(item);
 | 
			
		||||
 | 
			
		||||
    it("should save the inserted objects", function (): void {
 | 
			
		||||
      // given
 | 
			
		||||
      const ml = new ManageListener();
 | 
			
		||||
      let expectedObj: ListenerRss[] = [];
 | 
			
		||||
        // when
 | 
			
		||||
        ml.save();
 | 
			
		||||
        const ml_bis = new ManageListener(path);
 | 
			
		||||
        await ml_bis.load();
 | 
			
		||||
 | 
			
		||||
      for (let i = 1; i < 10; i++) {
 | 
			
		||||
        const generatedInfo = {
 | 
			
		||||
          address: `fake.rss.service.${i}`,
 | 
			
		||||
          customfields: {
 | 
			
		||||
            "media:group": ["media:group"],
 | 
			
		||||
          },
 | 
			
		||||
          timeloop: i * 10,
 | 
			
		||||
        };
 | 
			
		||||
        expectedObj.push(new ListenerRss(generatedInfo));
 | 
			
		||||
        ml.addNewListener(generatedInfo);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // when
 | 
			
		||||
      ml.save("tests/RessourcesTest/FakeRessources/fake_save.json");
 | 
			
		||||
      const tmp = require("./RessourcesTest/FakeRessources/save.json");
 | 
			
		||||
 | 
			
		||||
      ml.save("tests/RessourcesTest/FakeRessources/fake_save.json");
 | 
			
		||||
 | 
			
		||||
      ml.save("tests/RessourcesTest/FakeRessources/fake_save.json");
 | 
			
		||||
 | 
			
		||||
      // expect
 | 
			
		||||
      expect(expectedObj.map((item) => item.getProperty())).to.be.eql(tmp);
 | 
			
		||||
        // expect
 | 
			
		||||
        expect(
 | 
			
		||||
          ml_bis.listenerArray.map((listener) => listener.getProperty())
 | 
			
		||||
        ).to.be.eql(dataWithoutHistory);
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
@@ -93,366 +57,370 @@ describe("test class GestionListener", function () {
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it("should call correctly the events (no aggregation)", async function () {
 | 
			
		||||
      // given
 | 
			
		||||
      const clock = sinon.useFakeTimers();
 | 
			
		||||
      const ml = new ManageListener({
 | 
			
		||||
        path: "tests/RessourcesTest/RealRessources/save_no_history.json",
 | 
			
		||||
      await withFile(async ({ path }) => {
 | 
			
		||||
        // given
 | 
			
		||||
        const clock = sinon.useFakeTimers();
 | 
			
		||||
        const ml = new ManageListener(path);
 | 
			
		||||
        await ml.load();
 | 
			
		||||
        for (const item of dataWithoutHistory) await ml.addNewListener(item);
 | 
			
		||||
 | 
			
		||||
        const updateSpy = sinon.spy();
 | 
			
		||||
        const newEntriesSpy = sinon.spy();
 | 
			
		||||
 | 
			
		||||
        const tabChannelId = [
 | 
			
		||||
          "UCOuIgj0CYCXCvjWywjDbauw",
 | 
			
		||||
          "UCh2YBKhYIy-_LtfCIn2Jycg",
 | 
			
		||||
          "UCY7klexd1qEqxgqYK6W7BVQ",
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
        ml.on("update", updateSpy);
 | 
			
		||||
        ml.on("newEntries", newEntriesSpy);
 | 
			
		||||
        tabChannelId.forEach((item: string) => {
 | 
			
		||||
          nock("https://www.youtube.com")
 | 
			
		||||
            .get(`/feeds/videos.xml?channel_id=${item}`)
 | 
			
		||||
            .replyWithFile(
 | 
			
		||||
              200,
 | 
			
		||||
              joinPath(__dirname, `RessourcesTest/RealRessources/${item}.rss`),
 | 
			
		||||
              { "content-type": "text/xml", charset: "utf-8" }
 | 
			
		||||
            )
 | 
			
		||||
            .persist();
 | 
			
		||||
        });
 | 
			
		||||
        ml.startAll();
 | 
			
		||||
 | 
			
		||||
        // here we're testing the first call
 | 
			
		||||
        // when
 | 
			
		||||
        await Promise.all([
 | 
			
		||||
          events.once(ml.listenerArray[0], "update"),
 | 
			
		||||
          events.once(ml.listenerArray[1], "update"),
 | 
			
		||||
          events.once(ml.listenerArray[2], "update"),
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
        //expect
 | 
			
		||||
        expect(updateSpy).to.have.been.calledThrice;
 | 
			
		||||
        expect(newEntriesSpy).to.have.been.calledThrice;
 | 
			
		||||
 | 
			
		||||
        // here we're testing the second call for the first listener
 | 
			
		||||
        // given
 | 
			
		||||
        updateSpy.resetHistory();
 | 
			
		||||
        newEntriesSpy.resetHistory();
 | 
			
		||||
 | 
			
		||||
        // when
 | 
			
		||||
        await clock.tickAsync(10000);
 | 
			
		||||
        await events.once(ml.listenerArray[0], "update");
 | 
			
		||||
 | 
			
		||||
        //expect
 | 
			
		||||
        expect(updateSpy).to.have.been.calledOnce;
 | 
			
		||||
        expect(newEntriesSpy).to.not.have.been.called;
 | 
			
		||||
 | 
			
		||||
        // here we're testing the thrid call for the first listener and second for the second listener
 | 
			
		||||
        // given
 | 
			
		||||
        updateSpy.resetHistory();
 | 
			
		||||
 | 
			
		||||
        // when
 | 
			
		||||
        await clock.tickAsync(10000);
 | 
			
		||||
        await Promise.all([
 | 
			
		||||
          events.once(ml.listenerArray[0], "update"),
 | 
			
		||||
          events.once(ml.listenerArray[1], "update"),
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
        //expect
 | 
			
		||||
        expect(updateSpy).to.have.been.calledTwice;
 | 
			
		||||
        expect(newEntriesSpy).to.not.have.been.called;
 | 
			
		||||
 | 
			
		||||
        // here we're testing the fourth call for the first listener and second for the third listener
 | 
			
		||||
        // given
 | 
			
		||||
        updateSpy.resetHistory();
 | 
			
		||||
 | 
			
		||||
        // when
 | 
			
		||||
        await clock.tickAsync(10000);
 | 
			
		||||
        await Promise.all([
 | 
			
		||||
          events.once(ml.listenerArray[0], "update"),
 | 
			
		||||
          events.once(ml.listenerArray[2], "update"),
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
        //expect
 | 
			
		||||
        expect(updateSpy).to.have.been.calledTwice;
 | 
			
		||||
        expect(newEntriesSpy).to.not.have.been.called;
 | 
			
		||||
 | 
			
		||||
        ml.stopAll();
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      const updateSpy = sinon.spy();
 | 
			
		||||
      const newEntriesSpy = sinon.spy();
 | 
			
		||||
 | 
			
		||||
      const tabChannelId = [
 | 
			
		||||
        "UCOuIgj0CYCXCvjWywjDbauw",
 | 
			
		||||
        "UCh2YBKhYIy-_LtfCIn2Jycg",
 | 
			
		||||
        "UCY7klexd1qEqxgqYK6W7BVQ",
 | 
			
		||||
      ];
 | 
			
		||||
 | 
			
		||||
      ml.on("update", updateSpy);
 | 
			
		||||
      ml.on("newEntries", newEntriesSpy);
 | 
			
		||||
      tabChannelId.forEach((item: string) => {
 | 
			
		||||
        nock("https://www.youtube.com")
 | 
			
		||||
          .get(`/feeds/videos.xml?channel_id=${item}`)
 | 
			
		||||
          .replyWithFile(
 | 
			
		||||
            200,
 | 
			
		||||
            path.join(__dirname, `RessourcesTest/RealRessources/${item}.rss`),
 | 
			
		||||
            { "content-type": "text/xml", charset: "utf-8" }
 | 
			
		||||
          )
 | 
			
		||||
          .persist();
 | 
			
		||||
      });
 | 
			
		||||
      ml.startAll();
 | 
			
		||||
 | 
			
		||||
      // here we're testing the first call
 | 
			
		||||
      // when
 | 
			
		||||
      await Promise.all([
 | 
			
		||||
        events.once(ml.listenerArray[0], "update"),
 | 
			
		||||
        events.once(ml.listenerArray[1], "update"),
 | 
			
		||||
        events.once(ml.listenerArray[2], "update"),
 | 
			
		||||
      ]);
 | 
			
		||||
 | 
			
		||||
      //expect
 | 
			
		||||
      expect(updateSpy).to.have.been.calledThrice;
 | 
			
		||||
      expect(newEntriesSpy).to.have.been.calledThrice;
 | 
			
		||||
 | 
			
		||||
      // here we're testing the second call for the first listener
 | 
			
		||||
      // given
 | 
			
		||||
      updateSpy.resetHistory();
 | 
			
		||||
      newEntriesSpy.resetHistory();
 | 
			
		||||
 | 
			
		||||
      // when
 | 
			
		||||
      await clock.tickAsync(10000);
 | 
			
		||||
      await events.once(ml.listenerArray[0], "update");
 | 
			
		||||
 | 
			
		||||
      //expect
 | 
			
		||||
      expect(updateSpy).to.have.been.calledOnce;
 | 
			
		||||
      expect(newEntriesSpy).to.not.have.been.called;
 | 
			
		||||
 | 
			
		||||
      // here we're testing the thrid call for the first listener and second for the second listener
 | 
			
		||||
      // given
 | 
			
		||||
      updateSpy.resetHistory();
 | 
			
		||||
 | 
			
		||||
      // when
 | 
			
		||||
      await clock.tickAsync(10000);
 | 
			
		||||
      await Promise.all([
 | 
			
		||||
        events.once(ml.listenerArray[0], "update"),
 | 
			
		||||
        events.once(ml.listenerArray[1], "update"),
 | 
			
		||||
      ]);
 | 
			
		||||
 | 
			
		||||
      //expect
 | 
			
		||||
      expect(updateSpy).to.have.been.calledTwice;
 | 
			
		||||
      expect(newEntriesSpy).to.not.have.been.called;
 | 
			
		||||
 | 
			
		||||
      // here we're testing the fourth call for the first listener and second for the third listener
 | 
			
		||||
      // given
 | 
			
		||||
      updateSpy.resetHistory();
 | 
			
		||||
 | 
			
		||||
      // when
 | 
			
		||||
      await clock.tickAsync(10000);
 | 
			
		||||
      await Promise.all([
 | 
			
		||||
        events.once(ml.listenerArray[0], "update"),
 | 
			
		||||
        events.once(ml.listenerArray[2], "update"),
 | 
			
		||||
      ]);
 | 
			
		||||
 | 
			
		||||
      //expect
 | 
			
		||||
      expect(updateSpy).to.have.been.calledTwice;
 | 
			
		||||
      expect(newEntriesSpy).to.not.have.been.called;
 | 
			
		||||
 | 
			
		||||
      ml.stopAll();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it("should call correctly the events with a new entry (no aggregation)", async function () {
 | 
			
		||||
      // given
 | 
			
		||||
      const clock = sinon.useFakeTimers();
 | 
			
		||||
      const ml = new ManageListener({
 | 
			
		||||
        path: "tests/RessourcesTest/RealRessources/save.json",
 | 
			
		||||
      await withFile(async ({ path }) => {
 | 
			
		||||
        // given
 | 
			
		||||
        const clock = sinon.useFakeTimers();
 | 
			
		||||
        const ml = new ManageListener(path);
 | 
			
		||||
        await ml.load();
 | 
			
		||||
        for (const item of dataWithHistory) await ml.addNewListener(item);
 | 
			
		||||
 | 
			
		||||
        const updateSpy = sinon.spy();
 | 
			
		||||
        const newEntriesSpy = sinon.spy();
 | 
			
		||||
 | 
			
		||||
        const tabChannelId = [
 | 
			
		||||
          "UCOuIgj0CYCXCvjWywjDbauw",
 | 
			
		||||
          "UCh2YBKhYIy-_LtfCIn2Jycg",
 | 
			
		||||
          "UCY7klexd1qEqxgqYK6W7BVQ",
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
        ml.on("update", updateSpy);
 | 
			
		||||
        ml.on("newEntries", newEntriesSpy);
 | 
			
		||||
        tabChannelId.forEach((item: string) => {
 | 
			
		||||
          nock("https://www.youtube.com")
 | 
			
		||||
            .get(`/feeds/videos.xml?channel_id=${item}`)
 | 
			
		||||
            .once()
 | 
			
		||||
            .replyWithFile(
 | 
			
		||||
              200,
 | 
			
		||||
              joinPath(__dirname, `RessourcesTest/RealRessources/${item}.rss`),
 | 
			
		||||
              { "content-type": "text/xml", charset: "utf-8" }
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
        ml.startAll();
 | 
			
		||||
 | 
			
		||||
        // here we're testing the first call
 | 
			
		||||
        // when
 | 
			
		||||
        await Promise.all([
 | 
			
		||||
          events.once(ml.listenerArray[0], "update"),
 | 
			
		||||
          events.once(ml.listenerArray[1], "update"),
 | 
			
		||||
          events.once(ml.listenerArray[2], "update"),
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
        //expect
 | 
			
		||||
        expect(updateSpy).to.have.been.calledThrice;
 | 
			
		||||
        expect(newEntriesSpy).to.not.have.been.called;
 | 
			
		||||
 | 
			
		||||
        // here we're testing the second call for the first listener
 | 
			
		||||
        // given
 | 
			
		||||
        updateSpy.resetHistory();
 | 
			
		||||
        newEntriesSpy.resetHistory();
 | 
			
		||||
 | 
			
		||||
        tabChannelId.forEach((item: string) => {
 | 
			
		||||
          nock("https://www.youtube.com")
 | 
			
		||||
            .get(`/feeds/videos.xml?channel_id=${item}`)
 | 
			
		||||
            .replyWithFile(
 | 
			
		||||
              200,
 | 
			
		||||
              joinPath(
 | 
			
		||||
                __dirname,
 | 
			
		||||
                `RessourcesTest/RealRessources/WithUpdate/${item}.rss`
 | 
			
		||||
              ),
 | 
			
		||||
              { "content-type": "text/xml", charset: "utf-8" }
 | 
			
		||||
            )
 | 
			
		||||
            .persist();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // when
 | 
			
		||||
        await clock.tickAsync(10000);
 | 
			
		||||
        await events.once(ml.listenerArray[0], "update");
 | 
			
		||||
 | 
			
		||||
        //expect
 | 
			
		||||
        expect(updateSpy).to.have.been.calledOnce;
 | 
			
		||||
        expect(newEntriesSpy).to.have.been.calledOnce;
 | 
			
		||||
 | 
			
		||||
        // here we're testing the thrid call for the first listener and second for the second listener
 | 
			
		||||
        // given
 | 
			
		||||
        updateSpy.resetHistory();
 | 
			
		||||
        newEntriesSpy.resetHistory();
 | 
			
		||||
 | 
			
		||||
        // when
 | 
			
		||||
        await clock.tickAsync(10000);
 | 
			
		||||
        await Promise.all([
 | 
			
		||||
          events.once(ml.listenerArray[0], "update"),
 | 
			
		||||
          events.once(ml.listenerArray[1], "update"),
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
        //expect
 | 
			
		||||
        expect(updateSpy).to.have.been.calledTwice;
 | 
			
		||||
        expect(newEntriesSpy).to.have.been.calledOnce;
 | 
			
		||||
 | 
			
		||||
        // here we're testing the fourth call for the first listener and second for the third listener
 | 
			
		||||
        // given
 | 
			
		||||
        updateSpy.resetHistory();
 | 
			
		||||
        newEntriesSpy.resetHistory();
 | 
			
		||||
 | 
			
		||||
        // when
 | 
			
		||||
        await clock.tickAsync(10000);
 | 
			
		||||
        await Promise.all([
 | 
			
		||||
          events.once(ml.listenerArray[0], "update"),
 | 
			
		||||
          events.once(ml.listenerArray[2], "update"),
 | 
			
		||||
        ]);
 | 
			
		||||
 | 
			
		||||
        //expect
 | 
			
		||||
        expect(updateSpy).to.have.been.calledTwice;
 | 
			
		||||
        expect(newEntriesSpy).to.have.been.calledOnce;
 | 
			
		||||
 | 
			
		||||
        ml.stopAll();
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      const updateSpy = sinon.spy();
 | 
			
		||||
      const newEntriesSpy = sinon.spy();
 | 
			
		||||
 | 
			
		||||
      const tabChannelId = [
 | 
			
		||||
        "UCOuIgj0CYCXCvjWywjDbauw",
 | 
			
		||||
        "UCh2YBKhYIy-_LtfCIn2Jycg",
 | 
			
		||||
        "UCY7klexd1qEqxgqYK6W7BVQ",
 | 
			
		||||
      ];
 | 
			
		||||
 | 
			
		||||
      ml.on("update", updateSpy);
 | 
			
		||||
      ml.on("newEntries", newEntriesSpy);
 | 
			
		||||
      tabChannelId.forEach((item: string) => {
 | 
			
		||||
        nock("https://www.youtube.com")
 | 
			
		||||
          .get(`/feeds/videos.xml?channel_id=${item}`)
 | 
			
		||||
          .once()
 | 
			
		||||
          .replyWithFile(
 | 
			
		||||
            200,
 | 
			
		||||
            path.join(__dirname, `RessourcesTest/RealRessources/${item}.rss`),
 | 
			
		||||
            { "content-type": "text/xml", charset: "utf-8" }
 | 
			
		||||
          );
 | 
			
		||||
      });
 | 
			
		||||
      ml.startAll();
 | 
			
		||||
 | 
			
		||||
      // here we're testing the first call
 | 
			
		||||
      // when
 | 
			
		||||
      await Promise.all([
 | 
			
		||||
        events.once(ml.listenerArray[0], "update"),
 | 
			
		||||
        events.once(ml.listenerArray[1], "update"),
 | 
			
		||||
        events.once(ml.listenerArray[2], "update"),
 | 
			
		||||
      ]);
 | 
			
		||||
 | 
			
		||||
      //expect
 | 
			
		||||
      expect(updateSpy).to.have.been.calledThrice;
 | 
			
		||||
      expect(newEntriesSpy).to.not.have.been.called;
 | 
			
		||||
 | 
			
		||||
      // here we're testing the second call for the first listener
 | 
			
		||||
      // given
 | 
			
		||||
      updateSpy.resetHistory();
 | 
			
		||||
      newEntriesSpy.resetHistory();
 | 
			
		||||
 | 
			
		||||
      tabChannelId.forEach((item: string) => {
 | 
			
		||||
        nock("https://www.youtube.com")
 | 
			
		||||
          .get(`/feeds/videos.xml?channel_id=${item}`)
 | 
			
		||||
          .replyWithFile(
 | 
			
		||||
            200,
 | 
			
		||||
            path.join(
 | 
			
		||||
              __dirname,
 | 
			
		||||
              `RessourcesTest/RealRessources/WithUpdate/${item}.rss`
 | 
			
		||||
            ),
 | 
			
		||||
            { "content-type": "text/xml", charset: "utf-8" }
 | 
			
		||||
          )
 | 
			
		||||
          .persist();
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      // when
 | 
			
		||||
      await clock.tickAsync(10000);
 | 
			
		||||
      await events.once(ml.listenerArray[0], "update");
 | 
			
		||||
 | 
			
		||||
      //expect
 | 
			
		||||
      expect(updateSpy).to.have.been.calledOnce;
 | 
			
		||||
      expect(newEntriesSpy).to.have.been.calledOnce;
 | 
			
		||||
 | 
			
		||||
      // here we're testing the thrid call for the first listener and second for the second listener
 | 
			
		||||
      // given
 | 
			
		||||
      updateSpy.resetHistory();
 | 
			
		||||
      newEntriesSpy.resetHistory();
 | 
			
		||||
 | 
			
		||||
      // when
 | 
			
		||||
      await clock.tickAsync(10000);
 | 
			
		||||
      await Promise.all([
 | 
			
		||||
        events.once(ml.listenerArray[0], "update"),
 | 
			
		||||
        events.once(ml.listenerArray[1], "update"),
 | 
			
		||||
      ]);
 | 
			
		||||
 | 
			
		||||
      //expect
 | 
			
		||||
      expect(updateSpy).to.have.been.calledTwice;
 | 
			
		||||
      expect(newEntriesSpy).to.have.been.calledOnce;
 | 
			
		||||
 | 
			
		||||
      // here we're testing the fourth call for the first listener and second for the third listener
 | 
			
		||||
      // given
 | 
			
		||||
      updateSpy.resetHistory();
 | 
			
		||||
      newEntriesSpy.resetHistory();
 | 
			
		||||
 | 
			
		||||
      // when
 | 
			
		||||
      await clock.tickAsync(10000);
 | 
			
		||||
      await Promise.all([
 | 
			
		||||
        events.once(ml.listenerArray[0], "update"),
 | 
			
		||||
        events.once(ml.listenerArray[2], "update"),
 | 
			
		||||
      ]);
 | 
			
		||||
 | 
			
		||||
      //expect
 | 
			
		||||
      expect(updateSpy).to.have.been.calledTwice;
 | 
			
		||||
      expect(newEntriesSpy).to.have.been.calledOnce;
 | 
			
		||||
 | 
			
		||||
      ml.stopAll();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it("should call correctly the events (with aggregation)", async function () {
 | 
			
		||||
      // given
 | 
			
		||||
      const clock = sinon.useFakeTimers();
 | 
			
		||||
      const ml = new ManageListener({
 | 
			
		||||
        timeloop: 30,
 | 
			
		||||
        path: "tests/RessourcesTest/RealRessources/save_no_history.json",
 | 
			
		||||
      });
 | 
			
		||||
    //   it("should call correctly the events (with aggregation)", async function () {
 | 
			
		||||
    //     // given
 | 
			
		||||
    //     const clock = sinon.useFakeTimers();
 | 
			
		||||
    //     const ml = new ManageListener({
 | 
			
		||||
    //       timeloop: 30,
 | 
			
		||||
    //       path: "tests/RessourcesTest/RealRessources/save_no_history.json",
 | 
			
		||||
    //     });
 | 
			
		||||
 | 
			
		||||
      const updateSpy = sinon.spy((obj) => console.log(obj));
 | 
			
		||||
      const newEntriesSpy = sinon.spy();
 | 
			
		||||
    //     const updateSpy = sinon.spy((obj) => console.log(obj));
 | 
			
		||||
    //     const newEntriesSpy = sinon.spy();
 | 
			
		||||
 | 
			
		||||
      const tabChannelId = [
 | 
			
		||||
        "UCOuIgj0CYCXCvjWywjDbauw",
 | 
			
		||||
        "UCh2YBKhYIy-_LtfCIn2Jycg",
 | 
			
		||||
        "UCY7klexd1qEqxgqYK6W7BVQ",
 | 
			
		||||
      ];
 | 
			
		||||
    //     const tabChannelId = [
 | 
			
		||||
    //       "UCOuIgj0CYCXCvjWywjDbauw",
 | 
			
		||||
    //       "UCh2YBKhYIy-_LtfCIn2Jycg",
 | 
			
		||||
    //       "UCY7klexd1qEqxgqYK6W7BVQ",
 | 
			
		||||
    //     ];
 | 
			
		||||
 | 
			
		||||
      ml.on("update", updateSpy);
 | 
			
		||||
      ml.on("newEntries", newEntriesSpy);
 | 
			
		||||
      tabChannelId.forEach((item: string) => {
 | 
			
		||||
        nock("https://www.youtube.com")
 | 
			
		||||
          .get(`/feeds/videos.xml?channel_id=${item}`)
 | 
			
		||||
          .replyWithFile(
 | 
			
		||||
            200,
 | 
			
		||||
            path.join(__dirname, `RessourcesTest/RealRessources/${item}.rss`),
 | 
			
		||||
            { "content-type": "text/xml", charset: "utf-8" }
 | 
			
		||||
          )
 | 
			
		||||
          .persist();
 | 
			
		||||
      });
 | 
			
		||||
      ml.startAll();
 | 
			
		||||
    //     ml.on("update", updateSpy);
 | 
			
		||||
    //     ml.on("newEntries", newEntriesSpy);
 | 
			
		||||
    //     tabChannelId.forEach((item: string) => {
 | 
			
		||||
    //       nock("https://www.youtube.com")
 | 
			
		||||
    //         .get(`/feeds/videos.xml?channel_id=${item}`)
 | 
			
		||||
    //         .replyWithFile(
 | 
			
		||||
    //           200,
 | 
			
		||||
    //           path.join(__dirname, `RessourcesTest/RealRessources/${item}.rss`),
 | 
			
		||||
    //           { "content-type": "text/xml", charset: "utf-8" }
 | 
			
		||||
    //         )
 | 
			
		||||
    //         .persist();
 | 
			
		||||
    //     });
 | 
			
		||||
    //     ml.startAll();
 | 
			
		||||
 | 
			
		||||
      // when
 | 
			
		||||
      await Promise.all([
 | 
			
		||||
        events.once(ml.listenerArray[0], "update"),
 | 
			
		||||
        events.once(ml.listenerArray[1], "update"),
 | 
			
		||||
        events.once(ml.listenerArray[2], "update"),
 | 
			
		||||
      ]);
 | 
			
		||||
    //     // when
 | 
			
		||||
    //     await Promise.all([
 | 
			
		||||
    //       events.once(ml.listenerArray[0], "update"),
 | 
			
		||||
    //       events.once(ml.listenerArray[1], "update"),
 | 
			
		||||
    //       events.once(ml.listenerArray[2], "update"),
 | 
			
		||||
    //     ]);
 | 
			
		||||
 | 
			
		||||
      //expect
 | 
			
		||||
      expect(updateSpy).to.have.been.calledOnce;
 | 
			
		||||
      expect(newEntriesSpy).to.have.been.calledOnce;
 | 
			
		||||
    //     //expect
 | 
			
		||||
    //     expect(updateSpy).to.have.been.calledOnce;
 | 
			
		||||
    //     expect(newEntriesSpy).to.have.been.calledOnce;
 | 
			
		||||
 | 
			
		||||
      // given
 | 
			
		||||
      updateSpy.resetHistory();
 | 
			
		||||
      newEntriesSpy.resetHistory();
 | 
			
		||||
    //     // given
 | 
			
		||||
    //     updateSpy.resetHistory();
 | 
			
		||||
    //     newEntriesSpy.resetHistory();
 | 
			
		||||
 | 
			
		||||
      // when
 | 
			
		||||
      await clock.tickAsync(10000);
 | 
			
		||||
      await events.once(ml.listenerArray[0], "update");
 | 
			
		||||
    //     // when
 | 
			
		||||
    //     await clock.tickAsync(10000);
 | 
			
		||||
    //     await events.once(ml.listenerArray[0], "update");
 | 
			
		||||
 | 
			
		||||
      //expect
 | 
			
		||||
      expect(updateSpy).to.not.have.been.called;
 | 
			
		||||
      expect(newEntriesSpy).to.not.have.been.called;
 | 
			
		||||
    //     //expect
 | 
			
		||||
    //     expect(updateSpy).to.not.have.been.called;
 | 
			
		||||
    //     expect(newEntriesSpy).to.not.have.been.called;
 | 
			
		||||
 | 
			
		||||
      // when
 | 
			
		||||
      await clock.tickAsync(10000);
 | 
			
		||||
      await Promise.all([
 | 
			
		||||
        events.once(ml.listenerArray[0], "update"),
 | 
			
		||||
        events.once(ml.listenerArray[1], "update"),
 | 
			
		||||
      ]);
 | 
			
		||||
    //     // when
 | 
			
		||||
    //     await clock.tickAsync(10000);
 | 
			
		||||
    //     await Promise.all([
 | 
			
		||||
    //       events.once(ml.listenerArray[0], "update"),
 | 
			
		||||
    //       events.once(ml.listenerArray[1], "update"),
 | 
			
		||||
    //     ]);
 | 
			
		||||
 | 
			
		||||
      //expect
 | 
			
		||||
      expect(updateSpy).to.not.have.been.called;
 | 
			
		||||
      expect(newEntriesSpy).to.not.have.been.called;
 | 
			
		||||
    //     //expect
 | 
			
		||||
    //     expect(updateSpy).to.not.have.been.called;
 | 
			
		||||
    //     expect(newEntriesSpy).to.not.have.been.called;
 | 
			
		||||
 | 
			
		||||
      // when
 | 
			
		||||
      await clock.tickAsync(10000);
 | 
			
		||||
      await Promise.all([
 | 
			
		||||
        events.once(ml.listenerArray[0], "update"),
 | 
			
		||||
        events.once(ml.listenerArray[2], "update"),
 | 
			
		||||
      ]);
 | 
			
		||||
    //     // when
 | 
			
		||||
    //     await clock.tickAsync(10000);
 | 
			
		||||
    //     await Promise.all([
 | 
			
		||||
    //       events.once(ml.listenerArray[0], "update"),
 | 
			
		||||
    //       events.once(ml.listenerArray[2], "update"),
 | 
			
		||||
    //     ]);
 | 
			
		||||
 | 
			
		||||
      //expect
 | 
			
		||||
      expect(updateSpy).to.have.been.calledOnce;
 | 
			
		||||
      expect(newEntriesSpy).to.not.have.been.called;
 | 
			
		||||
    //     //expect
 | 
			
		||||
    //     expect(updateSpy).to.have.been.calledOnce;
 | 
			
		||||
    //     expect(newEntriesSpy).to.not.have.been.called;
 | 
			
		||||
 | 
			
		||||
      ml.stopAll();
 | 
			
		||||
    });
 | 
			
		||||
    //     ml.stopAll();
 | 
			
		||||
    //   });
 | 
			
		||||
 | 
			
		||||
    it("should call correctly the events with a new entry (with aggregation)", async function () {
 | 
			
		||||
      // given
 | 
			
		||||
      const clock = sinon.useFakeTimers();
 | 
			
		||||
      const ml = new ManageListener({
 | 
			
		||||
        timeloop: 30,
 | 
			
		||||
        path: "tests/RessourcesTest/RealRessources/save.json",
 | 
			
		||||
      });
 | 
			
		||||
    //   it("should call correctly the events with a new entry (with aggregation)", async function () {
 | 
			
		||||
    //     // given
 | 
			
		||||
    //     const clock = sinon.useFakeTimers();
 | 
			
		||||
    //     const ml = new ManageListener({
 | 
			
		||||
    //       timeloop: 30,
 | 
			
		||||
    //       path: "tests/RessourcesTest/RealRessources/save.json",
 | 
			
		||||
    //     });
 | 
			
		||||
 | 
			
		||||
      const updateSpy = sinon.spy();
 | 
			
		||||
      const newEntriesSpy = sinon.spy();
 | 
			
		||||
    //     const updateSpy = sinon.spy();
 | 
			
		||||
    //     const newEntriesSpy = sinon.spy();
 | 
			
		||||
 | 
			
		||||
      const tabChannelId = [
 | 
			
		||||
        "UCOuIgj0CYCXCvjWywjDbauw",
 | 
			
		||||
        "UCh2YBKhYIy-_LtfCIn2Jycg",
 | 
			
		||||
        "UCY7klexd1qEqxgqYK6W7BVQ",
 | 
			
		||||
      ];
 | 
			
		||||
    //     const tabChannelId = [
 | 
			
		||||
    //       "UCOuIgj0CYCXCvjWywjDbauw",
 | 
			
		||||
    //       "UCh2YBKhYIy-_LtfCIn2Jycg",
 | 
			
		||||
    //       "UCY7klexd1qEqxgqYK6W7BVQ",
 | 
			
		||||
    //     ];
 | 
			
		||||
 | 
			
		||||
      ml.on("update", updateSpy);
 | 
			
		||||
      ml.on("newEntries", newEntriesSpy);
 | 
			
		||||
      tabChannelId.forEach((item: string) => {
 | 
			
		||||
        nock("https://www.youtube.com")
 | 
			
		||||
          .get(`/feeds/videos.xml?channel_id=${item}`)
 | 
			
		||||
          .once()
 | 
			
		||||
          .replyWithFile(
 | 
			
		||||
            200,
 | 
			
		||||
            path.join(__dirname, `RessourcesTest/RealRessources/${item}.rss`),
 | 
			
		||||
            { "content-type": "text/xml", charset: "utf-8" }
 | 
			
		||||
          );
 | 
			
		||||
      });
 | 
			
		||||
      ml.startAll();
 | 
			
		||||
    //     ml.on("update", updateSpy);
 | 
			
		||||
    //     ml.on("newEntries", newEntriesSpy);
 | 
			
		||||
    //     tabChannelId.forEach((item: string) => {
 | 
			
		||||
    //       nock("https://www.youtube.com")
 | 
			
		||||
    //         .get(`/feeds/videos.xml?channel_id=${item}`)
 | 
			
		||||
    //         .once()
 | 
			
		||||
    //         .replyWithFile(
 | 
			
		||||
    //           200,
 | 
			
		||||
    //           path.join(__dirname, `RessourcesTest/RealRessources/${item}.rss`),
 | 
			
		||||
    //           { "content-type": "text/xml", charset: "utf-8" }
 | 
			
		||||
    //         );
 | 
			
		||||
    //     });
 | 
			
		||||
    //     ml.startAll();
 | 
			
		||||
 | 
			
		||||
      // when
 | 
			
		||||
      await Promise.all([
 | 
			
		||||
        events.once(ml.listenerArray[0], "update"),
 | 
			
		||||
        events.once(ml.listenerArray[1], "update"),
 | 
			
		||||
        events.once(ml.listenerArray[2], "update"),
 | 
			
		||||
      ]);
 | 
			
		||||
    //     // when
 | 
			
		||||
    //     await Promise.all([
 | 
			
		||||
    //       events.once(ml.listenerArray[0], "update"),
 | 
			
		||||
    //       events.once(ml.listenerArray[1], "update"),
 | 
			
		||||
    //       events.once(ml.listenerArray[2], "update"),
 | 
			
		||||
    //     ]);
 | 
			
		||||
 | 
			
		||||
      //expect
 | 
			
		||||
      expect(updateSpy).to.have.been.calledOnce;
 | 
			
		||||
      expect(newEntriesSpy).to.not.have.been.called;
 | 
			
		||||
    //     //expect
 | 
			
		||||
    //     expect(updateSpy).to.have.been.calledOnce;
 | 
			
		||||
    //     expect(newEntriesSpy).to.not.have.been.called;
 | 
			
		||||
 | 
			
		||||
      // given
 | 
			
		||||
      updateSpy.resetHistory();
 | 
			
		||||
    //     // given
 | 
			
		||||
    //     updateSpy.resetHistory();
 | 
			
		||||
 | 
			
		||||
      tabChannelId.forEach((item: string) => {
 | 
			
		||||
        nock("https://www.youtube.com")
 | 
			
		||||
          .get(`/feeds/videos.xml?channel_id=${item}`)
 | 
			
		||||
          .replyWithFile(
 | 
			
		||||
            200,
 | 
			
		||||
            path.join(
 | 
			
		||||
              __dirname,
 | 
			
		||||
              `RessourcesTest/RealRessources/WithUpdate/${item}.rss`
 | 
			
		||||
            ),
 | 
			
		||||
            { "content-type": "text/xml", charset: "utf-8" }
 | 
			
		||||
          )
 | 
			
		||||
          .persist();
 | 
			
		||||
      });
 | 
			
		||||
    //     tabChannelId.forEach((item: string) => {
 | 
			
		||||
    //       nock("https://www.youtube.com")
 | 
			
		||||
    //         .get(`/feeds/videos.xml?channel_id=${item}`)
 | 
			
		||||
    //         .replyWithFile(
 | 
			
		||||
    //           200,
 | 
			
		||||
    //           path.join(
 | 
			
		||||
    //             __dirname,
 | 
			
		||||
    //             `RessourcesTest/RealRessources/WithUpdate/${item}.rss`
 | 
			
		||||
    //           ),
 | 
			
		||||
    //           { "content-type": "text/xml", charset: "utf-8" }
 | 
			
		||||
    //         )
 | 
			
		||||
    //         .persist();
 | 
			
		||||
    //     });
 | 
			
		||||
 | 
			
		||||
      // when
 | 
			
		||||
      await clock.tickAsync(10000);
 | 
			
		||||
      await events.once(ml.listenerArray[0], "update");
 | 
			
		||||
    //     // when
 | 
			
		||||
    //     await clock.tickAsync(10000);
 | 
			
		||||
    //     await events.once(ml.listenerArray[0], "update");
 | 
			
		||||
 | 
			
		||||
      //expect
 | 
			
		||||
      expect(updateSpy).to.not.have.been.called;
 | 
			
		||||
      expect(newEntriesSpy).to.not.have.been.called;
 | 
			
		||||
    //     //expect
 | 
			
		||||
    //     expect(updateSpy).to.not.have.been.called;
 | 
			
		||||
    //     expect(newEntriesSpy).to.not.have.been.called;
 | 
			
		||||
 | 
			
		||||
      // when
 | 
			
		||||
      await clock.tickAsync(10000);
 | 
			
		||||
      await Promise.all([
 | 
			
		||||
        events.once(ml.listenerArray[0], "update"),
 | 
			
		||||
        events.once(ml.listenerArray[1], "update"),
 | 
			
		||||
      ]);
 | 
			
		||||
    //     // when
 | 
			
		||||
    //     await clock.tickAsync(10000);
 | 
			
		||||
    //     await Promise.all([
 | 
			
		||||
    //       events.once(ml.listenerArray[0], "update"),
 | 
			
		||||
    //       events.once(ml.listenerArray[1], "update"),
 | 
			
		||||
    //     ]);
 | 
			
		||||
 | 
			
		||||
      //expect
 | 
			
		||||
      expect(updateSpy).to.not.have.been.called;
 | 
			
		||||
      expect(newEntriesSpy).to.not.have.been.called;
 | 
			
		||||
    //     //expect
 | 
			
		||||
    //     expect(updateSpy).to.not.have.been.called;
 | 
			
		||||
    //     expect(newEntriesSpy).to.not.have.been.called;
 | 
			
		||||
 | 
			
		||||
      // when
 | 
			
		||||
      await clock.tickAsync(10000);
 | 
			
		||||
      await Promise.all([
 | 
			
		||||
        events.once(ml.listenerArray[0], "update"),
 | 
			
		||||
        events.once(ml.listenerArray[2], "update"),
 | 
			
		||||
      ]);
 | 
			
		||||
    //     // when
 | 
			
		||||
    //     await clock.tickAsync(10000);
 | 
			
		||||
    //     await Promise.all([
 | 
			
		||||
    //       events.once(ml.listenerArray[0], "update"),
 | 
			
		||||
    //       events.once(ml.listenerArray[2], "update"),
 | 
			
		||||
    //     ]);
 | 
			
		||||
 | 
			
		||||
      //expect
 | 
			
		||||
      expect(updateSpy).to.have.been.calledOnce;
 | 
			
		||||
      expect(newEntriesSpy).to.have.been.calledOnce;
 | 
			
		||||
    //     //expect
 | 
			
		||||
    //     expect(updateSpy).to.have.been.calledOnce;
 | 
			
		||||
    //     expect(newEntriesSpy).to.have.been.calledOnce;
 | 
			
		||||
 | 
			
		||||
      ml.stopAll();
 | 
			
		||||
    });
 | 
			
		||||
    //     ml.stopAll();
 | 
			
		||||
    //   });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										54
									
								
								tests/sqlite-tools-spec.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								tests/sqlite-tools-spec.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
			
		||||
import { SqliteTools } from "../src/sqlite-tools";
 | 
			
		||||
import { ListenerRSSInfos } from "listener-rss";
 | 
			
		||||
 | 
			
		||||
// testing
 | 
			
		||||
import * as chai from "chai";
 | 
			
		||||
import sinon from "ts-sinon";
 | 
			
		||||
import sinonChai from "sinon-chai";
 | 
			
		||||
 | 
			
		||||
import { withFile } from "tmp-promise";
 | 
			
		||||
 | 
			
		||||
chai.use(sinonChai);
 | 
			
		||||
 | 
			
		||||
const expect = chai.expect;
 | 
			
		||||
 | 
			
		||||
const dataWithHistory: ListenerRSSInfos[] = require("./RessourcesTest/RealRessources/save.json");
 | 
			
		||||
const dataWithoutHistory = dataWithHistory.map((data) => ({
 | 
			
		||||
  ...data,
 | 
			
		||||
  lastEntriesLinks: [],
 | 
			
		||||
}));
 | 
			
		||||
describe("test sqlite tools class", () => {
 | 
			
		||||
  it("should create a .db file and fill him", async () => {
 | 
			
		||||
    await withFile(async ({ path }) => {
 | 
			
		||||
      // given
 | 
			
		||||
      const dbTools = new SqliteTools(path);
 | 
			
		||||
      await dbTools.ensureTableExists();
 | 
			
		||||
 | 
			
		||||
      // when
 | 
			
		||||
      const oldValues: ListenerRSSInfos[] = await dbTools.fetchAll();
 | 
			
		||||
      for (const item of dataWithoutHistory) await dbTools.insertListener(item);
 | 
			
		||||
      const newValues: ListenerRSSInfos[] = await dbTools.fetchAll();
 | 
			
		||||
 | 
			
		||||
      // expect
 | 
			
		||||
      expect(oldValues).to.be.empty;
 | 
			
		||||
      expect(newValues).to.have.lengthOf(3);
 | 
			
		||||
 | 
			
		||||
      expect(newValues).to.be.eql(dataWithoutHistory);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  it("should update the values of the databases", async () => {
 | 
			
		||||
    await withFile(async ({ path }) => {
 | 
			
		||||
      // given
 | 
			
		||||
      const dbTools = new SqliteTools(path);
 | 
			
		||||
      await dbTools.ensureTableExists();
 | 
			
		||||
      for (const item of dataWithoutHistory) await dbTools.insertListener(item);
 | 
			
		||||
 | 
			
		||||
      //when
 | 
			
		||||
      await dbTools.updateAll(dataWithHistory);
 | 
			
		||||
      const values: ListenerRSSInfos[] = await dbTools.fetchAll();
 | 
			
		||||
 | 
			
		||||
      expect(values).to.be.eql(dataWithHistory);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
{
 | 
			
		||||
  "compilerOptions": {
 | 
			
		||||
    "target": "es2018",
 | 
			
		||||
    "module": "es2015",
 | 
			
		||||
    "module": "commonjs",
 | 
			
		||||
    "lib": ["es6"],
 | 
			
		||||
    "allowJs": true,
 | 
			
		||||
    "outDir": "build",
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user