+
+
+
+
+
+
+
+
+
+
+
+`
\ No newline at end of file
diff --git a/backend/src/adapters/driven/http/steam.client.js b/backend/src/adapters/driven/http/steam.client.js
index cedacef66..f04dd2b33 100644
--- a/backend/src/adapters/driven/http/steam.client.js
+++ b/backend/src/adapters/driven/http/steam.client.js
@@ -1,4 +1,5 @@
import { SteamApp } from "../../../core/models/steam.app.js";
+import { ValidDataSources } from "../../../core/models/valid.data.sources.js";
export class SteamClient {
#httpClient;
@@ -33,38 +34,27 @@ export class SteamClient {
).map((player) => (player ? player.data.response.player_count : 0));
}
- async getSteamAppHtmlDetailsPage(id) {
- // TODO https://github.com/lukatarman/steam-game-stats/issues/192
- // We add the try catch block here to not crash the whole backend when our application comes accross
- // errors written into the Steam API
- try {
- const url = `https://store.steampowered.com/app/${id}`;
-
- return (await this.#httpClient.get(url)).data;
- } catch (err) {
- return "";
- }
- }
+ // TODO https://github.com/lukatarman/steam-game-stats/issues/192
+ async getSourceHtmlDetailsPage(id, source) {
+ const url = this.getSourceUrl(id, source);
- async getSteamchartsGameHtmlDetailsPage(id) {
- // TODO https://github.com/lukatarman/steam-game-stats/issues/192
try {
- const url = `https://steamcharts.com/app/${id}`;
-
return (await this.#httpClient.get(url)).data;
} catch (err) {
return "";
}
}
- async getSteamDbHtmlDetailsPage(id) {
- // TODO https://github.com/lukatarman/steam-game-stats/issues/192
- try {
- const url = `https://steamdb.info/app/${id}/info/`;
+ getSourceUrl(id, source) {
+ switch (source) {
+ case ValidDataSources.validDataSources.steamWeb:
+ return `https://store.steampowered.com/app/${id}`;
- return (await this.#httpClient.get(url)).data;
- } catch (error) {
- return "";
+ case ValidDataSources.validDataSources.steacharts:
+ return `https://steamcharts.com/app/${id}`;
+
+ case ValidDataSources.validDataSources.steamDb:
+ return `https://steamdb.info/app/${id}/info/`;
}
}
}
diff --git a/backend/src/core/features/game-identifier/game.identifier.js b/backend/src/core/features/game-identifier/game.identifier.js
index 571c93574..d778c5273 100644
--- a/backend/src/core/features/game-identifier/game.identifier.js
+++ b/backend/src/core/features/game-identifier/game.identifier.js
@@ -1,14 +1,6 @@
-import {
- discoverGamesFromSteamWeb,
- updateTypeSideEffectFree,
- identifyGames,
- assignType,
- updateMissingDetails,
- updateMissingReleaseDates,
- recordAttemptsViaSteamDb,
-} from "../../services/game.service.js";
import { delay } from "../../../common/time.utils.js";
import { HistoryCheck } from "../../models/history.check.js";
+import { ValidDataSources } from "../../models/valid.data.sources.js";
export class GameIdentifier {
#steamClient;
@@ -17,6 +9,7 @@ export class GameIdentifier {
#historyChecksRepository;
#logger;
#options;
+ #htmlParser;
constructor(
steamClient,
@@ -25,6 +18,7 @@ export class GameIdentifier {
historyChecksRepository,
logger,
options,
+ htmlParser,
) {
this.#steamClient = steamClient;
this.#steamAppsRepository = steamAppsRepository;
@@ -32,196 +26,147 @@ export class GameIdentifier {
this.#historyChecksRepository = historyChecksRepository;
this.#logger = logger;
this.#options = options;
+ this.#htmlParser = htmlParser;
}
- tryViaSteamWeb = async () => {
- this.#logger.debugc("identifying games via steam web");
+ checkIfGameViaSource = async (source) => {
+ this.#logger.debugc(`identifying games via ${source}`);
- const steamApps = await this.#steamAppsRepository.getSteamWebUntriedFilteredSteamApps(
+ const steamApps = await this.#steamAppsRepository.getSourceUntriedFilteredSteamApps(
this.#options.batchSize,
+ source,
);
- if (steamApps.length === 0) {
+
+ if (steamApps.isEmpty) {
this.#logger.debugc(
`no steam apps in db, retry in: ${this.#options.globalIterationDelay} ms`,
);
+
return;
}
- const [games, updatedSteamApps] = await this.#identifyViaSteamWeb(steamApps);
-
- this.#persist(games, updatedSteamApps);
- };
+ const htmlDetailsPages = await this.#getSteamAppsHtmlDetailsPages(
+ steamApps.content,
+ source,
+ );
- async #identifyViaSteamWeb(steamApps) {
- const htmlDetailsPages = await this.#getSteamAppsHtmlDetailsPages(steamApps);
+ steamApps.identifyTypes(htmlDetailsPages, source);
- const games = discoverGamesFromSteamWeb(steamApps, htmlDetailsPages);
+ const games = steamApps.extractGames(htmlDetailsPages, source);
- const updatedSteamApps = updateTypeSideEffectFree(steamApps, htmlDetailsPages);
+ await this.#persistGameCheckUpdates(games, steamApps.content);
+ };
- return [games, updatedSteamApps];
- }
+ async #getSteamAppsHtmlDetailsPages(steamApps, source) {
+ const htmlDetailsPages = [];
- async #getSteamAppsHtmlDetailsPages(steamApps) {
- const detailsPages = [];
for (let steamApp of steamApps) {
- detailsPages.push(
- // TODO https://github.com/lukatarman/steam-game-stats/issues/192
- await this.#steamClient.getSteamAppHtmlDetailsPage(steamApp.appid),
+ // TODO https://github.com/lukatarman/steam-game-stats/issues/192
+ const htmlPage = await this.#steamClient.getSourceHtmlDetailsPage(
+ steamApp.appid,
+ source,
);
+
+ htmlDetailsPages.push({
+ page: this.#htmlParser(htmlPage).document,
+ id: steamApp.appid,
+ });
+
await delay(this.#options.unitDelay);
}
- return detailsPages;
+
+ return htmlDetailsPages;
}
- async #persist(games, updatedSteamApps) {
+ async #persistGameCheckUpdates(games, steamApps) {
if (games.length !== 0) {
this.#logger.debugc(`persiting ${games.length} identified games`);
+
await this.#gamesRepository.insertManyGames(games);
await this.#historyChecksRepository.insertManyHistoryChecks(
HistoryCheck.manyFromGames(games),
);
}
- await this.#steamAppsRepository.updateSteamAppsById(updatedSteamApps);
- }
-
- tryViaSteamchartsWeb = async () => {
- this.#logger.debugc("identifying games via steamcharts web");
-
- const steamApps =
- await this.#steamAppsRepository.getSteamchartsUntriedFilteredSteamApps(
- this.#options.batchSize,
- );
- if (steamApps.length === 0) {
- this.#logger.debugc(
- `no steam apps in db, retry in: ${this.#options.globalIterationDelay} ms`,
- );
- return;
- }
- const updatedSteamApps = await this.#updateStatusViaSteamchartsWeb(steamApps);
- const games = identifyGames(updatedSteamApps);
-
- this.#persist(games, updatedSteamApps);
- };
-
- // this method is a mess right now, including the tests. Will be fixed in issue: #198
- async #updateStatusViaSteamchartsWeb(steamApps) {
- const updatedSteamApps = [];
-
- for (let steamApp of steamApps) {
- const steamAppCopy = steamApp.copy();
- steamAppCopy.triedViaSteamchartsWeb();
-
- // TODO https://github.com/lukatarman/steam-game-stats/issues/192
- const result = await this.#steamClient.getSteamchartsGameHtmlDetailsPage(
- steamApp.appid,
- );
-
- if (result === "") {
- steamAppCopy.failedViaSteamchartsWeb();
- this.#logger.debugc(`no entry on steamcharts web for appid: ${steamApp.appid}`);
- }
-
- assignType(result, steamAppCopy);
-
- await delay(this.#options.unitDelay);
- updatedSteamApps.push(steamAppCopy);
- }
-
- return updatedSteamApps;
+ await this.#steamAppsRepository.updateSteamAppsById(steamApps);
}
updateGamesWithoutDetails = async () => {
+ const source = ValidDataSources.validDataSources.steamDb;
this.#logger.debugc("updating games without details");
const games = await this.#gamesRepository.getGamesWithoutDetails(
this.#options.batchSize,
);
- if (games.length === 0) {
+ if (games.isEmpty) {
this.#logger.debugc(
- `no games without details in db, retrying in ${
+ `no games without details in db, retry in: ${
this.#options.globalIterationDelay
} ms`,
);
return;
}
- const steamApps = await this.#steamAppsRepository.getSteamAppsById(
- games.map((game) => game.id),
- );
+ const steamApps = await this.#steamAppsRepository.getSteamAppsById(games.ids);
- const htmlDetailsPages = await this.#getSteamDbHtmlDetailsPages(games);
+ const htmlDetailsPages = await this.#getSteamAppsHtmlDetailsPages(
+ steamApps.content,
+ source,
+ );
- const updatedApps = recordAttemptsViaSteamDb(steamApps, htmlDetailsPages);
+ steamApps.recordAttemptsViaSource(htmlDetailsPages, source);
- updateMissingDetails(games, htmlDetailsPages);
+ games.updateGameDetailsFrom(htmlDetailsPages);
- this.#persistMissingProperties(games, updatedApps);
+ this.#persistUpdatedDetails(games.content, steamApps.content);
};
- async #getSteamDbHtmlDetailsPages(games) {
- const htmlDetailsPages = [];
-
- for (let game of games) {
- // TODO https://github.com/lukatarman/steam-game-stats/issues/192
- const htmlPage = await this.#steamClient.getSteamDbHtmlDetailsPage(game.id);
- htmlDetailsPages.push({ page: htmlPage, id: game.id });
-
- await delay(this.#options.unitDelay);
- }
-
- return htmlDetailsPages;
- }
-
- async #persistMissingProperties(games, appsWithoutPages) {
- if (appsWithoutPages.length !== 0) {
- this.#logger.debugc(`persisting ${appsWithoutPages.length} apps without pages`);
- this.#steamAppsRepository.updateSteamAppsById(appsWithoutPages);
- }
-
+ async #persistUpdatedDetails(games, steamApps) {
+ this.#logger.debugc(`persisting ${steamApps.length} apps with updated html attempts`);
this.#logger.debugc(`persisting ${games.length} games with updated details`);
- await this.#gamesRepository.updateGameDetails(games);
+
+ await this.#steamAppsRepository.updateSteamAppsById(steamApps);
+ await this.#gamesRepository.updateGameDetailsFrom(games);
}
updateGamesWithoutReleaseDates = async () => {
- this.#logger.debugc("updating games without details");
+ const source = ValidDataSources.validDataSources.steamDb;
+ this.#logger.debugc(`updating games without release dates via ${source}`);
const games = await this.#gamesRepository.getGamesWithoutReleaseDates(
this.#options.batchSize,
);
- if (games.length === 0) {
+ if (games.isEmpty) {
this.#logger.debugc(
- `no games without release dates in db, retrying in ${
- this.#options.iterationDelay
+ `no games without release dates in db, retry in: ${
+ this.#options.globalIterationDelay
} ms`,
);
+
return;
}
- const steamApps = await this.#steamAppsRepository.getSteamAppsById(
- games.map((game) => game.id),
- );
+ const steamApps = await this.#steamAppsRepository.getSteamAppsById(games.ids);
- const htmlDetailsPages = await this.#getSteamDbHtmlDetailsPages(games);
+ const htmlDetailsPages = await this.#getSteamAppsHtmlDetailsPages(
+ steamApps.content,
+ source,
+ );
- const updatedApps = recordAttemptsViaSteamDb(steamApps, htmlDetailsPages);
+ steamApps.recordAttemptsViaSource(htmlDetailsPages, source);
- updateMissingReleaseDates(games, htmlDetailsPages);
+ games.extractReleaseDatesFrom(htmlDetailsPages);
- this.#persistReleaseDates(games, updatedApps);
+ this.#persistReleaseDates(games.content, steamApps.content);
};
- #persistReleaseDates = async (games, appsWithoutPages) => {
- if (appsWithoutPages.length !== 0) {
- this.#logger.debugc(`persisting ${appsWithoutPages.length} apps without pages`);
- this.#steamAppsRepository.updateSteamAppsById(appsWithoutPages);
- }
-
+ async #persistReleaseDates(games, steamApps) {
+ this.#logger.debugc(`persisting ${steamApps.length} apps with updated html attempts`);
this.#logger.debugc(`persisting ${games.length} games with updated release dates`);
+ await this.#steamAppsRepository.updateSteamAppsById(steamApps);
await this.#gamesRepository.updateReleaseDates(games);
- };
+ }
}
diff --git a/backend/src/core/features/game-identifier/game.identifier.spec.js b/backend/src/core/features/game-identifier/game.identifier.spec.js
index 440543149..682501cd3 100644
--- a/backend/src/core/features/game-identifier/game.identifier.spec.js
+++ b/backend/src/core/features/game-identifier/game.identifier.spec.js
@@ -1,15 +1,4 @@
import { GameIdentifier } from "./game.identifier.js";
-import { animaddicts2gameHtmlDetailsPage } from "../../../../assets/steam-details-pages/animaddicts.2.game.html.details.page.js";
-import { glitchhikersSoundtrackHtmlDetailsPage } from "../../../../assets/steam-details-pages/glitchhikers.soundtrack.html.details.page.js";
-import { eldenRingHttpDetailsSteamcharts } from "../../../../assets/steamcharts-details-pages/elden.ring.multiple.histories.html.details.page.js";
-import { SteamApp } from "../../models/steam.app.js";
-import {
- discoverGamesFromSteamWeb,
- identifyGames,
- recordAttemptsViaSteamDb,
- updateMissingReleaseDates,
- updateTypeSideEffectFree,
-} from "../../services/game.service.js";
import { HistoryCheck } from "../../models/history.check.js";
import { createLoggerMock } from "../../../common/logger.mock.js";
import { counterStrikeHtmlDetailsSteamDb } from "../../../../assets/steamdb-details-pages/counter.strike.html.details.page.js";
@@ -17,699 +6,494 @@ import { riskOfRainHtmlDetailsSteamDb } from "../../../../assets/steamdb-details
import { getXGamesWithoutDetails } from "../../models/game.mocks.js";
import { createConfigMock } from "../../../common/config.loader.mock.js";
import { getXSampleSteamApps } from "../../models/steam.app.mocks.js";
-import { createHtmlDetailsPages } from "../../../../assets/html.details.pages.mock.js";
+import { ValidDataSources } from "../../models/valid.data.sources.js";
+import { gta5ageRestrictedHtmlDetailsPage } from "../../../../assets/steam-details-pages/gta.5.age.restricted.html.details.page.js";
+import { theSims4dlcHtmlDetailsPage } from "../../../../assets/steam-details-pages/the.sims.4.dlc.html.details.page.js";
+import { getParsedHtmlPages } from "../../../../assets/html.details.pages.mock.js";
+import { mortalDarknessGameHtmlDetailsPage } from "../../../../assets/steam-details-pages/mortal.darkness.game.html.details.page.js";
+import { SteamAppsAggregate } from "../../models/steam.apps.aggregate.js";
+import { GamesAggregate } from "../../models/games.aggregate.js";
+import { parseHTML } from "linkedom";
describe("game.identifier.js", function () {
- describe(".tryViaSteamWeb", function () {
- describe("gets zero steamApps from the database and stops. So,", function () {
- beforeAll(async function () {
- this.steamClientMock = createSteamMock([undefined]);
-
- this.steamAppsRepository = createSteamAppsRepositoryMock([], undefined);
- this.gamesRepository = createGamesRepositoryMock();
- this.historyChecksRepository = createHistoryChecksRepositoryMock();
+ describe(".checkIfGameViaSource.", function () {
+ describe("via SteamWeb", function () {
+ describe("Finds no unidentified steam apps in the database", function () {
+ beforeAll(async function () {
+ this.source = ValidDataSources.validDataSources.steamWeb;
+ this.steamClient = createSteamMock([]);
+ this.steamAppsRepository = createSteamAppsRepositoryMock(
+ [],
+ new SteamAppsAggregate([]),
+ );
+ this.gamesRepository = createGamesRepositoryMock([]);
+ this.historyChecksRepository = createHistoryChecksRepositoryMock();
- this.identifier = new GameIdentifier(
- this.steamClientMock,
- this.steamAppsRepository,
- this.gamesRepository,
- this.historyChecksRepository,
- createLoggerMock(),
- createConfigMock().features,
- );
+ this.identifier = new GameIdentifier(
+ this.steamClient,
+ this.steamAppsRepository,
+ this.gamesRepository,
+ this.historyChecksRepository,
+ createLoggerMock(),
+ createConfigMock().features,
+ parseHTML,
+ );
- await this.identifier.tryViaSteamWeb();
- });
+ await this.identifier.checkIfGameViaSource(this.source);
+ });
- it("getSteamWebUntriedFilteredSteamApps was called once", function () {
- expect(
- this.steamAppsRepository.getSteamWebUntriedFilteredSteamApps,
- ).toHaveBeenCalledTimes(1);
- });
+ it("getSourceUntriedFilteredSteamApps was called once", function () {
+ expect(
+ this.steamAppsRepository.getSourceUntriedFilteredSteamApps,
+ ).toHaveBeenCalledTimes(1);
+ });
- it("getSteamWebUntriedFilteredSteamApps was called with the correct batch size", function () {
- expect(
- this.steamAppsRepository.getSteamWebUntriedFilteredSteamApps,
- ).toHaveBeenCalledWith(1);
- });
+ it("getSourceUntriedFilteredSteamApps was called with the correct arguments", function () {
+ expect(
+ this.steamAppsRepository.getSourceUntriedFilteredSteamApps,
+ ).toHaveBeenCalledWith(1, this.source);
+ });
- it("getSteamAppHtmlDetailsPage was not called", function () {
- expect(this.steamClientMock.getSteamAppHtmlDetailsPage).toHaveBeenCalledTimes(0);
- });
+ it("getSourceHtmlDetailsPage was not called", function () {
+ expect(this.steamClient.getSourceHtmlDetailsPage).toHaveBeenCalledTimes(0);
+ });
- it("insertManyGames was not called", function () {
- expect(this.gamesRepository.insertManyGames).toHaveBeenCalledTimes(0);
- });
+ it("insertManyGames was not called", function () {
+ expect(this.gamesRepository.insertManyGames).toHaveBeenCalledTimes(0);
+ });
- it("insertManyHistoryChecks was not called", function () {
- expect(
- this.historyChecksRepository.insertManyHistoryChecks,
- ).toHaveBeenCalledTimes(0);
- });
+ it("insertManyHistoryChecks was not called", function () {
+ expect(
+ this.historyChecksRepository.insertManyHistoryChecks,
+ ).toHaveBeenCalledTimes(0);
+ });
- it("updateSteamAppsById was not called", function () {
- expect(this.steamAppsRepository.updateSteamAppsById).toHaveBeenCalledTimes(0);
+ it("updateSteamAppsById was not called", function () {
+ expect(this.steamAppsRepository.updateSteamAppsById).toHaveBeenCalledTimes(0);
+ });
});
- });
- describe("gets one game out of a batch of one steamApp, and inserts it into the database. So,", function () {
- beforeAll(async function () {
- this.app = getXSampleSteamApps(1);
+ describe("Finds two unidentified steam apps in the database, none of them being games", function () {
+ beforeAll(async function () {
+ this.steamApps = new SteamAppsAggregate(getXSampleSteamApps(2));
- this.games = discoverGamesFromSteamWeb(this.app, [
- animaddicts2gameHtmlDetailsPage,
- ]);
+ this.source = ValidDataSources.validDataSources.steamWeb;
- this.historychecks = HistoryCheck.manyFromGames(this.games);
+ const htmlDetailsPages = [
+ gta5ageRestrictedHtmlDetailsPage,
+ theSims4dlcHtmlDetailsPage,
+ ];
- this.instantiatedApp = SteamApp.manyFromSteamApi(this.app);
+ const parsedHtmlPages = getParsedHtmlPages(htmlDetailsPages);
- this.updatedSteamApps = updateTypeSideEffectFree(this.instantiatedApp, [
- animaddicts2gameHtmlDetailsPage,
- ]);
+ this.steamApps.identifyTypes(parsedHtmlPages, this.source);
- this.steamClientMock = createSteamMock([animaddicts2gameHtmlDetailsPage]);
+ this.games = this.steamApps.extractGames(parsedHtmlPages, this.source);
- this.steamAppsRepository = createSteamAppsRepositoryMock(
- this.instantiatedApp,
- undefined,
- );
- this.gamesRepository = createGamesRepositoryMock();
- this.historyChecksRepository = createHistoryChecksRepositoryMock();
+ this.historyChecks = HistoryCheck.manyFromGames(this.games);
- this.identifier = new GameIdentifier(
- this.steamClientMock,
- this.steamAppsRepository,
- this.gamesRepository,
- this.historyChecksRepository,
- createLoggerMock(),
- createConfigMock().features,
- );
+ this.steamClient = createSteamMock(htmlDetailsPages);
+ this.steamAppsRepository = createSteamAppsRepositoryMock(
+ undefined,
+ this.steamApps,
+ );
+ this.gamesRepository = createGamesRepositoryMock();
+ this.historyChecksRepository = createHistoryChecksRepositoryMock();
- await this.identifier.tryViaSteamWeb();
- });
+ this.identifier = new GameIdentifier(
+ this.steamClient,
+ this.steamAppsRepository,
+ this.gamesRepository,
+ this.historyChecksRepository,
+ createLoggerMock(),
+ createConfigMock().features,
+ parseHTML,
+ );
- it("getSteamWebUntriedFilteredSteamApps was called once", function () {
- expect(
- this.steamAppsRepository.getSteamWebUntriedFilteredSteamApps,
- ).toHaveBeenCalledTimes(1);
- });
+ await this.identifier.checkIfGameViaSource(this.source);
+ });
- it("getSteamWebUntriedFilteredSteamApps was called with the correct batch size", function () {
- expect(
- this.steamAppsRepository.getSteamWebUntriedFilteredSteamApps,
- ).toHaveBeenCalledWith(1);
- });
+ it("getSourceUntriedFilteredSteamApps was called once", function () {
+ expect(
+ this.steamAppsRepository.getSourceUntriedFilteredSteamApps,
+ ).toHaveBeenCalledTimes(1);
+ });
- it("getSteamWebUntriedFilteredSteamApps was called before getSteamAppHtmlDetailsPage", function () {
- expect(
- this.steamAppsRepository.getSteamWebUntriedFilteredSteamApps,
- ).toHaveBeenCalledBefore(this.steamClientMock.getSteamAppHtmlDetailsPage);
- });
+ it("getSourceUntriedFilteredSteamApps was called with the correct arguments", function () {
+ expect(
+ this.steamAppsRepository.getSourceUntriedFilteredSteamApps,
+ ).toHaveBeenCalledWith(1, this.source);
+ });
- it("getSteamAppHtmlDetailsPage was called once", function () {
- expect(this.steamClientMock.getSteamAppHtmlDetailsPage).toHaveBeenCalledTimes(1);
- });
+ it("getSourceHtmlDetailsPage was called twice", function () {
+ expect(this.steamClient.getSourceHtmlDetailsPage).toHaveBeenCalledTimes(2);
+ });
- it("getSteamAppHtmlDetailsPage was called with the correct id", function () {
- expect(this.steamClientMock.getSteamAppHtmlDetailsPage).toHaveBeenCalledWith(
- this.instantiatedApp[0].appid,
- );
- });
+ it("getSourceHtmlDetailsPage was called with the correct arguments", function () {
+ expect(this.steamClient.getSourceHtmlDetailsPage).toHaveBeenCalledWith(
+ this.steamApps.content[0].appid,
+ this.source,
+ );
+ expect(this.steamClient.getSourceHtmlDetailsPage).toHaveBeenCalledWith(
+ this.steamApps.content[1].appid,
+ this.source,
+ );
+ });
- it("getSteamAppHtmlDetailsPage was called before insertManyGames", function () {
- expect(this.steamClientMock.getSteamAppHtmlDetailsPage).toHaveBeenCalledBefore(
- this.gamesRepository.insertManyGames,
- );
- });
+ it("insertManyGames was not called", function () {
+ expect(this.gamesRepository.insertManyGames).toHaveBeenCalledTimes(0);
+ });
- it("insertManyGames was called once", function () {
- expect(this.gamesRepository.insertManyGames).toHaveBeenCalledTimes(1);
- });
+ it("insertManyHistoryChecks was not called", function () {
+ expect(
+ this.historyChecksRepository.insertManyHistoryChecks,
+ ).toHaveBeenCalledTimes(0);
+ });
- it("insertManyGames was called with the correct games", function () {
- expect(this.gamesRepository.insertManyGames).toHaveBeenCalledWith(this.games);
- });
+ it("updateSteamAppsById was called once", function () {
+ expect(this.steamAppsRepository.updateSteamAppsById).toHaveBeenCalledTimes(1);
+ });
- it("insertManyGames was called before insertManyHistoryChecks", function () {
- expect(this.gamesRepository.insertManyGames).toHaveBeenCalledBefore(
- this.historyChecksRepository.insertManyHistoryChecks,
- );
+ it("updateSteamAppsById was called with the correct argument", function () {
+ expect(this.steamAppsRepository.updateSteamAppsById).toHaveBeenCalledWith(
+ this.steamApps.content,
+ );
+ });
});
- it("insertManyHistoryChecks was called once", function () {
- expect(
- this.historyChecksRepository.insertManyHistoryChecks,
- ).toHaveBeenCalledTimes(1);
- });
+ describe("Finds two unidentified steam apps in the database, one of them being a game", function () {
+ beforeAll(async function () {
+ this.steamApps = new SteamAppsAggregate(getXSampleSteamApps(2));
- it("insertManyHistoryChecks was called with the correct history checks", function () {
- expect(this.historyChecksRepository.insertManyHistoryChecks).toHaveBeenCalledWith(
- this.historychecks,
- );
- });
+ this.source = ValidDataSources.validDataSources.steamWeb;
- it("insertManyHistoryChecks was called before updateSteamAppsById", function () {
- expect(
- this.historyChecksRepository.insertManyHistoryChecks,
- ).toHaveBeenCalledBefore(this.steamAppsRepository.updateSteamAppsById);
- });
+ const htmlDetailsPages = [
+ mortalDarknessGameHtmlDetailsPage,
+ gta5ageRestrictedHtmlDetailsPage,
+ ];
- it("updateSteamAppsById was called once", function () {
- expect(this.steamAppsRepository.updateSteamAppsById).toHaveBeenCalledTimes(1);
- });
+ const parsedHtmlPages = getParsedHtmlPages(htmlDetailsPages);
- it("updateSteamAppsById was called with the correct steam apps", function () {
- expect(this.steamAppsRepository.updateSteamAppsById).toHaveBeenCalledWith(
- this.updatedSteamApps,
- );
- });
- });
+ this.steamApps.identifyTypes(parsedHtmlPages, this.source);
- describe("gets one game out of a batch of two steamApps, and inserts it into the database. So,", function () {
- beforeAll(async function () {
- this.apps = getXSampleSteamApps(2);
+ this.games = this.steamApps.extractGames(parsedHtmlPages, this.source);
- this.htmlDetailsPages = [
- animaddicts2gameHtmlDetailsPage,
- glitchhikersSoundtrackHtmlDetailsPage,
- ];
+ this.historyChecks = HistoryCheck.manyFromGames(this.games);
- this.games = discoverGamesFromSteamWeb(this.apps, this.htmlDetailsPages);
+ this.steamClient = createSteamMock(htmlDetailsPages);
+ this.steamAppsRepository = createSteamAppsRepositoryMock(
+ undefined,
+ this.steamApps,
+ );
+ this.gamesRepository = createGamesRepositoryMock();
+ this.historyChecksRepository = createHistoryChecksRepositoryMock();
- this.historychecks = HistoryCheck.manyFromGames(this.games);
+ this.identifier = new GameIdentifier(
+ this.steamClient,
+ this.steamAppsRepository,
+ this.gamesRepository,
+ this.historyChecksRepository,
+ createLoggerMock(),
+ createConfigMock().features,
+ parseHTML,
+ );
- this.instantiatedApps = SteamApp.manyFromSteamApi(this.apps);
+ await this.identifier.checkIfGameViaSource(this.source);
+ });
- this.updatedSteamApps = updateTypeSideEffectFree(
- this.instantiatedApps,
- this.htmlDetailsPages,
- );
+ it("getSourceUntriedFilteredSteamApps was called once", function () {
+ expect(
+ this.steamAppsRepository.getSourceUntriedFilteredSteamApps,
+ ).toHaveBeenCalledTimes(1);
+ });
- this.steamClientMock = createSteamMock([
- animaddicts2gameHtmlDetailsPage,
- glitchhikersSoundtrackHtmlDetailsPage,
- ]);
+ it("getSourceUntriedFilteredSteamApps was called with the correct arguments", function () {
+ expect(
+ this.steamAppsRepository.getSourceUntriedFilteredSteamApps,
+ ).toHaveBeenCalledWith(1, this.source);
+ });
- this.steamAppsRepository = createSteamAppsRepositoryMock(
- this.instantiatedApps,
- undefined,
- );
- this.gamesRepository = createGamesRepositoryMock();
- this.historyChecksRepository = createHistoryChecksRepositoryMock();
+ it("getSourceHtmlDetailsPage was called twice", function () {
+ expect(this.steamClient.getSourceHtmlDetailsPage).toHaveBeenCalledTimes(2);
+ });
- this.identifier = new GameIdentifier(
- this.steamClientMock,
- this.steamAppsRepository,
- this.gamesRepository,
- this.historyChecksRepository,
- createLoggerMock(),
- createConfigMock().features,
- );
+ it("getSourceHtmlDetailsPage was called with the correct arguments", function () {
+ expect(this.steamClient.getSourceHtmlDetailsPage).toHaveBeenCalledWith(
+ this.steamApps.content[0].appid,
+ this.source,
+ );
+ expect(this.steamClient.getSourceHtmlDetailsPage).toHaveBeenCalledWith(
+ this.steamApps.content[1].appid,
+ this.source,
+ );
+ });
- await this.identifier.tryViaSteamWeb();
- });
+ it("insertManyGames was called once", function () {
+ expect(this.gamesRepository.insertManyGames).toHaveBeenCalledTimes(1);
+ });
- it("getSteamWebUntriedFilteredSteamApps was called once", function () {
- expect(
- this.steamAppsRepository.getSteamWebUntriedFilteredSteamApps,
- ).toHaveBeenCalledTimes(1);
- });
+ it("insertManyGames was called with the correct argument", function () {
+ expect(this.gamesRepository.insertManyGames).toHaveBeenCalledWith(this.games);
+ });
- it("getSteamWebUntriedFilteredSteamApps was called with the correct batch size", function () {
- expect(
- this.steamAppsRepository.getSteamWebUntriedFilteredSteamApps,
- ).toHaveBeenCalledWith(1);
- });
+ it("insertManyHistoryChecks was called once", function () {
+ expect(
+ this.historyChecksRepository.insertManyHistoryChecks,
+ ).toHaveBeenCalledTimes(1);
+ });
- it("getSteamWebUntriedFilteredSteamApps was called before getSteamAppHtmlDetailsPage", function () {
- expect(
- this.steamAppsRepository.getSteamWebUntriedFilteredSteamApps,
- ).toHaveBeenCalledBefore(this.steamClientMock.getSteamAppHtmlDetailsPage);
- });
+ it("insertManyHistoryChecks was called with the correct argument", function () {
+ expect(
+ this.historyChecksRepository.insertManyHistoryChecks,
+ ).toHaveBeenCalledWith(this.historyChecks);
+ });
- it("getSteamAppHtmlDetailsPage was called twice", function () {
- expect(this.steamClientMock.getSteamAppHtmlDetailsPage).toHaveBeenCalledTimes(2);
- });
+ it("updateSteamAppsById was called once", function () {
+ expect(this.steamAppsRepository.updateSteamAppsById).toHaveBeenCalledTimes(1);
+ });
- it("getSteamAppHtmlDetailsPage was called with the correct ids", function () {
- expect(this.steamClientMock.getSteamAppHtmlDetailsPage).toHaveBeenCalledWith(
- this.instantiatedApps[0].appid,
- );
- expect(this.steamClientMock.getSteamAppHtmlDetailsPage).toHaveBeenCalledWith(
- this.instantiatedApps[1].appid,
- );
+ it("updateSteamAppsById was called with the correct argument", function () {
+ expect(this.steamAppsRepository.updateSteamAppsById).toHaveBeenCalledWith(
+ this.steamApps.content,
+ );
+ });
});
+ });
- it("getSteamAppHtmlDetailsPage was called before insertManyGames", function () {
- expect(this.steamClientMock.getSteamAppHtmlDetailsPage).toHaveBeenCalledBefore(
- this.gamesRepository.insertManyGames,
- );
- });
+ describe("via Steamcharts", function () {
+ describe("Finds no unidentified steam apps in the database", function () {
+ beforeAll(async function () {
+ this.source = ValidDataSources.validDataSources.steamcharts;
+ this.steamClient = createSteamMock([]);
+ this.steamAppsRepository = createSteamAppsRepositoryMock(
+ [],
+ new SteamAppsAggregate([]),
+ );
+ this.gamesRepository = createGamesRepositoryMock([]);
+ this.historyChecksRepository = createHistoryChecksRepositoryMock();
- it("insertManyGames was called once", function () {
- expect(this.gamesRepository.insertManyGames).toHaveBeenCalledTimes(1);
- });
+ this.identifier = new GameIdentifier(
+ this.steamClient,
+ this.steamAppsRepository,
+ this.gamesRepository,
+ this.historyChecksRepository,
+ createLoggerMock(),
+ createConfigMock().features,
+ parseHTML,
+ );
- it("insertManyGames was called with the correct games", function () {
- expect(this.gamesRepository.insertManyGames).toHaveBeenCalledWith(this.games);
- });
+ await this.identifier.checkIfGameViaSource(this.source);
+ });
- it("insertManyGames was called before insertManyHistoryChecks", function () {
- expect(this.gamesRepository.insertManyGames).toHaveBeenCalledBefore(
- this.historyChecksRepository.insertManyHistoryChecks,
- );
- });
+ it("getSourceUntriedFilteredSteamApps was called once", function () {
+ expect(
+ this.steamAppsRepository.getSourceUntriedFilteredSteamApps,
+ ).toHaveBeenCalledTimes(1);
+ });
- it("insertManyHistoryChecks was called once", function () {
- expect(
- this.historyChecksRepository.insertManyHistoryChecks,
- ).toHaveBeenCalledTimes(1);
- });
+ it("getSourceUntriedFilteredSteamApps was called with the correct arguments", function () {
+ expect(
+ this.steamAppsRepository.getSourceUntriedFilteredSteamApps,
+ ).toHaveBeenCalledWith(1, this.source);
+ });
- it("insertManyHistoryChecks was called the correct history checks", function () {
- expect(this.historyChecksRepository.insertManyHistoryChecks).toHaveBeenCalledWith(
- this.historychecks,
- );
- });
+ it("getSourceHtmlDetailsPage was not called", function () {
+ expect(this.steamClient.getSourceHtmlDetailsPage).toHaveBeenCalledTimes(0);
+ });
- it("insertManyHistoryChecks was called before updateSteamAppsById", function () {
- expect(
- this.historyChecksRepository.insertManyHistoryChecks,
- ).toHaveBeenCalledBefore(this.steamAppsRepository.updateSteamAppsById);
- });
+ it("insertManyGames was not called", function () {
+ expect(this.gamesRepository.insertManyGames).toHaveBeenCalledTimes(0);
+ });
- it("updateSteamAppsById was called once", function () {
- expect(this.steamAppsRepository.updateSteamAppsById).toHaveBeenCalledTimes(1);
- });
+ it("insertManyHistoryChecks was not called", function () {
+ expect(
+ this.historyChecksRepository.insertManyHistoryChecks,
+ ).toHaveBeenCalledTimes(0);
+ });
- it("updateSteamAppsById was called with the correct steam apps", function () {
- expect(this.steamAppsRepository.updateSteamAppsById).toHaveBeenCalledWith(
- this.updatedSteamApps,
- );
+ it("updateSteamAppsById was not called", function () {
+ expect(this.steamAppsRepository.updateSteamAppsById).toHaveBeenCalledTimes(0);
+ });
});
- });
- describe("gets one game out of a batch of four steamApps.", function () {
- describe("The second and third games' pages experience errors.", function () {
+ describe("Finds two unidentified steam apps in the database, none of them being games", function () {
beforeAll(async function () {
- this.apps = getXSampleSteamApps(4);
+ this.steamApps = new SteamAppsAggregate(getXSampleSteamApps(2));
- this.htmlDetailsPages = [
- animaddicts2gameHtmlDetailsPage,
- "",
- "",
- glitchhikersSoundtrackHtmlDetailsPage,
- ];
+ this.source = ValidDataSources.validDataSources.steamcharts;
- this.instantiatedApps = SteamApp.manyFromSteamApi(this.apps);
+ const htmlDetailsPages = ["", ""];
- this.games = discoverGamesFromSteamWeb(
- this.instantiatedApps,
- this.htmlDetailsPages,
- );
+ const parsedHtmlPages = getParsedHtmlPages(htmlDetailsPages);
- this.historychecks = HistoryCheck.manyFromGames(this.games);
+ this.steamApps.identifyTypes(parsedHtmlPages, this.source);
- this.updatedSteamApps = updateTypeSideEffectFree(
- this.instantiatedApps,
- this.htmlDetailsPages,
- );
+ this.games = this.steamApps.extractGames(parsedHtmlPages, this.source);
- this.steamClientMock = createSteamMock(this.htmlDetailsPages);
+ this.historyChecks = HistoryCheck.manyFromGames(this.games);
+ this.steamClient = createSteamMock(htmlDetailsPages);
this.steamAppsRepository = createSteamAppsRepositoryMock(
- this.instantiatedApps,
undefined,
+ this.steamApps,
);
this.gamesRepository = createGamesRepositoryMock();
this.historyChecksRepository = createHistoryChecksRepositoryMock();
this.identifier = new GameIdentifier(
- this.steamClientMock,
+ this.steamClient,
this.steamAppsRepository,
this.gamesRepository,
this.historyChecksRepository,
createLoggerMock(),
createConfigMock().features,
+ parseHTML,
);
- await this.identifier.tryViaSteamWeb();
+ await this.identifier.checkIfGameViaSource(this.source);
});
- it("getSteamWebUntriedFilteredSteamApps was called once", function () {
+ it("getSourceUntriedFilteredSteamApps was called once", function () {
expect(
- this.steamAppsRepository.getSteamWebUntriedFilteredSteamApps,
+ this.steamAppsRepository.getSourceUntriedFilteredSteamApps,
).toHaveBeenCalledTimes(1);
});
- it("getSteamWebUntriedFilteredSteamApps was called with the correct batch size", function () {
+ it("getSourceUntriedFilteredSteamApps was called with the correct arguments", function () {
expect(
- this.steamAppsRepository.getSteamWebUntriedFilteredSteamApps,
- ).toHaveBeenCalledWith(1);
+ this.steamAppsRepository.getSourceUntriedFilteredSteamApps,
+ ).toHaveBeenCalledWith(1, this.source);
});
- it("getSteamWebUntriedFilteredSteamApps was called before getSteamAppHtmlDetailsPage", function () {
- expect(
- this.steamAppsRepository.getSteamWebUntriedFilteredSteamApps,
- ).toHaveBeenCalledBefore(this.steamClientMock.getSteamAppHtmlDetailsPage);
+ it("getSourceHtmlDetailsPage was called twice", function () {
+ expect(this.steamClient.getSourceHtmlDetailsPage).toHaveBeenCalledTimes(2);
});
- it("getSteamAppHtmlDetailsPage was called four times", function () {
- expect(this.steamClientMock.getSteamAppHtmlDetailsPage).toHaveBeenCalledTimes(
- 4,
+ it("getSourceHtmlDetailsPage was called with the correct arguments", function () {
+ expect(this.steamClient.getSourceHtmlDetailsPage).toHaveBeenCalledWith(
+ this.steamApps.content[0].appid,
+ this.source,
);
- });
-
- it("getSteamAppHtmlDetailsPage was called with the correct ids", function () {
- expect(this.steamClientMock.getSteamAppHtmlDetailsPage).toHaveBeenCalledWith(
- this.instantiatedApps[0].appid,
- );
- expect(this.steamClientMock.getSteamAppHtmlDetailsPage).toHaveBeenCalledWith(
- this.instantiatedApps[1].appid,
- );
- expect(this.steamClientMock.getSteamAppHtmlDetailsPage).toHaveBeenCalledWith(
- this.instantiatedApps[2].appid,
- );
- expect(this.steamClientMock.getSteamAppHtmlDetailsPage).toHaveBeenCalledWith(
- this.instantiatedApps[3].appid,
+ expect(this.steamClient.getSourceHtmlDetailsPage).toHaveBeenCalledWith(
+ this.steamApps.content[1].appid,
+ this.source,
);
});
- it("getSteamAppHtmlDetailsPage was called before insertManyGames", function () {
- expect(this.steamClientMock.getSteamAppHtmlDetailsPage).toHaveBeenCalledBefore(
- this.gamesRepository.insertManyGames,
- );
- });
-
- it("insertManyGames was called once", function () {
- expect(this.gamesRepository.insertManyGames).toHaveBeenCalledTimes(1);
- });
-
- it("insertManyGames was called with the correct games", function () {
- expect(this.gamesRepository.insertManyGames).toHaveBeenCalledWith(this.games);
- });
-
- it("insertManyGames was called before insertManyHistoryChecks", function () {
- expect(this.gamesRepository.insertManyGames).toHaveBeenCalledBefore(
- this.historyChecksRepository.insertManyHistoryChecks,
- );
- });
-
- it("insertManyHistoryChecks was called once", function () {
- expect(
- this.historyChecksRepository.insertManyHistoryChecks,
- ).toHaveBeenCalledTimes(1);
- });
-
- it("insertManyHistoryChecks was called with the correct history checks", function () {
- expect(
- this.historyChecksRepository.insertManyHistoryChecks,
- ).toHaveBeenCalledWith(this.historychecks);
+ it("insertManyGames was not called", function () {
+ expect(this.gamesRepository.insertManyGames).toHaveBeenCalledTimes(0);
});
- it("insertManyHistoryChecks was called before updateSteamAppsById", function () {
+ it("insertManyHistoryChecks was not called", function () {
expect(
this.historyChecksRepository.insertManyHistoryChecks,
- ).toHaveBeenCalledBefore(this.steamAppsRepository.updateSteamAppsById);
+ ).toHaveBeenCalledTimes(0);
});
it("updateSteamAppsById was called once", function () {
expect(this.steamAppsRepository.updateSteamAppsById).toHaveBeenCalledTimes(1);
});
- it("updateSteamAppsById was called with the correct updated steam apps", function () {
+ it("updateSteamAppsById was called with the correct argument", function () {
expect(this.steamAppsRepository.updateSteamAppsById).toHaveBeenCalledWith(
- this.updatedSteamApps,
+ this.steamApps.content,
);
});
});
- });
- });
-
- describe(".tryViaSteamchartsWeb", function () {
- describe("gets no steam apps from the database", function () {
- beforeAll(async function () {
- this.steamClientMock = createSteamMock([undefined]);
-
- this.steamAppsRepository = createSteamAppsRepositoryMock(undefined, []);
- this.gamesRepository = createGamesRepositoryMock();
- this.historyChecksRepository = createHistoryChecksRepositoryMock();
-
- this.identifier = new GameIdentifier(
- this.steamClientMock,
- this.steamAppsRepository,
- this.gamesRepository,
- this.historyChecksRepository,
- createLoggerMock(),
- createConfigMock().features,
- );
-
- await this.identifier.tryViaSteamchartsWeb();
- });
-
- it("getSteamchartsUntriedFilteredSteamApps was called once", function () {
- expect(
- this.steamAppsRepository.getSteamchartsUntriedFilteredSteamApps,
- ).toHaveBeenCalledTimes(1);
- });
-
- it("getSteamchartsUntriedFilteredSteamApps was called with the correct batch size", function () {
- expect(
- this.steamAppsRepository.getSteamchartsUntriedFilteredSteamApps,
- ).toHaveBeenCalledWith(1);
- });
-
- it("getSteamchartsGameHtmlDetailsPage was not called", function () {
- expect(
- this.steamClientMock.getSteamchartsGameHtmlDetailsPage,
- ).toHaveBeenCalledTimes(0);
- });
-
- it("insertManyGames was not called", function () {
- expect(this.gamesRepository.insertManyGames).toHaveBeenCalledTimes(0);
- });
-
- it("insertManyHistoryChecks was not called", function () {
- expect(
- this.historyChecksRepository.insertManyHistoryChecks,
- ).toHaveBeenCalledTimes(0);
- });
-
- it("updateSteamAppsById was not called", function () {
- expect(this.steamAppsRepository.updateSteamAppsById).toHaveBeenCalledTimes(0);
- });
- });
- describe("gets two steam apps from the database,", function () {
- describe("none of them being games", function () {
+ describe("Finds two unidentified steam apps in the database, one of them being a game", function () {
beforeAll(async function () {
- this.apps = getXSampleSteamApps(2);
+ this.steamApps = new SteamAppsAggregate(getXSampleSteamApps(2));
- const pages = ["", ""];
+ this.source = ValidDataSources.validDataSources.steamcharts;
- this.htmlDetailsPages = createHtmlDetailsPages(pages);
+ const htmlDetailsPages = [mortalDarknessGameHtmlDetailsPage, ""];
- this.instantiatedMarkedApps = instantiateAndMark(
- this.apps,
- this.htmlDetailsPages,
- );
+ const parsedHtmlPages = getParsedHtmlPages(htmlDetailsPages);
+
+ this.steamApps.identifyTypes(parsedHtmlPages, this.source);
- this.steamClientMock = createSteamMock(["", ""]);
+ this.games = this.steamApps.extractGames(parsedHtmlPages, this.source);
- this.steamAppsRepository = createSteamAppsRepositoryMock(undefined, this.apps);
+ this.historyChecks = HistoryCheck.manyFromGames(this.games);
+
+ this.steamClient = createSteamMock(htmlDetailsPages);
+ this.steamAppsRepository = createSteamAppsRepositoryMock(
+ undefined,
+ this.steamApps,
+ );
this.gamesRepository = createGamesRepositoryMock();
this.historyChecksRepository = createHistoryChecksRepositoryMock();
this.identifier = new GameIdentifier(
- this.steamClientMock,
+ this.steamClient,
this.steamAppsRepository,
this.gamesRepository,
this.historyChecksRepository,
createLoggerMock(),
createConfigMock().features,
+ parseHTML,
);
- await this.identifier.tryViaSteamchartsWeb();
+ await this.identifier.checkIfGameViaSource(this.source);
});
- it("getSteamchartsUntriedFilteredSteamApps was called once", function () {
+ it("getSourceUntriedFilteredSteamApps was called once", function () {
expect(
- this.steamAppsRepository.getSteamchartsUntriedFilteredSteamApps,
+ this.steamAppsRepository.getSourceUntriedFilteredSteamApps,
).toHaveBeenCalledTimes(1);
});
- it("getSteamchartsUntriedFilteredSteamApps was called with the correct batch size", function () {
+ it("getSourceUntriedFilteredSteamApps was called with the correct arguments", function () {
expect(
- this.steamAppsRepository.getSteamchartsUntriedFilteredSteamApps,
- ).toHaveBeenCalledWith(1);
+ this.steamAppsRepository.getSourceUntriedFilteredSteamApps,
+ ).toHaveBeenCalledWith(1, this.source);
});
- it("getSteamchartsUntriedFilteredSteamApps was called before getSteamchartsGameHtmlDetailsPage", function () {
- expect(
- this.steamAppsRepository.getSteamchartsUntriedFilteredSteamApps,
- ).toHaveBeenCalledBefore(
- this.steamClientMock.getSteamchartsGameHtmlDetailsPage,
+ it("getSourceHtmlDetailsPage was called twice", function () {
+ expect(this.steamClient.getSourceHtmlDetailsPage).toHaveBeenCalledTimes(2);
+ });
+
+ it("getSourceHtmlDetailsPage was called with the correct arguments", function () {
+ expect(this.steamClient.getSourceHtmlDetailsPage).toHaveBeenCalledWith(
+ this.steamApps.content[0].appid,
+ this.source,
+ );
+ expect(this.steamClient.getSourceHtmlDetailsPage).toHaveBeenCalledWith(
+ this.steamApps.content[1].appid,
+ this.source,
);
});
- it("getSteamchartsGameHtmlDetailsPage was called two times", function () {
- expect(
- this.steamClientMock.getSteamchartsGameHtmlDetailsPage,
- ).toHaveBeenCalledTimes(2);
+ it("insertManyGames was called once", function () {
+ expect(this.gamesRepository.insertManyGames).toHaveBeenCalledTimes(1);
});
- it("getSteamchartsGameHtmlDetailsPage was called with the correct ids", function () {
- expect(
- this.steamClientMock.getSteamchartsGameHtmlDetailsPage,
- ).toHaveBeenCalledWith(this.apps[0].appid);
+ it("insertManyGames was called with the correct argument", function () {
+ expect(this.gamesRepository.insertManyGames).toHaveBeenCalledWith(this.games);
+ });
+
+ it("insertManyHistoryChecks was called once", function () {
expect(
- this.steamClientMock.getSteamchartsGameHtmlDetailsPage,
- ).toHaveBeenCalledWith(this.apps[1].appid);
+ this.historyChecksRepository.insertManyHistoryChecks,
+ ).toHaveBeenCalledTimes(1);
});
- it("getSteamchartsGameHtmlDetailsPage was called before updateSteamAppsById", function () {
+ it("insertManyHistoryChecks was called with the correct argument", function () {
expect(
- this.steamClientMock.getSteamchartsGameHtmlDetailsPage,
- ).toHaveBeenCalledBefore(this.steamAppsRepository.updateSteamAppsById);
+ this.historyChecksRepository.insertManyHistoryChecks,
+ ).toHaveBeenCalledWith(this.historyChecks);
});
it("updateSteamAppsById was called once", function () {
expect(this.steamAppsRepository.updateSteamAppsById).toHaveBeenCalledTimes(1);
});
- it("updateSteamAppsById was called with the correct steam apps", function () {
+ it("updateSteamAppsById was called with the correct argument", function () {
expect(this.steamAppsRepository.updateSteamAppsById).toHaveBeenCalledWith(
- this.instantiatedMarkedApps,
+ this.steamApps.content,
);
});
-
- it("insertManyGames was not called", function () {
- expect(this.gamesRepository.insertManyGames).toHaveBeenCalledTimes(0);
- });
-
- it("insertManyHistoryChecks was not called", function () {
- expect(
- this.historyChecksRepository.insertManyHistoryChecks,
- ).toHaveBeenCalledTimes(0);
- });
- });
- });
-
- describe("one of them being a game", function () {
- beforeAll(async function () {
- this.apps = getXSampleSteamApps(2);
-
- const pages = [eldenRingHttpDetailsSteamcharts, ""];
-
- this.htmlDetailsPages = createHtmlDetailsPages(pages);
-
- this.instantiatedMarkedApps = instantiateAndMark(
- this.apps,
- this.htmlDetailsPages,
- );
-
- this.games = identifyGames(this.instantiatedMarkedApps);
-
- this.historychecks = HistoryCheck.manyFromGames(this.games);
-
- this.steamClientMock = createSteamMock([eldenRingHttpDetailsSteamcharts, ""]);
-
- this.steamAppsRepository = createSteamAppsRepositoryMock(undefined, this.apps);
- this.gamesRepository = createGamesRepositoryMock(this.games);
- this.historyChecksRepository = createHistoryChecksRepositoryMock();
-
- this.identifier = new GameIdentifier(
- this.steamClientMock,
- this.steamAppsRepository,
- this.gamesRepository,
- this.historyChecksRepository,
- createLoggerMock(),
- createConfigMock().features,
- );
-
- await this.identifier.tryViaSteamchartsWeb();
- });
-
- it("getSteamchartsUntriedFilteredSteamApps was called once", function () {
- expect(
- this.steamAppsRepository.getSteamchartsUntriedFilteredSteamApps,
- ).toHaveBeenCalledTimes(1);
- });
-
- it("getSteamchartsUntriedFilteredSteamApps was called with the correct batch size", function () {
- expect(
- this.steamAppsRepository.getSteamchartsUntriedFilteredSteamApps,
- ).toHaveBeenCalledWith(1);
- });
-
- it("getSteamchartsUntriedFilteredSteamApps was called before getSteamchartsGameHtmlDetailsPage", function () {
- expect(
- this.steamAppsRepository.getSteamchartsUntriedFilteredSteamApps,
- ).toHaveBeenCalledBefore(this.steamClientMock.getSteamchartsGameHtmlDetailsPage);
- });
-
- it("getSteamchartsGameHtmlDetailsPage was called two times", function () {
- expect(
- this.steamClientMock.getSteamchartsGameHtmlDetailsPage,
- ).toHaveBeenCalledTimes(2);
- });
-
- it("getSteamchartsGameHtmlDetailsPage was called with the correct ids", function () {
- expect(
- this.steamClientMock.getSteamchartsGameHtmlDetailsPage,
- ).toHaveBeenCalledWith(this.apps[0].appid);
- expect(
- this.steamClientMock.getSteamchartsGameHtmlDetailsPage,
- ).toHaveBeenCalledWith(this.apps[1].appid);
- });
-
- it("getSteamchartsGameHtmlDetailsPage was called before insertManyGames", function () {
- expect(
- this.steamClientMock.getSteamchartsGameHtmlDetailsPage,
- ).toHaveBeenCalledBefore(this.gamesRepository.insertManyGames);
- });
-
- it("insertManyGames was called once", function () {
- expect(this.gamesRepository.insertManyGames).toHaveBeenCalledTimes(1);
- });
-
- it("insertManyGames was called with the correct games", function () {
- expect(this.gamesRepository.insertManyGames).toHaveBeenCalledWith(this.games);
- });
-
- it("insertManyGames was called before insertManyHistoryChecks", function () {
- expect(this.gamesRepository.insertManyGames).toHaveBeenCalledBefore(
- this.historyChecksRepository.insertManyHistoryChecks,
- );
- });
-
- it("insertManyHistoryChecks was called once", function () {
- expect(
- this.historyChecksRepository.insertManyHistoryChecks,
- ).toHaveBeenCalledTimes(1);
- });
-
- it("insertManyHistoryChecks was called with the correct history checks", function () {
- expect(this.historyChecksRepository.insertManyHistoryChecks).toHaveBeenCalledWith(
- this.historychecks,
- );
- });
-
- it("insertManyHistoryChecks was called before updateSteamAppsById", function () {
- expect(
- this.historyChecksRepository.insertManyHistoryChecks,
- ).toHaveBeenCalledBefore(this.steamAppsRepository.updateSteamAppsById);
- });
-
- it("updateSteamAppsById was called once", function () {
- expect(this.steamAppsRepository.updateSteamAppsById).toHaveBeenCalledTimes(1);
- });
-
- it("updateSteamAppsById was called with the correct steam apps", function () {
- expect(this.steamAppsRepository.updateSteamAppsById).toHaveBeenCalledWith(
- this.instantiatedMarkedApps,
- );
});
});
});
@@ -719,7 +503,7 @@ describe("game.identifier.js", function () {
beforeAll(async function () {
this.steamClientMock = createSteamMock([]);
this.steamAppsRepository = createSteamAppsRepositoryMock();
- this.gamesRepository = createGamesRepositoryMock([]);
+ this.gamesRepository = createGamesRepositoryMock(new GamesAggregate([]));
this.historyChecksRepository = createHistoryChecksRepositoryMock();
this.identifier = new GameIdentifier(
@@ -729,6 +513,7 @@ describe("game.identifier.js", function () {
this.historyChecksRepository,
createLoggerMock(),
createConfigMock().features,
+ parseHTML,
);
await this.identifier.updateGamesWithoutDetails();
@@ -746,40 +531,40 @@ describe("game.identifier.js", function () {
expect(this.steamAppsRepository.getSteamAppsById).toHaveBeenCalledTimes(0);
});
- it("getSteamDbHtmlDetailsPage was not called", function () {
- expect(this.steamClientMock.getSteamDbHtmlDetailsPage).toHaveBeenCalledTimes(0);
+ it("getSourceHtmlDetailsPage was not called", function () {
+ expect(this.steamClientMock.getSourceHtmlDetailsPage).toHaveBeenCalledTimes(0);
});
it("updateSteamAppsById was not called", function () {
expect(this.steamAppsRepository.updateSteamAppsById).toHaveBeenCalledTimes(0);
});
- it("updateGameDetails was not called", function () {
- expect(this.gamesRepository.updateGameDetails).toHaveBeenCalledTimes(0);
+ it("updateGameDetailsFrom was not called", function () {
+ expect(this.gamesRepository.updateGameDetailsFrom).toHaveBeenCalledTimes(0);
});
});
describe("Finds two games with missing properties,", function () {
beforeAll(async function () {
- this.steamApps = getXSampleSteamApps(2);
+ this.source = ValidDataSources.validDataSources.steamDb;
- this.games = getXGamesWithoutDetails(2);
+ this.steamApps = new SteamAppsAggregate(getXSampleSteamApps(2));
- const pages = [counterStrikeHtmlDetailsSteamDb, riskOfRainHtmlDetailsSteamDb];
+ this.games = new GamesAggregate(getXGamesWithoutDetails(2));
- this.htmlDetailsPages = createHtmlDetailsPages(pages);
+ const htmlDetailsPages = [
+ counterStrikeHtmlDetailsSteamDb,
+ riskOfRainHtmlDetailsSteamDb,
+ ];
- this.updatedApps = recordAttemptsViaSteamDb(
- this.steamApps,
- this.htmlDetailsPages,
- );
+ const parsedPages = getParsedHtmlPages(htmlDetailsPages);
- this.steamClientMock = createSteamMock(pages);
- this.steamAppsRepository = createSteamAppsRepositoryMock(
- undefined,
- undefined,
- this.steamApps,
- );
+ this.games.updateGameDetailsFrom(parsedPages);
+
+ this.steamApps.recordAttemptsViaSource(parsedPages, this.source);
+
+ this.steamClientMock = createSteamMock(htmlDetailsPages);
+ this.steamAppsRepository = createSteamAppsRepositoryMock(this.steamApps);
this.gamesRepository = createGamesRepositoryMock(this.games);
this.historyChecksRepository = createHistoryChecksRepositoryMock();
@@ -790,6 +575,7 @@ describe("game.identifier.js", function () {
this.historyChecksRepository,
createLoggerMock(),
createConfigMock().features,
+ parseHTML,
);
await this.identifier.updateGamesWithoutDetails();
@@ -803,28 +589,18 @@ describe("game.identifier.js", function () {
expect(this.gamesRepository.getGamesWithoutDetails).toHaveBeenCalledWith(1);
});
- it("getGamesWithoutDetails was called before getSteamDbHtmlDetailsPage", function () {
- expect(this.gamesRepository.getGamesWithoutDetails).toHaveBeenCalledBefore(
- this.steamClientMock.getSteamDbHtmlDetailsPage,
- );
- });
-
- it("getSteamDbHtmlDetailsPage was called twice", function () {
- expect(this.steamClientMock.getSteamDbHtmlDetailsPage).toHaveBeenCalledTimes(2);
+ it("getSourceHtmlDetailsPage was called twice", function () {
+ expect(this.steamClientMock.getSourceHtmlDetailsPage).toHaveBeenCalledTimes(2);
});
- it("getSteamDbHtmlDetailsPage was called with the correct ids", function () {
- expect(this.steamClientMock.getSteamDbHtmlDetailsPage).toHaveBeenCalledWith(
- this.games[0].id,
+ it("getSourceHtmlDetailsPage was called with the correct arguments", function () {
+ expect(this.steamClientMock.getSourceHtmlDetailsPage).toHaveBeenCalledWith(
+ this.games.content[0].id,
+ this.source,
);
- expect(this.steamClientMock.getSteamDbHtmlDetailsPage).toHaveBeenCalledWith(
- this.games[1].id,
- );
- });
-
- it("getSteamDbHtmlDetailsPage was called before updateSteamAppsById", function () {
- expect(this.steamClientMock.getSteamDbHtmlDetailsPage).toHaveBeenCalledBefore(
- this.steamAppsRepository.updateSteamAppsById,
+ expect(this.steamClientMock.getSourceHtmlDetailsPage).toHaveBeenCalledWith(
+ this.games.content[1].id,
+ this.source,
);
});
@@ -834,22 +610,18 @@ describe("game.identifier.js", function () {
it("updateSteamAppsById was called with the correct argument", function () {
expect(this.steamAppsRepository.updateSteamAppsById).toHaveBeenCalledWith(
- this.updatedApps,
- );
- });
-
- it("updateSteamAppsById was called before updateSteamAppsById", function () {
- expect(this.steamAppsRepository.updateSteamAppsById).toHaveBeenCalledBefore(
- this.gamesRepository.updateGameDetails,
+ this.steamApps.content,
);
});
- it("updateGameDetails was called once", function () {
- expect(this.gamesRepository.updateGameDetails).toHaveBeenCalledTimes(1);
+ it("updateGameDetailsFrom was called once", function () {
+ expect(this.gamesRepository.updateGameDetailsFrom).toHaveBeenCalledTimes(1);
});
- it("updateGameDetails was called with the correct argument", function () {
- expect(this.gamesRepository.updateGameDetails).toHaveBeenCalledWith(this.games);
+ it("updateGameDetailsFrom was called with the correct argument", function () {
+ expect(this.gamesRepository.updateGameDetailsFrom).toHaveBeenCalledWith(
+ this.games.content,
+ );
});
});
});
@@ -859,7 +631,7 @@ describe("game.identifier.js", function () {
beforeAll(async function () {
this.steamClientMock = createSteamMock([]);
this.steamAppsRepository = createSteamAppsRepositoryMock();
- this.gamesRepository = createGamesRepositoryMock([]);
+ this.gamesRepository = createGamesRepositoryMock(new GamesAggregate([]));
this.historyChecksRepository = createHistoryChecksRepositoryMock();
this.identifier = new GameIdentifier(
@@ -869,6 +641,7 @@ describe("game.identifier.js", function () {
this.historyChecksRepository,
createLoggerMock(),
createConfigMock(2).features,
+ parseHTML,
);
await this.identifier.updateGamesWithoutReleaseDates();
@@ -886,8 +659,8 @@ describe("game.identifier.js", function () {
expect(this.steamAppsRepository.getSteamAppsById).toHaveBeenCalledTimes(0);
});
- it("getSteamDbHtmlDetailsPage was not called", function () {
- expect(this.steamClientMock.getSteamDbHtmlDetailsPage).toHaveBeenCalledTimes(0);
+ it("getSourceHtmlDetailsPage was not called", function () {
+ expect(this.steamClientMock.getSourceHtmlDetailsPage).toHaveBeenCalledTimes(0);
});
it("updateSteamAppsById was not called", function () {
@@ -900,265 +673,111 @@ describe("game.identifier.js", function () {
});
describe("Finds two games with missing release dates", function () {
- describe("with no empty html pages", function () {
- beforeAll(async function () {
- this.games = getXGamesWithoutDetails(2);
-
- const apps = getXSampleSteamApps(2);
-
- const pages = [counterStrikeHtmlDetailsSteamDb, riskOfRainHtmlDetailsSteamDb];
-
- const updatedPages = createHtmlDetailsPages(pages);
-
- this.updatedApps = recordAttemptsViaSteamDb(apps, updatedPages);
-
- this.steamClientMock = createSteamMock([
- counterStrikeHtmlDetailsSteamDb,
- riskOfRainHtmlDetailsSteamDb,
- ]);
- this.steamAppsRepository = createSteamAppsRepositoryMock(
- undefined,
- undefined,
- apps,
- );
- this.gamesRepository = createGamesRepositoryMock(this.games);
- this.historyChecksRepository = createHistoryChecksRepositoryMock();
-
- this.identifier = new GameIdentifier(
- this.steamClientMock,
- this.steamAppsRepository,
- this.gamesRepository,
- this.historyChecksRepository,
- createLoggerMock(),
- createConfigMock(2).features,
- );
-
- await this.identifier.updateGamesWithoutReleaseDates();
- });
-
- it("getGamesWithoutReleaseDates was called once", function () {
- expect(this.gamesRepository.getGamesWithoutReleaseDates).toHaveBeenCalledTimes(
- 1,
- );
- });
-
- it("getGamesWithoutReleaseDates was called with the correct batch size", function () {
- expect(this.gamesRepository.getGamesWithoutReleaseDates).toHaveBeenCalledWith(
- 2,
- );
- });
-
- it("getGamesWithoutReleaseDates was called before getSteamAppsById", function () {
- expect(this.gamesRepository.getGamesWithoutReleaseDates).toHaveBeenCalledBefore(
- this.steamAppsRepository.getSteamAppsById,
- );
- });
-
- it("getSteamAppsById was called once", function () {
- expect(this.steamAppsRepository.getSteamAppsById).toHaveBeenCalledTimes(1);
- });
-
- it("getSteamAppsById was called with the correct argument", function () {
- expect(this.steamAppsRepository.getSteamAppsById).toHaveBeenCalledWith(
- this.games.map((game) => game.id),
- );
- });
+ beforeAll(async function () {
+ this.games = new GamesAggregate(getXGamesWithoutDetails(2));
- it("getSteamAppsById was called before getSteamDbHtmlDetailsPage", function () {
- expect(this.steamAppsRepository.getSteamAppsById).toHaveBeenCalledBefore(
- this.steamClientMock.getSteamDbHtmlDetailsPage,
- );
- });
+ this.steamApps = new SteamAppsAggregate(getXSampleSteamApps(2));
- it("getSteamDbHtmlDetailsPage was called twice", function () {
- expect(this.steamClientMock.getSteamDbHtmlDetailsPage).toHaveBeenCalledTimes(2);
- });
+ const htmlDetailsPages = [
+ counterStrikeHtmlDetailsSteamDb,
+ riskOfRainHtmlDetailsSteamDb,
+ ];
- it("getSteamDbHtmlDetailsPage was called with the correct ids", function () {
- expect(this.steamClientMock.getSteamDbHtmlDetailsPage).toHaveBeenCalledWith(
- this.games[0].id,
- );
- expect(this.steamClientMock.getSteamDbHtmlDetailsPage).toHaveBeenCalledWith(
- this.games[1].id,
- );
- });
+ const parsedPages = getParsedHtmlPages(htmlDetailsPages);
- it("getSteamDbHtmlDetailsPage was called before updateSteamAppsById", function () {
- expect(this.steamClientMock.getSteamDbHtmlDetailsPage).toHaveBeenCalledBefore(
- this.steamAppsRepository.updateSteamAppsById,
- );
- });
+ this.source = ValidDataSources.validDataSources.steamDb;
- it("updateSteamAppsById was called once", function () {
- expect(this.steamAppsRepository.updateSteamAppsById).toHaveBeenCalledTimes(1);
- });
+ this.steamApps.recordAttemptsViaSource(parsedPages, this.source);
- it("updateSteamAppsById was called with the correct argument", function () {
- expect(this.steamAppsRepository.updateSteamAppsById).toHaveBeenCalledWith(
- this.updatedApps,
- );
- });
+ this.games.extractReleaseDatesFrom(parsedPages);
- it("updateSteamAppsById was called before updateReleaseDates", function () {
- expect(this.steamAppsRepository.updateSteamAppsById).toHaveBeenCalledBefore(
- this.gamesRepository.updateReleaseDates,
- );
- });
+ this.steamClientMock = createSteamMock(htmlDetailsPages);
+ this.steamAppsRepository = createSteamAppsRepositoryMock(this.steamApps);
+ this.gamesRepository = createGamesRepositoryMock(this.games);
+ this.historyChecksRepository = createHistoryChecksRepositoryMock();
- it("updateReleaseDates was called once", function () {
- expect(this.gamesRepository.updateReleaseDates).toHaveBeenCalledTimes(1);
- });
+ this.identifier = new GameIdentifier(
+ this.steamClientMock,
+ this.steamAppsRepository,
+ this.gamesRepository,
+ this.historyChecksRepository,
+ createLoggerMock(),
+ createConfigMock(2).features,
+ parseHTML,
+ );
- it("updateReleaseDates was called with the correct argument", function () {
- expect(this.gamesRepository.updateReleaseDates).toHaveBeenCalledWith(
- this.games,
- );
- });
+ await this.identifier.updateGamesWithoutReleaseDates();
});
- describe("with one empty html page", function () {
- beforeAll(async function () {
- const steamApps = getXSampleSteamApps(2);
-
- this.games = getXGamesWithoutDetails(2);
-
- const pages = [counterStrikeHtmlDetailsSteamDb, ""];
-
- this.steamClientMock = createSteamMock(pages);
-
- const htmlPages = createHtmlDetailsPages(pages);
-
- this.updatedApps = recordAttemptsViaSteamDb(steamApps, htmlPages);
-
- updateMissingReleaseDates(this.games, htmlPages);
-
- this.steamAppsRepository = createSteamAppsRepositoryMock(
- undefined,
- undefined,
- steamApps,
- );
- this.gamesRepository = createGamesRepositoryMock(this.games);
- this.historyChecksRepository = createHistoryChecksRepositoryMock();
-
- this.identifier = new GameIdentifier(
- this.steamClientMock,
- this.steamAppsRepository,
- this.gamesRepository,
- this.historyChecksRepository,
- createLoggerMock(),
- createConfigMock(2).features,
- );
-
- await this.identifier.updateGamesWithoutReleaseDates();
- });
-
- it("getGamesWithoutReleaseDates was called once", function () {
- expect(this.gamesRepository.getGamesWithoutReleaseDates).toHaveBeenCalledTimes(
- 1,
- );
- });
-
- it("getGamesWithoutReleaseDates was called with the correct batch size", function () {
- expect(this.gamesRepository.getGamesWithoutReleaseDates).toHaveBeenCalledWith(
- 2,
- );
- });
-
- it("getGamesWithoutReleaseDates was called before getSteamAppsById", function () {
- expect(this.gamesRepository.getGamesWithoutReleaseDates).toHaveBeenCalledBefore(
- this.steamAppsRepository.getSteamAppsById,
- );
- });
-
- it("getSteamAppsById was called once", function () {
- expect(this.steamAppsRepository.getSteamAppsById).toHaveBeenCalledTimes(1);
- });
-
- it("getSteamAppsById was called with the correct argument", function () {
- expect(this.steamAppsRepository.getSteamAppsById).toHaveBeenCalledWith(
- this.games.map((game) => game.id),
- );
- });
+ it("getGamesWithoutReleaseDates was called once", function () {
+ expect(this.gamesRepository.getGamesWithoutReleaseDates).toHaveBeenCalledTimes(1);
+ });
- it("getSteamAppsById was called before getSteamDbHtmlDetailsPage", function () {
- expect(this.steamAppsRepository.getSteamAppsById).toHaveBeenCalledBefore(
- this.steamClientMock.getSteamDbHtmlDetailsPage,
- );
- });
+ it("getGamesWithoutReleaseDates was called with the correct batch size", function () {
+ expect(this.gamesRepository.getGamesWithoutReleaseDates).toHaveBeenCalledWith(2);
+ });
- it("getSteamDbHtmlDetailsPage was called twice", function () {
- expect(this.steamClientMock.getSteamDbHtmlDetailsPage).toHaveBeenCalledTimes(2);
- });
+ it("getSteamAppsById was called once", function () {
+ expect(this.steamAppsRepository.getSteamAppsById).toHaveBeenCalledTimes(1);
+ });
- it("getSteamDbHtmlDetailsPage was called with the correct ids", function () {
- expect(this.steamClientMock.getSteamDbHtmlDetailsPage).toHaveBeenCalledWith(
- this.games[0].id,
- );
- expect(this.steamClientMock.getSteamDbHtmlDetailsPage).toHaveBeenCalledWith(
- this.games[1].id,
- );
- });
+ it("getSteamAppsById was called with the correct argument", function () {
+ expect(this.steamAppsRepository.getSteamAppsById).toHaveBeenCalledWith(
+ this.games.ids,
+ );
+ });
- it("getSteamDbHtmlDetailsPage was called before updateSteamAppsById", function () {
- expect(this.steamClientMock.getSteamDbHtmlDetailsPage).toHaveBeenCalledBefore(
- this.steamAppsRepository.updateSteamAppsById,
- );
- });
+ it("getSourceHtmlDetailsPage was called twice", function () {
+ expect(this.steamClientMock.getSourceHtmlDetailsPage).toHaveBeenCalledTimes(2);
+ });
- it("updateSteamAppsById was called once", function () {
- expect(this.steamAppsRepository.updateSteamAppsById).toHaveBeenCalledTimes(1);
- });
+ it("getSourceHtmlDetailsPage was called with the correct arguments", function () {
+ expect(this.steamClientMock.getSourceHtmlDetailsPage).toHaveBeenCalledWith(
+ this.games.content[0].id,
+ this.source,
+ );
+ expect(this.steamClientMock.getSourceHtmlDetailsPage).toHaveBeenCalledWith(
+ this.games.content[1].id,
+ this.source,
+ );
+ });
- it("updateSteamAppsById was called with the correct argument", function () {
- expect(this.steamAppsRepository.updateSteamAppsById).toHaveBeenCalledWith(
- this.updatedApps,
- );
- });
+ it("updateSteamAppsById was called once", function () {
+ expect(this.steamAppsRepository.updateSteamAppsById).toHaveBeenCalledTimes(1);
+ });
- it("updateSteamAppsById was called before updateReleaseDates", function () {
- expect(this.steamAppsRepository.updateSteamAppsById).toHaveBeenCalledBefore(
- this.gamesRepository.updateReleaseDates,
- );
- });
+ it("updateSteamAppsById was called with the correct argument", function () {
+ expect(this.steamAppsRepository.updateSteamAppsById).toHaveBeenCalledWith(
+ this.steamApps.content,
+ );
+ });
- it("updateReleaseDates was called once", function () {
- expect(this.gamesRepository.updateReleaseDates).toHaveBeenCalledTimes(1);
- });
+ it("updateReleaseDates was called once", function () {
+ expect(this.gamesRepository.updateReleaseDates).toHaveBeenCalledTimes(1);
+ });
- it("updateReleaseDates was called with the correct argument", function () {
- expect(this.gamesRepository.updateReleaseDates).toHaveBeenCalledWith(
- this.games,
- );
- });
+ it("updateReleaseDates was called with the correct argument", function () {
+ expect(this.gamesRepository.updateReleaseDates).toHaveBeenCalledWith(
+ this.games.content,
+ );
});
});
});
});
function createSteamMock(args) {
- const spyObj = jasmine.createSpyObj("steamClient", [
- "getSteamAppHtmlDetailsPage",
- "getSteamchartsGameHtmlDetailsPage",
- "getSteamDbHtmlDetailsPage",
- ]);
+ const spyObj = jasmine.createSpyObj("steamClient", ["getSourceHtmlDetailsPage"]);
- spyObj.getSteamAppHtmlDetailsPage.and.returnValues(...args);
- spyObj.getSteamchartsGameHtmlDetailsPage.and.returnValues(...args);
- spyObj.getSteamDbHtmlDetailsPage.and.returnValues(...args);
+ spyObj.getSourceHtmlDetailsPage.and.returnValues(...args);
return spyObj;
}
-function createSteamAppsRepositoryMock(
- steamWebDbRet,
- steamchartsWebDbRet,
- steamAppByIdDbRet,
-) {
+function createSteamAppsRepositoryMock(steamAppByIdDbRet, sourceUntriedRet) {
return jasmine.createSpyObj("SteamAppsRepository", {
- getSteamWebUntriedFilteredSteamApps: Promise.resolve(steamWebDbRet),
updateSteamAppsById: Promise.resolve(undefined),
- getSteamchartsUntriedFilteredSteamApps: Promise.resolve(steamchartsWebDbRet),
getSteamAppsById: Promise.resolve(steamAppByIdDbRet),
+ getSourceUntriedFilteredSteamApps: Promise.resolve(sourceUntriedRet),
});
}
@@ -1166,9 +785,10 @@ function createGamesRepositoryMock(gamesRepoRet) {
return jasmine.createSpyObj("GamesRepository", {
insertManyGames: Promise.resolve(undefined),
getGamesWithoutDetails: Promise.resolve(gamesRepoRet),
- updateGameDetails: Promise.resolve(undefined),
+ updateGameDetailsFrom: Promise.resolve(undefined),
getGamesWithoutReleaseDates: Promise.resolve(gamesRepoRet),
updateReleaseDates: Promise.resolve(undefined),
+ getSourceHtmlDetailsPage: Promise.resolve(gamesRepoRet),
});
}
@@ -1177,19 +797,3 @@ function createHistoryChecksRepositoryMock() {
insertManyHistoryChecks: Promise.resolve(undefined),
});
}
-
-function instantiateAndMark(apps, pages) {
- const instantiatedApps = SteamApp.manyFromSteamApi(apps);
-
- const updatedApps = instantiatedApps.map((app, i) => {
- if (pages[i].page === "") app.failedViaSteamchartsWeb();
- if (pages[i].page) {
- app.type = SteamApp.validTypes.game;
- }
- app.triedViaSteamchartsWeb();
-
- return app;
- });
-
- return updatedApps;
-}
diff --git a/backend/src/core/models/game.js b/backend/src/core/models/game.js
index b91b0c807..4292113a9 100644
--- a/backend/src/core/models/game.js
+++ b/backend/src/core/models/game.js
@@ -11,17 +11,32 @@ export class Game {
imageUrl;
playerHistory;
+ copy() {
+ const copy = new Game();
+ copy.id = this.id;
+ copy.name = this.name;
+ copy.releaseDate = this.releaseDate;
+ copy.developers = this.developers.slice();
+ copy.genres = this.genres.slice();
+ copy.description = this.description;
+ copy.imageUrl = this.imageUrl;
+ copy.playerHistory = PlayerHistory.manyFromDbEntry(this.playerHistory);
+
+ return copy;
+ }
+
// prettier-ignore
- static fromSteamApp(steamApp, releaseDate, developers, genres, description) {
+ static fromSteamApp(steamApp, page) {
const game = new Game();
game.id = steamApp.appid;
game.name = steamApp.name;
- game.releaseDate = releaseDate;
- game.developers = developers;
- game.genres = genres;
- game.description = description;
+ game.releaseDate = game.#extractReleaseDateFrom(page);
+ game.developers = game.#extractDevelopersFrom(page);
+ game.genres = game.#extractGenresFrom(page);
+ game.description = game.#extractDescriptionFrom(page);
game.imageUrl = `https://cdn.akamai.steamstatic.com/steam/apps/${game.id}/header.jpg`
game.playerHistory = [];
+
return game;
}
@@ -93,19 +108,124 @@ export class Game {
});
}
- updateGameDetails(newDevelopers, newGenres, newDescription) {
- if (newDevelopers.length !== 0 && this.developers.length === 0)
- this.developers = Array.from(newDevelopers);
+ #extractReleaseDateFrom(page) {
+ const releaseDateElement = page.querySelector(".release_date .date");
+
+ if (!releaseDateElement) return "";
+
+ const releaseDate = new Date(`${releaseDateElement.textContent.trim()} UTC`);
+
+ return releaseDate == "Invalid Date" ? "" : releaseDate;
+ }
+
+ #extractDevelopersFrom(page) {
+ const developers = page.querySelector(".dev_row #developers_list");
+
+ if (!developers) return [];
+
+ return Array.from(developers.children).map((developer) =>
+ developer.textContent.trim(),
+ );
+ }
+
+ #extractGenresFrom(page) {
+ const genres = page.querySelector("#genresAndManufacturer span");
+
+ if (!genres) return [];
+
+ return Array.from(genres.children)
+ .map((genre) => genre.textContent.trim())
+ .filter((genre) => !!genre);
+ }
+
+ #extractDescriptionFrom(page) {
+ const description = page.querySelector(".game_description_snippet");
+
+ if (!description) return "";
+
+ return description.textContent.trim();
+ }
+
+ updateGameDetailsFrom(page) {
+ this.#updateDevelopers(page);
+ this.#updateGenres(page);
+ this.#updateDescription(page);
+ }
+
+ #updateDevelopers(page) {
+ if (this.developers.length !== 0) return;
+
+ this.developers = this.#extractSteamDbDevelopersFrom(page);
+ }
+
+ #updateGenres(page) {
+ if (this.genres.length !== 0) return;
+
+ this.genres = this.#extractSteamDbGenresFrom(page);
+ }
+
+ #updateDescription(page) {
+ if (this.description.length !== 0) return;
+
+ this.description = this.#extractSteamDbDescriptionFrom(page);
+ }
+
+ updateReleaseDate(page) {
+ if (this.releaseDate) return;
+
+ const date = this.#extractSteamDbReleaseDateFrom(page);
+
+ if (date === "") return;
+
+ this.releaseDate = date;
+ }
+
+ #extractSteamDbDevelopersFrom(page) {
+ const developers = page.querySelector(
+ "table.table.table-bordered.table-hover.table-responsive-flex tbody tr:nth-child(3) td:last-child",
+ );
+
+ if (!developers) return [];
+
+ return Array.from(developers.children).map((developer) => developer.textContent);
+ }
+
+ #extractSteamDbGenresFrom(page) {
+ const domTableBody = page.querySelector("#info tbody");
+
+ if (!domTableBody) return [];
+
+ const genresNodes = Array.from(domTableBody.children).filter(
+ (tableEntry) => tableEntry.children[0].textContent === "Store Genres",
+ )[0].children[1].childNodes;
+
+ return Array.from(genresNodes)
+ .filter((genre) => genre.constructor.name === "Text")
+ .map((genre) => genre.nodeValue.replace(",", "").trim());
+ }
+
+ #extractSteamDbDescriptionFrom(page) {
+ const description = page.querySelector(".header-description");
- if (newGenres.length !== 0 && this.genres.length === 0)
- this.genres = Array.from(newGenres);
+ if (!description) return "";
- if (newDescription !== "" && this.description === "")
- this.description = newDescription;
+ return description.textContent;
}
- updateReleaseDate(newReleaseDate) {
- if (newReleaseDate !== "" && this.releaseDate === "")
- this.releaseDate = newReleaseDate;
+ #extractSteamDbReleaseDateFrom(page) {
+ const releaseDateElement = page.querySelector(
+ "table.table.table-bordered.table-hover.table-responsive-flex tbody tr:last-child td:last-child",
+ );
+
+ if (!releaseDateElement) return "";
+
+ const releaseDateString = releaseDateElement.textContent;
+
+ const releaseDate = new Date(`
+ ${releaseDateString.slice(0, releaseDateString.indexOf("–") - 1)} UTC`);
+
+ if (releaseDate == "Invalid Date") return "";
+
+ return releaseDate;
}
}
diff --git a/backend/src/core/models/game.mocks.js b/backend/src/core/models/game.mocks.js
index 244b15f2e..21f9b882f 100644
--- a/backend/src/core/models/game.mocks.js
+++ b/backend/src/core/models/game.mocks.js
@@ -1,22 +1,24 @@
+import { getParsedHtmlPage } from "../../../assets/html.details.pages.mock.js";
+import { feartressGameHtmlDetailsPage } from "../../../assets/steam-details-pages/feartress.game.html.details.page.js";
import { daysToMs } from "../../common/time.utils.js";
import { Game } from "./game.js";
+import { getSamplePlayerHistory } from "./player.history.mocks.js";
import { getXSampleSteamApps } from "./steam.app.mocks.js";
export const getXGamesWithoutDetails = (amount) => {
const steamApps = getXSampleSteamApps(amount);
- return steamApps.map((app, i) => Game.fromSteamApp(steamApps[i], "", [], [], ""));
+ return steamApps.map((app, i) =>
+ Game.fromSteamApp(steamApps[i], getParsedHtmlPage("")),
+ );
};
export const getOneSteamAppInstantiatedGame = () => {
const steamApp = getXSampleSteamApps(1);
- const releaseDate = "21 July 2019";
- const developers = ["Valve", "Hopoo Games"];
- const genres = ["Action", "Adventure"];
- const description = "Best game";
+ const page = getParsedHtmlPage(feartressGameHtmlDetailsPage);
- return Game.fromSteamApp(steamApp, releaseDate, developers, genres, description);
+ return Game.fromSteamApp(steamApp, page);
};
export const getXsteamchartsInstantiatedGames = (amount) => {
@@ -38,6 +40,22 @@ export const getOneGameWithDetails = () => {
];
};
+export const getOneGameWithPlayerHistory = () => {
+ const dbEntry = [
+ {
+ id: 239140,
+ name: "Dying Light",
+ releaseDate: "21.09.1989",
+ developers: ["Techland"],
+ genres: ["Action", "RPG"],
+ description: "Best game",
+ playerHistory: getSamplePlayerHistory(),
+ },
+ ];
+
+ return Game.manyFromDbEntry(dbEntry)[0];
+};
+
export const getGamesWithEmptyPlayerHistories = () => {
return [
{
diff --git a/backend/src/core/models/game.spec.js b/backend/src/core/models/game.spec.js
index b943db7de..ca1e724a2 100644
--- a/backend/src/core/models/game.spec.js
+++ b/backend/src/core/models/game.spec.js
@@ -1,583 +1,690 @@
+import { getParsedHtmlPage } from "../../../assets/html.details.pages.mock.js";
+import { crusaderKingsDetailsPage } from "../../../assets/steam-details-pages/crusader.kings.multiple.developers.html.details.page.js";
+import { feartressGameHtmlDetailsPage } from "../../../assets/steam-details-pages/feartress.game.html.details.page.js";
+import { mortalDarknessGameHtmlDetailsPage } from "../../../assets/steam-details-pages/mortal.darkness.game.html.details.page.js";
+import { riskOfRainHtmlDetailsPageMissingInfo } from "../../../assets/steam-details-pages/risk.of.rain.missing.additional.info.page.js";
+import { counterStrikeHtmlDetailsSteamDb } from "../../../assets/steamdb-details-pages/counter.strike.html.details.page.js";
+import { karmazooHtmlDetailsPageSteamDb } from "../../../assets/steamdb-details-pages/karmazoo.html.details.page.js";
+import { riskOfRainHtmlDetailsSteamDb } from "../../../assets/steamdb-details-pages/risk.of.rain.html.details.page.js";
import { Game } from "./game.js";
-import { getOneSteamAppInstantiatedGame, getXGamesWithoutDetails } from "./game.mocks.js";
+import { getOneGameWithPlayerHistory, getXGamesWithoutDetails } from "./game.mocks.js";
import { PlayerHistory } from "./player.history.js";
import { getXSampleSteamApps } from "./steam.app.mocks.js";
-describe("game.js", function () {
- describe("Game", function () {
- describe(".fromSteamApp", function () {
- describe("is called with no arguments, ", function () {
- it("an Error is thrown", function () {
- expect(Game.fromSteamApp).toThrowError();
- });
+describe("Game", function () {
+ describe(".copy", function () {
+ beforeAll(function () {
+ this.game = getOneGameWithPlayerHistory();
+ this.result = this.game.copy();
+
+ this.game.id = 99;
+ });
+
+ it("the result is a copy of game", function () {
+ expect(this.result).toBeInstanceOf(Game);
+ expect(this.result.playerHistory[0]).toBeInstanceOf(PlayerHistory);
+ });
+
+ it("the copy has identical values to the original", function () {
+ expect(this.result.id).toBe(239140);
+ expect(this.result.name).toBe("Dying Light");
+ expect(this.result.releaseDate).toBe("21.09.1989");
+ expect(this.result.developers).toEqual(["Techland"]);
+ expect(this.result.genres).toEqual(["Action", "RPG"]);
+ expect(this.result.description).toBe("Best game");
+ });
+ });
+
+ describe(".fromSteamApp", function () {
+ describe("when the method is called", function () {
+ beforeAll(function () {
+ const steamApp = getXSampleSteamApps(1)[0];
+ const page = getParsedHtmlPage(feartressGameHtmlDetailsPage);
+
+ this.result = Game.fromSteamApp(steamApp, page);
});
- describe("is called with incomplete arguments, ", function () {
- beforeAll(function () {
- this.testObject = {
- id: 123,
- name: "test game",
- };
- });
+ it("is an instance of Game", function () {
+ expect(this.result).toBeInstanceOf(Game);
+ });
- it("an Error is thrown", function () {
- expect(Game.fromSteamApp.bind(this.testObject)).toThrowError();
- });
+ it("the game has the correct values", function () {
+ expect(this.result.id).toBe(1);
+ expect(this.result.name).toBe("Game #1");
+ expect(this.result.releaseDate).toEqual(new Date("Jan 1 2001 UTC"));
+ expect(this.result.developers).toEqual(["Frederik List", "Aaron Miles"]);
+ expect(this.result.imageUrl).toBe(
+ `https://cdn.akamai.steamstatic.com/steam/apps/1/header.jpg`,
+ );
+ expect(this.result.playerHistory).toEqual([]);
});
+ });
- describe("is called with appropriate attributes, the returned value", function () {
- beforeAll(function () {
- this.testObject = {
- appid: 123,
- name: "test game",
- imageUrl: "test url",
- playerHistory: [],
- };
+ describe("if the provided HTML page does not include a release date section,", function () {
+ beforeAll(function () {
+ const steamApp = getXSampleSteamApps(1)[0];
+ const page = getParsedHtmlPage(riskOfRainHtmlDetailsPageMissingInfo);
- this.releaseDate = "24.08.2023";
+ this.result = Game.fromSteamApp(steamApp, page);
+ });
- this.developers = ["Two Giants Studios"];
+ it("the result is an instance of game", function () {
+ expect(this.result).toBeInstanceOf(Game);
+ });
- this.genres = ["Action", "Adventure"];
+ it("the game's release date will be an empty string", function () {
+ expect(this.result.releaseDate).toBe("");
+ });
+ });
- this.description = ["A game description"];
+ describe("if the provided HTML page includes a release date,", function () {
+ beforeAll(function () {
+ const steamApp = getXSampleSteamApps(1)[0];
+ const page = getParsedHtmlPage(mortalDarknessGameHtmlDetailsPage);
- this.result = Game.fromSteamApp(
- this.testObject,
- this.releaseDate,
- this.developers,
- this.genres,
- this.description,
- );
- });
+ this.result = Game.fromSteamApp(steamApp, page);
+ });
- it("is an instance of Game", function () {
- expect(this.result).toBeInstanceOf(Game);
- });
+ it("the result is an instance of game", function () {
+ expect(this.result).toBeInstanceOf(Game);
+ });
- it("has an 'id' property which equals 123", function () {
- expect(this.result.id).toBe(this.testObject.appid);
- });
+ it("the game's release date is set to the correct date'", function () {
+ expect(this.result.releaseDate.toISOString()).toEqual("2023-08-01T00:00:00.000Z");
+ });
+ });
- it("has a 'name' property which equals 'test game'", function () {
- expect(this.result.name).toBe(this.testObject.name);
- });
+ describe("if the provided HTML page does not include any developers,", function () {
+ beforeAll(function () {
+ const steamApp = getXSampleSteamApps(1)[0];
+ const page = getParsedHtmlPage(riskOfRainHtmlDetailsPageMissingInfo);
- it("has a 'releaseDate' property which equals '24.08.2023", function () {
- expect(this.result.releaseDate).toBe(this.releaseDate);
- });
+ this.result = Game.fromSteamApp(steamApp, page);
+ });
- it("has a 'developers' property which is an array with a length of 1", function () {
- expect(this.result.developers.length).toBe(1);
- });
+ it("the result is an instance of game", function () {
+ expect(this.result).toBeInstanceOf(Game);
+ });
- it("has a 'developers' property which equals 'Two Giants Studios'", function () {
- expect(this.result.developers[0]).toBe(this.developers[0]);
- });
+ it("the games developers do not get updated", function () {
+ expect(this.result.developers).toEqual([]);
+ });
+ });
- it("has a 'genres' property which is an array with a length of 2", function () {
- expect(this.result.genres.length).toBe(2);
- });
+ describe("if the provided HTML page includes two developers,", function () {
+ beforeAll(function () {
+ const steamApp = getXSampleSteamApps(1)[0];
+ const page = getParsedHtmlPage(crusaderKingsDetailsPage);
- it("'s first value of the genres property equals 'Action'", function () {
- expect(this.result.genres[0]).toBe(this.genres[0]);
- });
+ this.result = Game.fromSteamApp(steamApp, page);
+ });
- it("'s second value of the genres property equals 'Adventure'", function () {
- expect(this.result.genres[1]).toBe(this.genres[1]);
- });
+ it("the result is an instance of game", function () {
+ expect(this.result).toBeInstanceOf(Game);
+ });
- it("has a 'description' property which equals 'A game description'", function () {
- expect(this.result.description).toBe(this.description);
- });
+ it("the game's developers get updated with the correct values", function () {
+ expect(this.result.developers).toEqual([
+ "Paradox Development Studio",
+ "Paradox Thalassic",
+ ]);
+ });
+ });
- it("has an 'imageUrl' property which equals a link", function () {
- expect(this.result.imageUrl).toBe(
- `https://cdn.akamai.steamstatic.com/steam/apps/${this.testObject.appid}/header.jpg`,
- );
- });
+ describe("if the provided HTML page does not include any genres,", function () {
+ beforeAll(function () {
+ const steamApp = getXSampleSteamApps(1)[0];
+ const page = getParsedHtmlPage(riskOfRainHtmlDetailsPageMissingInfo);
- it("has a 'playerHistory' property which equals an empty array", function () {
- expect(this.result.playerHistory).toEqual(this.testObject.playerHistory);
- });
+ this.result = Game.fromSteamApp(steamApp, page);
});
- describe("is called with appropriate attributes, but the releaseDate and Developers are empty the returned value", function () {
- beforeAll(function () {
- this.testObject = {
- appid: 123,
- name: "test game",
- imageUrl: "test url",
- playerHistory: [],
- };
+ it("the result is an instance of game", function () {
+ expect(this.result).toBeInstanceOf(Game);
+ });
+
+ it("the game's genres do not get updated", function () {
+ expect(this.result.genres).toEqual([]);
+ });
+ });
- this.releaseDate = "";
- this.developers = [];
+ describe("if the provided HTML page includes genres,", function () {
+ beforeAll(function () {
+ const steamApp = getXSampleSteamApps(1)[0];
+ const page = getParsedHtmlPage(mortalDarknessGameHtmlDetailsPage);
- this.result = Game.fromSteamApp(
- this.testObject,
- this.releaseDate,
- this.developers,
- );
- });
+ this.result = Game.fromSteamApp(steamApp, page);
+ });
- it("is an instance of Game", function () {
- expect(this.result).toBeInstanceOf(Game);
- });
+ it("the result is an instance of game", function () {
+ expect(this.result).toBeInstanceOf(Game);
+ });
- it("has an 'id' property which equals 123", function () {
- expect(this.result.id).toBe(this.testObject.appid);
- });
+ it("the game's genres get updated with the correct values", function () {
+ expect(this.result.genres).toEqual(["Action", "Adventure", "Indie", "RPG"]);
+ });
+ });
- it("has a 'name' property which equals 'test game'", function () {
- expect(this.result.name).toBe(this.testObject.name);
- });
+ describe("if the provided HTML page does not include a game description,", function () {
+ beforeAll(function () {
+ const steamApp = getXSampleSteamApps(1)[0];
+ const page = getParsedHtmlPage(riskOfRainHtmlDetailsPageMissingInfo);
- it("has a 'releaseDate' property which equals an empty string", function () {
- expect(this.result.releaseDate).toBe("");
- });
+ this.result = Game.fromSteamApp(steamApp, page);
+ });
- it("has a 'developers' property which equals an empty array", function () {
- expect(this.result.developers).toEqual([]);
- });
+ it("the result is an instance of game", function () {
+ expect(this.result).toBeInstanceOf(Game);
+ });
- it("has an 'imageUrl' property which equals a link", function () {
- expect(this.result.imageUrl).toBe(
- `https://cdn.akamai.steamstatic.com/steam/apps/${this.testObject.appid}/header.jpg`,
- );
- });
+ it("the game's description does not get updated", function () {
+ expect(this.result.description).toEqual("");
+ });
+ });
- it("has a 'playerHistory' property which equals an empty array", function () {
- expect(this.result.playerHistory).toEqual(this.testObject.playerHistory);
- });
+ describe("if the provided HTML page includes a description,", function () {
+ beforeAll(function () {
+ const steamApp = getXSampleSteamApps(1)[0];
+ const page = getParsedHtmlPage(mortalDarknessGameHtmlDetailsPage);
+
+ this.result = Game.fromSteamApp(steamApp, page);
+ });
+
+ it("the result is an instance of game", function () {
+ expect(this.result).toBeInstanceOf(Game);
+ });
+
+ it("the game's description is updated with the correct value", function () {
+ expect(this.result.description).toBe(
+ "“One grim dawn and noble I wake, The darkness is rampant, our oath shall break. A noble warrior soon shall rise, and clear the air of the darkened skies.”",
+ );
});
});
+ });
- describe(".fromSteamcharts", function () {
- describe("is called with no arguments, ", function () {
- it("an Error is thrown", function () {
- expect(Game.fromSteamcharts).toThrowError();
- });
+ describe(".fromSteamcharts", function () {
+ describe("is called with no arguments, ", function () {
+ it("an Error is thrown", function () {
+ expect(Game.fromSteamcharts).toThrowError();
});
+ });
- describe("is called with incomplete arguments, ", function () {
- beforeAll(function () {
- this.testObject = {
- id: 123,
- name: "test game",
- };
- });
+ describe("is called with incomplete arguments, ", function () {
+ beforeAll(function () {
+ this.testObject = {
+ id: 123,
+ name: "test game",
+ };
+ });
- it("an Error is thrown", function () {
- expect(Game.fromSteamcharts.bind(this.testObject)).toThrowError();
- });
+ it("an Error is thrown", function () {
+ expect(Game.fromSteamcharts.bind(this.testObject)).toThrowError();
});
+ });
- describe("is called with appropriate attributes, the returned value", function () {
- beforeAll(function () {
- this.testObject = {
- appid: 123,
- name: "test game",
- imageUrl: "test url",
- playerHistory: [],
- };
+ describe("is called with appropriate attributes, the returned value", function () {
+ beforeAll(function () {
+ this.testObject = {
+ appid: 123,
+ name: "test game",
+ imageUrl: "test url",
+ playerHistory: [],
+ };
- this.result = Game.fromSteamcharts(this.testObject);
- });
+ this.result = Game.fromSteamcharts(this.testObject);
+ });
- it("is an instance of Game", function () {
- expect(this.result).toBeInstanceOf(Game);
- });
+ it("is an instance of Game", function () {
+ expect(this.result).toBeInstanceOf(Game);
+ });
- it("has an 'id' property which equals 123", function () {
- expect(this.result.id).toBe(this.testObject.appid);
- });
+ it("has an 'id' property which equals 123", function () {
+ expect(this.result.id).toBe(this.testObject.appid);
+ });
- it("has a 'name' property which equals 'test game'", function () {
- expect(this.result.name).toBe(this.testObject.name);
- });
+ it("has a 'name' property which equals 'test game'", function () {
+ expect(this.result.name).toBe(this.testObject.name);
+ });
- it("has a 'releaseDate' property which equals an empty string", function () {
- expect(this.result.releaseDate).toBe("");
- });
+ it("has a 'releaseDate' property which equals an empty string", function () {
+ expect(this.result.releaseDate).toBe("");
+ });
- it("has a 'developers' property which equals an empty array", function () {
- expect(this.result.developers).toEqual([]);
- });
+ it("has a 'developers' property which equals an empty array", function () {
+ expect(this.result.developers).toEqual([]);
+ });
- it("has a 'genres' property which equals an empty array", function () {
- expect(this.result.genres).toEqual([]);
- });
+ it("has a 'genres' property which equals an empty array", function () {
+ expect(this.result.genres).toEqual([]);
+ });
- it("has a 'description' property which equals an empty string", function () {
- expect(this.result.description).toEqual("");
- });
+ it("has a 'description' property which equals an empty string", function () {
+ expect(this.result.description).toEqual("");
+ });
- it("has an 'imageUrl' property which equals a link", function () {
- expect(this.result.imageUrl).toBe(
- `https://cdn.akamai.steamstatic.com/steam/apps/${this.testObject.appid}/header.jpg`,
- );
- });
+ it("has an 'imageUrl' property which equals a link", function () {
+ expect(this.result.imageUrl).toBe(
+ `https://cdn.akamai.steamstatic.com/steam/apps/${this.testObject.appid}/header.jpg`,
+ );
+ });
- it("has a 'playerHistory' property which equals an empty array", function () {
- expect(this.result.playerHistory).toEqual(this.testObject.playerHistory);
- });
+ it("has a 'playerHistory' property which equals an empty array", function () {
+ expect(this.result.playerHistory).toEqual(this.testObject.playerHistory);
});
});
+ });
- describe(".fromDbEntry", function () {
- describe("is called with no arguments, ", function () {
- it("an Error is thrown", function () {
- expect(Game.fromDbEntry).toThrowError();
- });
+ describe(".fromDbEntry", function () {
+ describe("is called with no arguments, ", function () {
+ it("an Error is thrown", function () {
+ expect(Game.fromDbEntry).toThrowError();
});
+ });
- describe("is called with incomplete arguments, ", function () {
- beforeAll(function () {
- this.testObject = {
- id: 123,
- name: "test game",
- };
- });
+ describe("is called with incomplete arguments, ", function () {
+ beforeAll(function () {
+ this.testObject = {
+ id: 123,
+ name: "test game",
+ };
+ });
- it("an Error is thrown", function () {
- expect(Game.fromDbEntry.bind(this.testObject)).toThrowError();
- });
+ it("an Error is thrown", function () {
+ expect(Game.fromDbEntry.bind(this.testObject)).toThrowError();
});
+ });
- describe("is called with appropriate attributes, the returned value", function () {
- beforeAll(function () {
- this.testObject = {
- id: 123,
- name: "test game",
- releaseDate: "3 Mar, 2022",
- developers: ["Crossplatform"],
- genres: ["Action", "Adventure"],
- description: "A game's description",
- imageUrl: "test url",
- playerHistory: [],
- };
+ describe("is called with appropriate attributes, the returned value", function () {
+ beforeAll(function () {
+ this.testObject = {
+ id: 123,
+ name: "test game",
+ releaseDate: "3 Mar, 2022",
+ developers: ["Crossplatform"],
+ genres: ["Action", "Adventure"],
+ description: "A game's description",
+ imageUrl: "test url",
+ playerHistory: [],
+ };
- this.result = Game.fromDbEntry(this.testObject);
- });
+ this.result = Game.fromDbEntry(this.testObject);
+ });
- it("is an instance of Game", function () {
- expect(this.result).toBeInstanceOf(Game);
- });
+ it("is an instance of Game", function () {
+ expect(this.result).toBeInstanceOf(Game);
+ });
- it("has an 'id' property which equals 123", function () {
- expect(this.result.id).toBe(this.testObject.id);
- });
+ it("has an 'id' property which equals 123", function () {
+ expect(this.result.id).toBe(this.testObject.id);
+ });
- it("has a 'name' property which equals 'test game'", function () {
- expect(this.result.name).toBe(this.testObject.name);
- });
+ it("has a 'name' property which equals 'test game'", function () {
+ expect(this.result.name).toBe(this.testObject.name);
+ });
- it("has a 'releaseDate' property which equals '3 Mar, 2022", function () {
- expect(this.result.releaseDate).toBe("3 Mar, 2022");
- });
+ it("has a 'releaseDate' property which equals '3 Mar, 2022", function () {
+ expect(this.result.releaseDate).toBe("3 Mar, 2022");
+ });
- it("has a 'developers' property which equals 'Crossplatform", function () {
- expect(this.result.developers[0]).toBe("Crossplatform");
- });
+ it("has a 'developers' property which equals 'Crossplatform", function () {
+ expect(this.result.developers[0]).toBe("Crossplatform");
+ });
- it("has a 'genres' property which is an array with a length of 2", function () {
- expect(this.result.genres.length).toBe(2);
- });
+ it("has a 'genres' property which is an array with a length of 2", function () {
+ expect(this.result.genres.length).toBe(2);
+ });
- it("first genres value equals 'Action'", function () {
- expect(this.result.genres[0]).toBe("Action");
- });
+ it("first genres value equals 'Action'", function () {
+ expect(this.result.genres[0]).toBe("Action");
+ });
- it("second genres value equals 'Adventure'", function () {
- expect(this.result.genres[1]).toBe("Adventure");
- });
+ it("second genres value equals 'Adventure'", function () {
+ expect(this.result.genres[1]).toBe("Adventure");
+ });
- it("has a 'description' property which equals 'A game's description'", function () {
- expect(this.result.description).toBe("A game's description");
- });
+ it("has a 'description' property which equals 'A game's description'", function () {
+ expect(this.result.description).toBe("A game's description");
+ });
- it("has an 'imageUrl' property which equals 'test url'", function () {
- expect(this.result.imageUrl).toBe(this.testObject.imageUrl);
- });
+ it("has an 'imageUrl' property which equals 'test url'", function () {
+ expect(this.result.imageUrl).toBe(this.testObject.imageUrl);
+ });
- it("has a 'playerHistory' property which equals an empty array", function () {
- expect(this.result.playerHistory).toEqual(this.testObject.playerHistory);
- });
+ it("has a 'playerHistory' property which equals an empty array", function () {
+ expect(this.result.playerHistory).toEqual(this.testObject.playerHistory);
});
});
+ });
- describe(".pushCurrentPlayers creates a new player history entry or updates an existing one.", function () {
- describe("When this month's player history entry already exists,", function () {
- describe("players are added to the existing entry.", function () {
- beforeAll(function () {
- this.currentPlayers = 45;
+ describe(".pushCurrentPlayers creates a new player history entry or updates an existing one.", function () {
+ describe("When this month's player history entry already exists,", function () {
+ describe("players are added to the existing entry.", function () {
+ beforeAll(function () {
+ this.currentPlayers = 45;
+
+ const playerHistory = [
+ {
+ year: new Date().getFullYear(),
+ month: new Date().getMonth(),
+ averagePlayers: 0,
+ trackedPlayers: [],
+ },
+ ];
+
+ this.historyLength = playerHistory.length;
+
+ const game = {
+ id: 1,
+ name: "Test Game",
+ playerHistory: PlayerHistory.manyFromDbEntry(playerHistory),
+ };
- const playerHistory = [
- {
- year: new Date().getFullYear(),
- month: new Date().getMonth(),
- averagePlayers: 0,
- trackedPlayers: [],
- },
- ];
+ this.result = Game.fromDbEntry(game);
- this.historyLength = playerHistory.length;
+ this.result.pushCurrentPlayers(this.currentPlayers);
+ });
- const game = {
- id: 1,
- name: "Test Game",
- playerHistory: PlayerHistory.manyFromDbEntry(playerHistory),
- };
+ it("No new entry is created", function () {
+ expect(this.result.playerHistory.length).toBe(this.historyLength);
+ });
- this.result = Game.fromDbEntry(game);
+ it("The existing entry is updated.", function () {
+ expect(this.result.playerHistory[0]).toBeInstanceOf(PlayerHistory);
+ expect(this.result.playerHistory[0].trackedPlayers[0].players).toBe(
+ this.currentPlayers,
+ );
+ });
+ });
+ });
- this.result.pushCurrentPlayers(this.currentPlayers);
- });
+ describe("When this month's player history entry does not exist yet", function () {
+ describe("An entry for the current month is created. So,", function () {
+ beforeAll(function () {
+ this.currentPlayers = 33;
+
+ const playerHistory = [
+ {
+ year: "2022",
+ month: "10",
+ averagePlayers: 75,
+ trackedPlayers: [],
+ },
+ ];
+
+ this.game = {
+ id: 1,
+ name: "Test Game",
+ playerHistory: PlayerHistory.manyFromDbEntry(playerHistory),
+ };
- it("No new entry is created", function () {
- expect(this.result.playerHistory.length).toBe(this.historyLength);
- });
+ this.result = Game.fromDbEntry(this.game);
- it("The existing entry is updated.", function () {
- expect(this.result.playerHistory[0]).toBeInstanceOf(PlayerHistory);
- expect(this.result.playerHistory[0].trackedPlayers[0].players).toBe(
- this.currentPlayers,
- );
- });
+ this.result.pushCurrentPlayers(this.currentPlayers);
});
- });
- describe("When this month's player history entry does not exist yet", function () {
- describe("An entry for the current month is created. So,", function () {
- beforeAll(function () {
- this.currentPlayers = 33;
-
- const playerHistory = [
- {
- year: "2022",
- month: "10",
- averagePlayers: 75,
- trackedPlayers: [],
- },
- ];
-
- this.game = {
- id: 1,
- name: "Test Game",
- playerHistory: PlayerHistory.manyFromDbEntry(playerHistory),
- };
-
- this.result = Game.fromDbEntry(this.game);
-
- this.result.pushCurrentPlayers(this.currentPlayers);
- });
-
- it("this month's entry is created", function () {
- expect(this.result.playerHistory.length).toBe(2);
- expect(this.result.playerHistory[1]).toBeInstanceOf(PlayerHistory);
- });
-
- it("the last time we checked the game was played by 33 players", function () {
- expect(this.result.playerHistory[1].trackedPlayers[0].players).toBe(
- this.currentPlayers,
- );
- });
-
- it("the existing entry does not change", function () {
- expect(this.game.playerHistory[0]).toEqual(this.result.playerHistory[0]);
- });
+ it("this month's entry is created", function () {
+ expect(this.result.playerHistory.length).toBe(2);
+ expect(this.result.playerHistory[1]).toBeInstanceOf(PlayerHistory);
+ });
+
+ it("the last time we checked the game was played by 33 players", function () {
+ expect(this.result.playerHistory[1].trackedPlayers[0].players).toBe(
+ this.currentPlayers,
+ );
+ });
+
+ it("the existing entry does not change", function () {
+ expect(this.game.playerHistory[0]).toEqual(this.result.playerHistory[0]);
});
});
});
+ });
- describe(".pushSteamchartsPlayerHistory adds player histories from Steamcharts to existing entries while keeping the order intact.", function () {
- beforeAll(function () {
- const steamApp = getXSampleSteamApps(1);
-
- this.releaseDate = "";
- this.developers = [];
+ describe(".pushSteamchartsPlayerHistory adds player histories from Steamcharts to existing entries while keeping the order intact.", function () {
+ beforeAll(function () {
+ const steamApp = getXSampleSteamApps(1);
- this.result = Game.fromSteamApp(steamApp, this.releaseDate, this.developers);
+ this.result = Game.fromSteamcharts(steamApp);
- this.result.pushCurrentPlayers(513);
+ this.result.pushCurrentPlayers(513);
- const gameHistories = [];
- gameHistories.push(PlayerHistory.fromRawData(5, "April 2020"));
- gameHistories.push(PlayerHistory.fromRawData(15, "July 2020"));
- gameHistories.push(PlayerHistory.fromRawData(55, "February 2020"));
+ const gameHistories = [];
+ gameHistories.push(PlayerHistory.fromRawData(5, "April 2020"));
+ gameHistories.push(PlayerHistory.fromRawData(15, "July 2020"));
+ gameHistories.push(PlayerHistory.fromRawData(55, "February 2020"));
- this.result.pushSteamchartsPlayerHistory(gameHistories);
- });
+ this.result.pushSteamchartsPlayerHistory(gameHistories);
+ });
- it("The result is an instance of Game", function () {
- expect(this.result).toBeInstanceOf(Game);
- });
+ it("The result is an instance of Game", function () {
+ expect(this.result).toBeInstanceOf(Game);
+ });
- it("The result has a property release date, which equals an empty string", function () {
- expect(this.result.releaseDate).toBe("");
- });
+ it("The result has a property release date, which equals an empty string", function () {
+ expect(this.result.releaseDate).toBe("");
+ });
- it("The result has a property developers, which equals an empty array", function () {
- expect(this.result.developers).toEqual([]);
- });
+ it("The result has a property developers, which equals an empty array", function () {
+ expect(this.result.developers).toEqual([]);
+ });
- it("The game has three new player history entries", function () {
- expect(this.result.playerHistory.length).toBe(4);
- });
+ it("The game has three new player history entries", function () {
+ expect(this.result.playerHistory.length).toBe(4);
+ });
- it("All player history entries are in correct order", function () {
- expect(this.result.playerHistory[0].averagePlayers).toBe(55);
- expect(this.result.playerHistory[1].averagePlayers).toBe(5);
- expect(this.result.playerHistory[2].averagePlayers).toBe(15);
- expect(this.result.playerHistory[3].averagePlayers).toBe(513);
- });
+ it("All player history entries are in correct order", function () {
+ expect(this.result.playerHistory[0].averagePlayers).toBe(55);
+ expect(this.result.playerHistory[1].averagePlayers).toBe(5);
+ expect(this.result.playerHistory[2].averagePlayers).toBe(15);
+ expect(this.result.playerHistory[3].averagePlayers).toBe(513);
+ });
- it("The games player history entries are new PlayerHistory class instances", function () {
- expect(this.result.playerHistory[0]).toBeInstanceOf(PlayerHistory);
- expect(this.result.playerHistory[1]).toBeInstanceOf(PlayerHistory);
- expect(this.result.playerHistory[2]).toBeInstanceOf(PlayerHistory);
- expect(this.result.playerHistory[3]).toBeInstanceOf(PlayerHistory);
- });
+ it("The games player history entries are new PlayerHistory class instances", function () {
+ expect(this.result.playerHistory[0]).toBeInstanceOf(PlayerHistory);
+ expect(this.result.playerHistory[1]).toBeInstanceOf(PlayerHistory);
+ expect(this.result.playerHistory[2]).toBeInstanceOf(PlayerHistory);
+ expect(this.result.playerHistory[3]).toBeInstanceOf(PlayerHistory);
});
});
- describe(".updateGameDetails", function () {
- describe("When we try to update missing developers,", function () {
+ describe(".updateGameDetailsFrom", function () {
+ describe("When we try to update a game with existing developers", function () {
beforeAll(function () {
- this.developers = ["Valve", "Test Dev"];
-
this.game = getXGamesWithoutDetails(1)[0];
- this.game.updateGameDetails(this.developers, [], "");
- });
+ this.existingDevelopers = ["Valve", "Hopoo Games"];
+
+ this.game.developers = this.existingDevelopers;
- it("a game is returned.", function () {
- expect(this.game).toBeInstanceOf(Game);
+ const page = getParsedHtmlPage(riskOfRainHtmlDetailsSteamDb);
+
+ this.game.updateGameDetailsFrom(page);
});
- it("the game's developers are updated", function () {
- expect(this.game.developers).toEqual(this.developers);
+ it("the game's developers stays unchanged", function () {
+ expect(this.game.developers).toBe(this.existingDevelopers);
});
});
- describe("When we try to update existing developers,", function () {
- beforeAll(function () {
- this.game = getOneSteamAppInstantiatedGame();
+ describe("When we try to update a game with no existing developers", function () {
+ describe("and the provided html page doesn't contain a developer section", function () {
+ beforeAll(function () {
+ this.game = getXGamesWithoutDetails(1)[0];
+ const page = getParsedHtmlPage(riskOfRainHtmlDetailsPageMissingInfo);
- this.game.updateGameDetails(["Test Dev"], [], "");
- });
+ this.game.updateGameDetailsFrom(page);
+ });
- it("a game is returned.", function () {
- expect(this.game).toBeInstanceOf(Game);
+ it("the game's developers stay unchanged", function () {
+ expect(this.game.developers).toEqual([]);
+ });
});
- it("the game's developers stay the same", function () {
- expect(this.game.developers).toEqual(["Valve", "Hopoo Games"]);
+ describe("and the provided html page contains two developers,", function () {
+ beforeAll(function () {
+ this.game = getXGamesWithoutDetails(1)[0];
+ const page = getParsedHtmlPage(counterStrikeHtmlDetailsSteamDb);
+
+ this.game.updateGameDetailsFrom(page);
+ });
+
+ it("the game's developers are correctly changed", function () {
+ expect(this.game.developers).toEqual(["Valve", "Hidden Path Entertainment"]);
+ });
});
});
- describe("When we try to update the missing genres,", function () {
+ describe("When we try to update a game with existing genres", function () {
beforeAll(function () {
- this.genres = ["RPG", "Strategy"];
-
this.game = getXGamesWithoutDetails(1)[0];
- this.game.updateGameDetails([], this.genres, "");
- });
+ this.existingGenres = ["Action", "RPG"];
- it("a game is returned.", function () {
- expect(this.game).toBeInstanceOf(Game);
+ this.game.genres = this.existingGenres;
+
+ const page = getParsedHtmlPage(riskOfRainHtmlDetailsSteamDb);
+
+ this.game.updateGameDetailsFrom(page);
});
- it("the game's genres are updated", function () {
- expect(this.game.genres).toEqual(this.genres);
+ it("the game's genres stays unchanged", function () {
+ expect(this.game.genres).toBe(this.existingGenres);
});
});
- describe("When we try to update existing genres,", function () {
- beforeAll(function () {
- this.game = getOneSteamAppInstantiatedGame();
+ describe("When we try to update a game with no existing genres", function () {
+ describe("and the provided html page doesn't contain a genres section,", function () {
+ beforeAll(function () {
+ this.game = getXGamesWithoutDetails(1)[0];
+ const page = getParsedHtmlPage(riskOfRainHtmlDetailsPageMissingInfo);
- this.game.updateGameDetails([], ["Test Genre"], "");
- });
+ this.game.updateGameDetailsFrom(page);
+ });
- it("a game is returned.", function () {
- expect(this.game).toBeInstanceOf(Game);
+ it("the game's genres stay unchanged", function () {
+ expect(this.game.genres).toEqual([]);
+ });
});
- it("the game's genres stay the same", function () {
- expect(this.game.genres).toEqual(["Action", "Adventure"]);
+ describe("and the provided html page contains the genres,", function () {
+ beforeAll(function () {
+ this.game = getXGamesWithoutDetails(1)[0];
+ const page = getParsedHtmlPage(riskOfRainHtmlDetailsSteamDb);
+
+ this.game.updateGameDetailsFrom(page);
+ });
+
+ it("the game's genres are correctly changed", function () {
+ expect(this.game.genres).toEqual(["Action", "Indie"]);
+ });
});
});
- describe("When we try to update the missing description,", function () {
+ describe("When we try to update a game with an existing description", function () {
beforeAll(function () {
- this.description = "Test description";
-
this.game = getXGamesWithoutDetails(1)[0];
- this.game.updateGameDetails([], [], this.description);
- });
+ this.existingDescription = "Test description";
+
+ this.game.description = this.existingDescription;
- it("a game is returned.", function () {
- expect(this.game).toBeInstanceOf(Game);
+ const page = getParsedHtmlPage(riskOfRainHtmlDetailsSteamDb);
+
+ this.game.updateGameDetailsFrom(page);
});
- it("the game's description is updated", function () {
- expect(this.game.description).toBe(this.description);
+ it("the game's description stays unchanged", function () {
+ expect(this.game.description).toBe(this.existingDescription);
});
});
- describe("When we try to update an existing description,", function () {
- beforeAll(function () {
- this.game = getOneSteamAppInstantiatedGame();
+ describe("When we try to update a game with no existing description", function () {
+ describe("and the provided html page doesn't contain a description section,", function () {
+ beforeAll(function () {
+ this.game = getXGamesWithoutDetails(1)[0];
+ const page = getParsedHtmlPage(riskOfRainHtmlDetailsPageMissingInfo);
- this.game.updateGameDetails([], [], "Test description");
- });
+ this.game.updateGameDetailsFrom(page);
+ });
- it("a game is returned.", function () {
- expect(this.game).toBeInstanceOf(Game);
+ it("the game's description remains unchanged", function () {
+ expect(this.game.description).toEqual("");
+ });
});
- it("the game's description stays the same", function () {
- expect(this.game.description).toEqual("Best game");
+ describe("and the provided html page contains the description,", function () {
+ beforeAll(function () {
+ this.game = getXGamesWithoutDetails(1)[0];
+ const page = getParsedHtmlPage(riskOfRainHtmlDetailsSteamDb);
+
+ this.game.updateGameDetailsFrom(page);
+ });
+
+ it("the game's description is correctly changed", function () {
+ expect(this.game.description).toEqual(
+ "Escape a chaotic alien planet by fighting through hordes of frenzied monsters – with your friends, or on your own. Combine loot in surprising ways and master each character until you become the havoc you feared upon your first crash landing.",
+ );
+ });
});
});
});
describe(".updateReleaseDate", function () {
- describe("When we try to update a missing release date,", function () {
+ describe("When we try to update the date of a game with an existing release date,", function () {
beforeAll(function () {
- this.releaseDate = new Date("23 July 2023");
-
this.game = getXGamesWithoutDetails(1)[0];
+ this.existingDate = new Date("23 July 2023");
- this.game.updateReleaseDate(this.releaseDate);
- });
+ this.game.releaseDate = this.existingDate;
- it("a game is returned.", function () {
- expect(this.game).toBeInstanceOf(Game);
+ const page = getParsedHtmlPage(riskOfRainHtmlDetailsSteamDb);
+
+ this.game.updateReleaseDate(page);
});
- it("the game's release date is updated", function () {
- expect(this.game.releaseDate).toBe(this.releaseDate);
+ it("the game's release date stays unchanged", function () {
+ expect(this.game.releaseDate).toBe(this.existingDate);
});
});
- describe("When we try to update an existing release date,", function () {
- beforeAll(function () {
- this.game = getOneSteamAppInstantiatedGame();
+ describe("When we try to use a page that has no existing release date", function () {
+ describe("and the provided html page doesn't contain a valid release date,", function () {
+ beforeAll(function () {
+ this.game = getXGamesWithoutDetails(1)[0];
+ const page = getParsedHtmlPage(karmazooHtmlDetailsPageSteamDb);
+
+ this.game.updateReleaseDate(page);
+ });
- this.game.updateReleaseDate("22 July 2019");
+ it("the release date stays unchanged", function () {
+ expect(this.game.releaseDate).toBe("");
+ });
});
- it("a game is returned.", function () {
- expect(this.game).toBeInstanceOf(Game);
+ describe("and the provided html page doesn't contain a date section", function () {
+ beforeAll(function () {
+ this.game = getXGamesWithoutDetails(1)[0];
+ const page = getParsedHtmlPage(riskOfRainHtmlDetailsPageMissingInfo);
+
+ this.game.updateReleaseDate(page);
+ });
+
+ it("the release date stays unchanged", function () {
+ expect(this.game.releaseDate).toBe("");
+ });
});
- it("the game's release date stays the same", function () {
- expect(this.game.releaseDate).toBe("21 July 2019");
+ describe("and the provided html page contains a valid release date,", function () {
+ beforeAll(function () {
+ this.game = getXGamesWithoutDetails(1)[0];
+ const page = getParsedHtmlPage(riskOfRainHtmlDetailsSteamDb);
+
+ this.game.updateReleaseDate(page);
+ });
+
+ it("the release date is changed to the correct value", function () {
+ expect(this.game.releaseDate).toEqual(new Date("11 August 2020 UTC"));
+ });
});
});
});
diff --git a/backend/src/core/models/games.aggregate.js b/backend/src/core/models/games.aggregate.js
new file mode 100644
index 000000000..9e375a544
--- /dev/null
+++ b/backend/src/core/models/games.aggregate.js
@@ -0,0 +1,51 @@
+import { Game } from "./game.js";
+
+export class GamesAggregate {
+ #games;
+
+ constructor(games) {
+ this.#games = games.map((game) => Game.fromDbEntry(game));
+ }
+
+ get content() {
+ return this.#games;
+ }
+
+ get ids() {
+ return this.#games.map((game) => game.id);
+ }
+
+ get isEmpty() {
+ if (this.#games.length > 0) return false;
+
+ return true;
+ }
+
+ updateGameDetailsFrom(htmlDetailsPages) {
+ this.#games = this.#games.map((game) => {
+ const gameCopy = game.copy();
+
+ const page = this.findPageForGameById(htmlDetailsPages, gameCopy.id);
+
+ gameCopy.updateGameDetailsFrom(page);
+
+ return gameCopy;
+ });
+ }
+
+ findPageForGameById(htmlDetailsPages, gameId) {
+ return htmlDetailsPages.find((page) => gameId === page.id).page;
+ }
+
+ extractReleaseDatesFrom(htmlDetailsPages) {
+ this.#games = this.#games.map((game) => {
+ const gameCopy = game.copy();
+
+ const page = this.findPageForGameById(htmlDetailsPages, gameCopy.id);
+
+ gameCopy.updateReleaseDate(page);
+
+ return gameCopy;
+ });
+ }
+}
diff --git a/backend/src/core/models/games.aggregate.spec.js b/backend/src/core/models/games.aggregate.spec.js
new file mode 100644
index 000000000..c43f4a483
--- /dev/null
+++ b/backend/src/core/models/games.aggregate.spec.js
@@ -0,0 +1,117 @@
+import { getParsedHtmlPages } from "../../../assets/html.details.pages.mock.js";
+import { counterStrikeHtmlDetailsSteamDb } from "../../../assets/steamdb-details-pages/counter.strike.html.details.page.js";
+import { riskOfRainHtmlDetailsSteamDb } from "../../../assets/steamdb-details-pages/risk.of.rain.html.details.page.js";
+import { Game } from "./game.js";
+import {
+ getXGamesWithoutDetails,
+ getXsteamchartsInstantiatedGames,
+} from "./game.mocks.js";
+import { GamesAggregate } from "./games.aggregate.js";
+
+describe("GamesAggregate", function () {
+ describe(".getIds", () => {
+ describe("if the aggregate contains two games,", function () {
+ beforeAll(function () {
+ const games = new GamesAggregate(getXGamesWithoutDetails(2));
+
+ this.result = games.ids;
+ });
+
+ it("the games' ids are returned.", function () {
+ expect(this.result).toEqual([1, 2]);
+ });
+ });
+ });
+
+ describe(".isEmpty", function () {
+ describe("when the aggregate contains no games", function () {
+ beforeAll(function () {
+ const gamesArray = new GamesAggregate([]);
+
+ this.result = gamesArray.isEmpty;
+ });
+
+ it("the emptyness check is true", function () {
+ expect(this.result).toBeTruthy();
+ });
+ });
+
+ describe("when the aggregate contains games", function () {
+ beforeAll(function () {
+ const gamesArray = new GamesAggregate(getXGamesWithoutDetails(2));
+
+ this.result = gamesArray.isEmpty;
+ });
+
+ it("the emptyness check is false", function () {
+ expect(this.result).toBeFalsy();
+ });
+ });
+ });
+
+ describe(".updateGameDetailsFrom.", function () {
+ describe("When we try to update two games with missing details,", function () {
+ beforeAll(function () {
+ this.result = new GamesAggregate(getXGamesWithoutDetails(2));
+
+ const htmlDetailsPages = [
+ counterStrikeHtmlDetailsSteamDb,
+ riskOfRainHtmlDetailsSteamDb,
+ ];
+
+ const parsedPages = getParsedHtmlPages(htmlDetailsPages);
+
+ this.result.updateGameDetailsFrom(parsedPages);
+ });
+
+ it("the first game's details are updated", function () {
+ expect(this.result.content[0].developers).toEqual([
+ "Valve",
+ "Hidden Path Entertainment",
+ ]);
+ expect(this.result.content[0].genres).toEqual(["Action", "Free to Play"]);
+ expect(this.result.content[0].description).toBe(
+ "Counter-Strike: Global Offensive (CS: GO) expands upon the team-based action gameplay that it pioneered when it was launched 19 years ago. CS: GO features new maps, characters, weapons, and game modes, and delivers updated versions of the classic CS content (de_dust2, etc.).",
+ );
+ });
+
+ it("the second game's details are updated", function () {
+ expect(this.result.content[1].developers).toEqual(["Hopoo Games"]);
+ expect(this.result.content[1].genres).toEqual(["Action", "Indie"]);
+ expect(this.result.content[1].description).toBe(
+ "Escape a chaotic alien planet by fighting through hordes of frenzied monsters – with your friends, or on your own. Combine loot in surprising ways and master each character until you become the havoc you feared upon your first crash landing.",
+ );
+ });
+ });
+ });
+
+ describe(".extractReleaseDatesFrom.", function () {
+ describe("When we try to update two games with missing release dates,", function () {
+ beforeAll(function () {
+ const games = getXsteamchartsInstantiatedGames(2);
+ this.gamesArray = new GamesAggregate(games);
+
+ const htmlDetailsPages = [
+ counterStrikeHtmlDetailsSteamDb,
+ riskOfRainHtmlDetailsSteamDb,
+ ];
+
+ const parsedPages = getParsedHtmlPages(htmlDetailsPages);
+
+ this.gamesArray.extractReleaseDatesFrom(parsedPages);
+ });
+
+ it("the first game's release date is updated", function () {
+ expect(this.gamesArray.content[0].releaseDate).toEqual(
+ new Date("21 August 2012 UTC"),
+ );
+ });
+
+ it("the second game's release date is updated", function () {
+ expect(this.gamesArray.content[1].releaseDate).toEqual(
+ new Date("11 August 2020 UTC"),
+ );
+ });
+ });
+ });
+});
diff --git a/backend/src/core/models/player.history.mocks.js b/backend/src/core/models/player.history.mocks.js
new file mode 100644
index 000000000..eb600edcf
--- /dev/null
+++ b/backend/src/core/models/player.history.mocks.js
@@ -0,0 +1,15 @@
+import { PlayerHistory } from "./player.history.js";
+import { getXSampleTrackedPlayers } from "./tracked.players.mocks.js";
+
+const histories = [
+ {
+ year: "2020",
+ month: "September",
+ trackedPlayers: getXSampleTrackedPlayers(2),
+ averagePlayers: 105,
+ },
+];
+
+export const getSamplePlayerHistory = () => {
+ return PlayerHistory.manyFromDbEntry(histories);
+};
diff --git a/backend/src/core/models/steam.app.js b/backend/src/core/models/steam.app.js
index 975d0fec5..ad9106499 100644
--- a/backend/src/core/models/steam.app.js
+++ b/backend/src/core/models/steam.app.js
@@ -12,6 +12,14 @@ export class SteamApp {
"unknown",
]);
+ static #createValidTypesEnum(values) {
+ const enumObject = {};
+ for (const val of values) {
+ enumObject[val] = val;
+ }
+ return Object.freeze(enumObject);
+ }
+
copy() {
const copy = new SteamApp();
copy.appid = this.appid;
@@ -23,46 +31,6 @@ export class SteamApp {
return copy;
}
- triedViaSteamWeb() {
- this.triedVia.push(ValidDataSources.validDataSources.steamWeb);
- }
-
- triedViaSteamchartsWeb() {
- this.triedVia.push(ValidDataSources.validDataSources.steamcharts);
- }
-
- triedViaSteamDb() {
- this.triedVia.push(ValidDataSources.validDataSources.steamDb);
- }
-
- failedViaSteamWeb() {
- this.failedVia.push(ValidDataSources.validDataSources.steamWeb);
- }
-
- failedViaSteamchartsWeb() {
- this.failedVia.push(ValidDataSources.validDataSources.steamcharts);
- }
-
- failedViaSteamDb() {
- this.failedVia.push(ValidDataSources.validDataSources.steamDb);
- }
-
- isGame() {
- return this.type === SteamApp.validTypes.game;
- }
-
- set appType(type) {
- this.type = type;
- }
-
- static #createValidTypesEnum(values) {
- const enumObject = {};
- for (const val of values) {
- enumObject[val] = val;
- }
- return Object.freeze(enumObject);
- }
-
static manyFromSteamApi(apps) {
return apps.map((app) => SteamApp.oneFromSteamApi(app));
}
@@ -98,4 +66,62 @@ export class SteamApp {
return steamAppsSource.filter((app) => !targetAppIds.includes(app.appid));
}
+
+ get isGame() {
+ return this.type === SteamApp.validTypes.game;
+ }
+
+ recordHtmlAttempt(page, source) {
+ this.#addHtmlPageTriedViaSource(source);
+
+ if (page.toString() === "") this.#addHtmlPageFailedViaSource(source);
+ }
+
+ #addHtmlPageTriedViaSource(source) {
+ if (this.triedVia.includes(source)) return;
+
+ this.triedVia.push(source);
+ }
+
+ #addHtmlPageFailedViaSource(source) {
+ if (this.failedVia.includes(source)) return;
+
+ this.failedVia.push(source);
+ }
+
+ updateSteamAppType(page, source) {
+ this.type = this.#getType(page, source);
+ }
+
+ #getType(page, source) {
+ if (source === ValidDataSources.validDataSources.steamWeb)
+ return this.#getSteamWebAppType(page);
+ if (source === ValidDataSources.validDataSources.steamcharts)
+ return this.#getSteamchartsAppType(page);
+ }
+
+ #getSteamWebAppType(page) {
+ const breadcrumbElement = page.querySelector(".blockbg");
+
+ if (!breadcrumbElement) return SteamApp.validTypes.unknown;
+
+ const breadcrumbText = breadcrumbElement.children[0].textContent;
+
+ if (breadcrumbText !== "All Software" && breadcrumbText !== "All Games")
+ return SteamApp.validTypes.unknown;
+
+ for (let child of breadcrumbElement.children) {
+ if (child.textContent === "Downloadable Content")
+ return SteamApp.validTypes.downloadableContent;
+ }
+
+ return SteamApp.validTypes.game;
+ }
+
+ // TODO https://github.com/lukatarman/steam-game-stats/issues/178
+ #getSteamchartsAppType(page) {
+ if (page.toString() === "") return SteamApp.validTypes.unknown;
+
+ return SteamApp.validTypes.game;
+ }
}
diff --git a/backend/src/core/models/steam.app.mocks.js b/backend/src/core/models/steam.app.mocks.js
index 902395b74..3b33b491b 100644
--- a/backend/src/core/models/steam.app.mocks.js
+++ b/backend/src/core/models/steam.app.mocks.js
@@ -1,5 +1,4 @@
import { SteamApp } from "./steam.app.js";
-import { ValidDataSources } from "./valid.data.sources.js";
export const getXSampleSteamApps = (amount) => {
return Array.from({ length: amount }, (x, index) =>
@@ -7,143 +6,32 @@ export const getXSampleSteamApps = (amount) => {
);
};
-export const getThreeSteamwebUntriedFilteredSteamApps = () => {
- return [
- {
- appid: 1,
- name: "Risk of Strain",
- type: "unknown",
- triedVia: [ValidDataSources.validDataSources.steamcharts],
- failedVia: [],
- },
- {
- appid: 2,
- name: "Risk of Stain",
- type: "unknown",
- triedVia: [],
- failedVia: [],
- },
- {
- appid: 3,
- name: "Risk of Sprain",
- type: "game",
- triedVia: [ValidDataSources.validDataSources.steamcharts],
- failedVia: [],
- },
- {
- appid: 4,
- name: "Risk of Rain",
- type: "unknown",
- triedVia: [
- ValidDataSources.validDataSources.steamcharts,
- ValidDataSources.validDataSources.steamWeb,
- ],
- failedVia: [ValidDataSources.validDataSources.steamWeb],
- },
- {
- appid: 5,
- name: "Risk of Train Soundtrack",
- type: "unknown",
- triedVia: [ValidDataSources.validDataSources.steamcharts],
- failedVia: [],
- },
- {
- appid: 6,
- name: "Risk of Cane DLC",
- type: "unknown",
- triedVia: [ValidDataSources.validDataSources.steamcharts],
- failedVia: [],
- },
- {
- appid: 7,
- name: "Risk of Plain Demo",
- type: "unknown",
- triedVia: [ValidDataSources.validDataSources.steamcharts],
- failedVia: [],
- },
- {
- appid: 8,
- name: "Risk of Crane",
- type: "unknown",
- triedVia: [ValidDataSources.validDataSources.steamcharts],
- failedVia: [],
- },
- ];
+export const getThreeSourceUntriedFilteredSteamApps = (amount, source) => {
+ return Array.from({ length: amount }, (x, index) =>
+ SteamApp.oneFromSteamApi({ appid: index + 1, name: `Game #${index + 1}` }),
+ ).map((app, index) => {
+ if (isSecondFourthOrSeventhValue(index)) return app;
+
+ app.triedVia.push(source);
+ return app;
+ });
};
-export const getThreeSteamchartsUntriedFilteredSteamApps = () => {
- return [
- {
- appid: 1,
- name: "Risk of Strain",
- type: "unknown",
- triedVia: [ValidDataSources.validDataSources.steamWeb],
- failedVia: [],
- },
- {
- appid: 2,
- name: "Risk of Stain",
- type: "unknown",
- triedVia: [ValidDataSources.validDataSources.steamWeb],
- failedVia: [],
- },
- {
- appid: 3,
- name: "Risk of Gain",
- type: "unknown",
- triedVia: [ValidDataSources.validDataSources.steamWeb],
- failedVia: [ValidDataSources.validDataSources.steamWeb],
- },
- {
- appid: 4,
- name: "Risk of Sprain",
- type: "game",
- triedVia: [ValidDataSources.validDataSources.steamWeb],
- failedVia: [],
- },
- {
- appid: 5,
- name: "Risk of Rain",
- type: "unknown",
- triedVia: [ValidDataSources.validDataSources.steamcharts],
- failedVia: [],
- },
- {
- appid: 6,
- name: "Risk of Train",
- type: "unknown",
+
+export const getXSampleSteamAppsMarkedAsGames = (amount) => {
+ return Array.from({ length: amount }, (x, index) =>
+ SteamApp.oneFromDbEntry({
+ appid: index + 1,
+ name: `Game #${index + 1}`,
+ type: SteamApp.validTypes.game,
triedVia: [],
failedVia: [],
- },
- {
- appid: 7,
- name: "Risk of Cane Soundtrack",
- type: "unknown",
- triedVia: [ValidDataSources.validDataSources.steamWeb],
- failedVia: [],
- },
- {
- appid: 8,
- name: "Risk of Plain DLC",
- type: "unknown",
- triedVia: [ValidDataSources.validDataSources.steamWeb],
- failedVia: [],
- },
- {
- appid: 9,
- name: "Risk of Crane Demo",
- type: "unknown",
- triedVia: [ValidDataSources.validDataSources.steamWeb],
- failedVia: [],
- },
- {
- appid: 10,
- name: "Risk of Lane",
- type: "unknown",
- triedVia: [
- ValidDataSources.validDataSources.steamWeb,
- ValidDataSources.validDataSources.steamcharts,
- ],
- failedVia: [ValidDataSources.validDataSources.steamWeb],
- },
- ];
+ }),
+ );
+};
+
+const isSecondFourthOrSeventhValue = (index) => {
+ if (index === 1) return true;
+ if (index === 3) return true;
+ if (index === 6) return true;
+ return false;
};
diff --git a/backend/src/core/models/steam.app.spec.js b/backend/src/core/models/steam.app.spec.js
index da979d327..39cf59412 100644
--- a/backend/src/core/models/steam.app.spec.js
+++ b/backend/src/core/models/steam.app.spec.js
@@ -2,6 +2,12 @@ import { gamesMock } from "../../../assets/small.data.set.js";
import { smallestGamesMock } from "../../../assets/smallest.data.set.js";
import { ValidDataSources } from "./valid.data.sources.js";
import { SteamApp } from "./steam.app.js";
+import { getXSampleSteamApps } from "./steam.app.mocks.js";
+import { feartressGameHtmlDetailsPage } from "../../../assets/steam-details-pages/feartress.game.html.details.page.js";
+import { gta5ageRestrictedHtmlDetailsPage } from "../../../assets/steam-details-pages/gta.5.age.restricted.html.details.page.js";
+import { padakVideoHtmlDetailsPage } from "../../../assets/steam-details-pages/padak.video.html.details.page.js";
+import { theSims4dlcHtmlDetailsPage } from "../../../assets/steam-details-pages/the.sims.4.dlc.html.details.page.js";
+import { getParsedHtmlPage } from "../../../assets/html.details.pages.mock.js";
describe("SteamApp", function () {
describe(".copy", function () {
@@ -35,179 +41,6 @@ describe("SteamApp", function () {
});
});
- describe(".triedViaSteamWeb", function () {
- describe("pushes 'steamWeb' into the triedVia property. When this is done,", function () {
- beforeAll(function () {
- this.app = {
- name: "Castlevania",
- appid: 1,
- };
-
- this.result = SteamApp.oneFromSteamApi(this.app);
-
- this.result.triedViaSteamWeb();
- });
-
- it("the triedVia property array value is 'steamWeb'", function () {
- expect(this.result.triedVia[0]).toBe(ValidDataSources.validDataSources.steamWeb);
- });
- });
- });
-
- describe(".triedViaSteamchartsWeb", function () {
- describe("pushes 'steamCharts' into the triedVia property. When this is done,", function () {
- beforeAll(function () {
- this.app = {
- name: "Castlevania",
- appid: 1,
- };
-
- this.result = SteamApp.oneFromSteamApi(this.app);
-
- this.result.triedViaSteamchartsWeb();
- });
-
- it("the triedVia property array value is 'steamCharts'", function () {
- expect(this.result.triedVia[0]).toBe(
- ValidDataSources.validDataSources.steamcharts,
- );
- });
- });
- });
-
- describe(".triedViaSteamDb", function () {
- beforeAll(function () {
- this.app = {
- name: "Castlevania",
- appid: 1,
- };
-
- this.result = SteamApp.oneFromSteamApi(this.app);
-
- this.result.triedViaSteamDb();
- });
-
- it("the resulting property is 'steamDb'", function () {
- expect(this.result.triedVia[0]).toBe(ValidDataSources.validDataSources.steamDb);
- });
- });
-
- describe(".failedViaSteamWeb", function () {
- describe("pushes 'steamWeb' into the filedVia property. When this is done,", function () {
- beforeAll(function () {
- this.app = {
- name: "Castlevania",
- appid: 1,
- };
-
- this.result = SteamApp.oneFromSteamApi(this.app);
-
- this.result.failedViaSteamWeb();
- });
-
- it("the triedVia property array value is 'steamWeb'", function () {
- expect(this.result.failedVia[0]).toBe(ValidDataSources.validDataSources.steamWeb);
- });
- });
- });
-
- describe(".failedViaSteamcharts", function () {
- describe("pushes 'steamcharts' into the filedVia property. When this is done,", function () {
- beforeAll(function () {
- this.app = {
- name: "Castlevania",
- appid: 1,
- };
-
- this.result = SteamApp.oneFromSteamApi(this.app);
-
- this.result.failedViaSteamchartsWeb();
- });
-
- it("the triedVia property array value is 'steamcharts'", function () {
- expect(this.result.failedVia[0]).toBe(
- ValidDataSources.validDataSources.steamcharts,
- );
- });
- });
- });
-
- describe(".failedViaSteamDb", function () {
- describe("pushes 'steamDb' into the filedVia property. When this is done,", function () {
- beforeAll(function () {
- this.app = {
- name: "Castlevania",
- appid: 1,
- };
-
- this.result = SteamApp.oneFromSteamApi(this.app);
-
- this.result.failedViaSteamDb();
- });
-
- it("the triedVia property array value is 'steamDb'", function () {
- expect(this.result.failedVia[0]).toBe(ValidDataSources.validDataSources.steamDb);
- });
- });
- });
-
- describe(".isGame", function () {
- describe("checks if the type property of the class instance equals 'games'. So, ", function () {
- describe("if an app's type property equals 'game'", function () {
- beforeAll(function () {
- this.app = {
- name: "Castlevania",
- appid: 1,
- };
-
- this.steamApp = SteamApp.oneFromSteamApi(this.app);
- this.steamApp.type = SteamApp.validTypes.game;
- });
-
- it("the method returns true", function () {
- expect(this.steamApp.isGame()).toBeTrue();
- });
- });
-
- describe("if an app's type property does not equal 'game'", function () {
- beforeAll(function () {
- this.app = {
- name: "Castlevania",
- appid: 1,
- };
-
- this.steamApp = SteamApp.oneFromSteamApi(this.app);
- this.steamApp.type = SteamApp.validTypes.unknown;
- });
-
- it("the method returns false", function () {
- expect(this.steamApp.isGame()).toBeFalse();
- });
- });
- });
- });
-
- describe(".appType", function () {
- describe("sets the 'type' property to whatever was passed in as an argument. When this is done,", function () {
- beforeAll(function () {
- this.app = {
- name: "Castlevania",
- appid: 1,
- };
-
- this.type = SteamApp.validTypes.game;
-
- this.result = SteamApp.oneFromSteamApi(this.app);
-
- this.result.appType = this.type;
- });
-
- it("the 'type' property equals 'game'", function () {
- expect(this.result.type).toBe(SteamApp.validTypes.game);
- });
- });
- });
-
describe(".manyFromSteamApi returns an array of SteamApp instances.", function () {
describe("When two apps are passed into it,", function () {
beforeAll(function () {
@@ -412,4 +245,174 @@ describe("SteamApp", function () {
});
});
});
+
+ describe(".recordHtmlAttempt", () => {
+ describe("if the html page is not empty", function () {
+ describe("if the steamApp's triedVia doesn't already include the provided source", function () {
+ beforeAll(function () {
+ this.source = ValidDataSources.validDataSources.steamWeb;
+
+ this.steamApp = getXSampleSteamApps(1)[0];
+
+ const page = feartressGameHtmlDetailsPage;
+
+ this.steamApp.recordHtmlAttempt(page, this.source);
+ });
+
+ it("the steam app is mark as tried via steam web", function () {
+ expect(this.steamApp.triedVia).toEqual([this.source]);
+ });
+ });
+
+ describe("if the steamApp's triedVia already includes the provided source, and we try to add another", function () {
+ beforeAll(function () {
+ this.source = ValidDataSources.validDataSources.steamWeb;
+
+ this.steamApp = getXSampleSteamApps(1)[0];
+
+ const page = feartressGameHtmlDetailsPage;
+
+ this.steamApp.recordHtmlAttempt(page, this.source);
+ this.steamApp.recordHtmlAttempt(page, this.source);
+ });
+
+ it("the steam app is marked as tried via steam web only once", function () {
+ expect(this.steamApp.triedVia).toEqual([this.source]);
+ });
+ });
+ });
+
+ describe("if the html page is empty", function () {
+ describe("if the steamApp's failedVia doesn't already include steamWeb", function () {
+ beforeAll(function () {
+ this.source = ValidDataSources.validDataSources.steamWeb;
+
+ this.steamApp = getXSampleSteamApps(1)[0];
+
+ const page = "";
+
+ this.steamApp.recordHtmlAttempt(page, this.source);
+ });
+
+ it("the steam app is mark as tried via steam web", function () {
+ expect(this.steamApp.triedVia).toEqual([this.source]);
+ });
+
+ it("the steam app is marked as failed via steam web", function () {
+ expect(this.steamApp.failedVia).toEqual([this.source]);
+ });
+ });
+
+ describe("if the steamApp's failedVia already includes steamWeb and we try to add it again", function () {
+ beforeAll(function () {
+ this.source = ValidDataSources.validDataSources.steamWeb;
+
+ this.steamApp = getXSampleSteamApps(1)[0];
+
+ const page = "";
+
+ this.steamApp.recordHtmlAttempt(page, this.source);
+ this.steamApp.recordHtmlAttempt(page, this.source);
+ });
+
+ it("the steam app is mark as tried via steam web", function () {
+ expect(this.steamApp.triedVia).toEqual([this.source]);
+ });
+
+ it("the steam app is marked as failed via steam web only once", function () {
+ expect(this.steamApp.failedVia).toEqual([this.source]);
+ });
+ });
+ });
+ });
+
+ describe(".updateSteamAppType", function () {
+ describe("via steam web", function () {
+ describe("when the app is age restricted", function () {
+ beforeAll(function () {
+ this.app = getXSampleSteamApps(1)[0];
+
+ const source = ValidDataSources.validDataSources.steamWeb;
+ const page = getParsedHtmlPage(gta5ageRestrictedHtmlDetailsPage);
+
+ this.app.updateSteamAppType(page, source);
+ });
+
+ it("the app will be marked as unknown", function () {
+ expect(this.app.type).toEqual(SteamApp.validTypes.unknown);
+ });
+ });
+
+ describe("when the app does not have the appropriate text in the first breadcrumb", function () {
+ beforeAll(function () {
+ this.app = getXSampleSteamApps(1)[0];
+
+ const source = ValidDataSources.validDataSources.steamWeb;
+ const page = getParsedHtmlPage(padakVideoHtmlDetailsPage);
+
+ this.app.updateSteamAppType(page, source);
+ });
+
+ it("the app will be marked as unknown", function () {
+ expect(this.app.type).toEqual(SteamApp.validTypes.unknown);
+ });
+ });
+
+ describe("when app has 'downloadable content' in its breadcrumb", function () {
+ beforeAll(function () {
+ this.app = getXSampleSteamApps(1)[0];
+
+ const source = ValidDataSources.validDataSources.steamWeb;
+ const page = getParsedHtmlPage(theSims4dlcHtmlDetailsPage);
+
+ this.app.updateSteamAppType(page, source);
+ });
+
+ it("the app will be marked as 'Downloadable Content'", function () {
+ expect(this.app.type).toEqual(SteamApp.validTypes.downloadableContent);
+ });
+ });
+
+ describe("when the app is a game", function () {
+ beforeAll(function () {
+ this.app = getXSampleSteamApps(1)[0];
+
+ const source = ValidDataSources.validDataSources.steamWeb;
+ const page = getParsedHtmlPage(feartressGameHtmlDetailsPage);
+
+ this.app.updateSteamAppType(page, source);
+ });
+
+ it("the app will be marked as a game", function () {
+ expect(this.app.type).toEqual(SteamApp.validTypes.game);
+ });
+ });
+ });
+
+ describe("via steamcharts", function () {
+ describe("the provided html page is empty", function () {
+ beforeAll(async function () {
+ this.app = getXSampleSteamApps(1)[0];
+ const source = ValidDataSources.validDataSources.steamcharts;
+ this.app.updateSteamAppType("", source);
+ });
+
+ it("the app will be marked as unknown", function () {
+ expect(this.app.type).toBe(SteamApp.validTypes.unknown);
+ });
+ });
+
+ describe("the provided html page is not empty", function () {
+ beforeAll(async function () {
+ this.app = getXSampleSteamApps(1)[0];
+ const source = ValidDataSources.validDataSources.steamcharts;
+ this.app.updateSteamAppType(feartressGameHtmlDetailsPage, source);
+ });
+
+ it("the app will be marked as game", function () {
+ expect(this.app.type).toBe(SteamApp.validTypes.game);
+ });
+ });
+ });
+ });
});
diff --git a/backend/src/core/models/steam.apps.aggregate.js b/backend/src/core/models/steam.apps.aggregate.js
new file mode 100644
index 000000000..59e70320d
--- /dev/null
+++ b/backend/src/core/models/steam.apps.aggregate.js
@@ -0,0 +1,64 @@
+import { Game } from "./game.js";
+import { SteamApp } from "./steam.app.js";
+
+export class SteamAppsAggregate {
+ #apps;
+
+ constructor(steamApps) {
+ this.#apps = steamApps.map((app) => SteamApp.oneFromDbEntry(app));
+ }
+
+ get content() {
+ return this.#apps;
+ }
+
+ get isEmpty() {
+ if (this.#apps.length > 0) return false;
+
+ return true;
+ }
+
+ identifyTypes(htmlDetailsPages, source) {
+ this.#apps = this.#apps.map((app) => {
+ const appCopy = app.copy();
+
+ const page = this.#findSteamAppHtmlDetailsPage(htmlDetailsPages, appCopy.appid);
+
+ appCopy.recordHtmlAttempt(page, source);
+
+ appCopy.updateSteamAppType(page, source);
+
+ return appCopy;
+ });
+ }
+
+ #findSteamAppHtmlDetailsPage(htmlDetailsPages, steamAppId) {
+ return htmlDetailsPages.find((page) => steamAppId === page.id).page;
+ }
+
+ extractGames(htmlDetailsPages) {
+ return this.#apps
+ .map((app) => {
+ if (!app.isGame) return "";
+
+ const page = this.#findSteamAppHtmlDetailsPage(htmlDetailsPages, app.appid);
+
+ return Game.fromSteamApp(app, page);
+ })
+ .filter((game) => !!game);
+ }
+
+ recordAttemptsViaSource(htmlDetailsPages, source) {
+ this.#apps = this.#apps.map((app) => {
+ const appCopy = app.copy();
+ const currentPage = this.#findSteamAppHtmlDetailsPage(
+ htmlDetailsPages,
+ appCopy.appid,
+ );
+
+ appCopy.recordHtmlAttempt(currentPage, source);
+
+ return appCopy;
+ });
+ }
+}
diff --git a/backend/src/core/models/steam.apps.aggregate.spec.js b/backend/src/core/models/steam.apps.aggregate.spec.js
new file mode 100644
index 000000000..35f760cc9
--- /dev/null
+++ b/backend/src/core/models/steam.apps.aggregate.spec.js
@@ -0,0 +1,114 @@
+import { getParsedHtmlPages } from "../../../assets/html.details.pages.mock.js";
+import { feartressGameHtmlDetailsPage } from "../../../assets/steam-details-pages/feartress.game.html.details.page.js";
+import { mortalDarknessGameHtmlDetailsPage } from "../../../assets/steam-details-pages/mortal.darkness.game.html.details.page.js";
+import { SteamApp } from "./steam.app.js";
+import {
+ getXSampleSteamApps,
+ getXSampleSteamAppsMarkedAsGames,
+} from "./steam.app.mocks.js";
+import { SteamAppsAggregate } from "./steam.apps.aggregate.js";
+import { ValidDataSources } from "./valid.data.sources.js";
+
+describe("SteamAppsAggregate", function () {
+ describe(".isEmpty", function () {
+ describe("when the aggregate contains no steam apps", function () {
+ beforeAll(function () {
+ const steamAppsArray = new SteamAppsAggregate([]);
+
+ this.result = steamAppsArray.isEmpty;
+ });
+
+ it("the emptyness check returns true", function () {
+ expect(this.result).toBeTruthy();
+ });
+ });
+
+ describe("when the aggregate contains steam apps", function () {
+ beforeAll(function () {
+ const steamAppsArray = new SteamAppsAggregate(getXSampleSteamApps(2));
+
+ this.result = steamAppsArray.isEmpty;
+ });
+
+ it("the emptyness check returns false", function () {
+ expect(this.result).toBeFalsy();
+ });
+ });
+ });
+
+ describe(".identifyTypes", function () {
+ describe("When we try to identify two steam apps", function () {
+ beforeAll(function () {
+ this.steamAppsArray = new SteamAppsAggregate(getXSampleSteamApps(2));
+
+ const source = ValidDataSources.validDataSources.steamWeb;
+ const pages = getParsedHtmlPages(["", mortalDarknessGameHtmlDetailsPage]);
+
+ this.steamAppsArray.identifyTypes(pages, source);
+ });
+
+ it("the first app is correctly identified", function () {
+ expect(this.steamAppsArray.content[0].appid).toBe(1);
+ expect(this.steamAppsArray.content[0].triedVia).toEqual(["steamWeb"]);
+ expect(this.steamAppsArray.content[0].failedVia).toEqual(["steamWeb"]);
+ expect(this.steamAppsArray.content[0].type).toBe("unknown");
+ });
+
+ it("the second app is correctly identified", function () {
+ expect(this.steamAppsArray.content[1].appid).toBe(2);
+ expect(this.steamAppsArray.content[1].triedVia).toEqual(["steamWeb"]);
+ expect(this.steamAppsArray.content[1].failedVia).toEqual([]);
+ expect(this.steamAppsArray.content[1].type).toBe("game");
+ });
+ });
+ });
+
+ describe(".extractGames", function () {
+ describe("when no steam apps are marked as games", function () {
+ beforeAll(function () {
+ const steamAppsArray = new SteamAppsAggregate(getXSampleSteamApps(2));
+ const pages = getParsedHtmlPages(["", ""]);
+
+ this.result = steamAppsArray.extractGames(pages);
+ });
+
+ it("no games are returned", function () {
+ expect(this.result).toEqual([]);
+ });
+ });
+
+ describe("when one out of two steam apps is marked as a game", function () {
+ beforeAll(function () {
+ const steamAppsArray = new SteamAppsAggregate(getXSampleSteamApps(2));
+ const source = ValidDataSources.validDataSources.steamWeb;
+ const pages = getParsedHtmlPages(["", mortalDarknessGameHtmlDetailsPage]);
+
+ steamAppsArray.identifyTypes(pages, source);
+
+ this.result = steamAppsArray.extractGames(pages);
+ });
+
+ it("one game is returned", function () {
+ expect(this.result.length).toBe(1);
+ });
+ });
+
+ describe("when two out of two steam apps are marked as games", function () {
+ beforeAll(function () {
+ const steamAppsArray = new SteamAppsAggregate(
+ getXSampleSteamAppsMarkedAsGames(2),
+ );
+ const pages = getParsedHtmlPages([
+ feartressGameHtmlDetailsPage,
+ mortalDarknessGameHtmlDetailsPage,
+ ]);
+
+ this.result = steamAppsArray.extractGames(pages);
+ });
+
+ it("two games are returned", function () {
+ expect(this.result.length).toBe(2);
+ });
+ });
+ });
+});
diff --git a/backend/src/core/models/tracked.players.mocks.js b/backend/src/core/models/tracked.players.mocks.js
new file mode 100644
index 000000000..b8a173db1
--- /dev/null
+++ b/backend/src/core/models/tracked.players.mocks.js
@@ -0,0 +1,11 @@
+import { TrackedPlayers } from "./tracked.players.js";
+
+export const getXSampleTrackedPlayers = (amount) => {
+ const samplePlayerAmount = amount * 12;
+ const sampleDateTimestamp = 1598911200000 + amount * 86400000;
+
+ return Array.from(
+ { length: amount },
+ (x, index) => new TrackedPlayers(samplePlayerAmount, sampleDateTimestamp),
+ );
+};
diff --git a/backend/src/core/repositories/games.repository.js b/backend/src/core/repositories/games.repository.js
index 288515e85..8883014e8 100644
--- a/backend/src/core/repositories/games.repository.js
+++ b/backend/src/core/repositories/games.repository.js
@@ -1,5 +1,6 @@
import { Game } from "../models/game.js";
import { daysToMs } from "../../common/time.utils.js";
+import { GamesAggregate } from "../models/games.aggregate.js";
export class GamesRepository {
#dbClient;
@@ -21,26 +22,26 @@ export class GamesRepository {
}
async getGamesWithoutDetails(amount) {
- return (
- await this.#dbClient
- .get("games")
- .aggregate([
- {
- $match: {
- $or: [
- { developers: { $eq: [] } },
- { genres: { $eq: [] } },
- { description: { $eq: "" } },
- ],
- },
+ const response = await this.#dbClient
+ .get("games")
+ .aggregate([
+ {
+ $match: {
+ $or: [
+ { developers: { $eq: [] } },
+ { genres: { $eq: [] } },
+ { description: { $eq: "" } },
+ ],
},
- { $limit: amount },
- ])
- .toArray()
- ).map((dbEntry) => Game.fromDbEntry(dbEntry));
+ },
+ { $limit: amount },
+ ])
+ .toArray();
+
+ return new GamesAggregate(response);
}
- async updateGameDetails(games) {
+ async updateGameDetailsFrom(games) {
await Promise.all(
games.map((game) =>
this.#dbClient.updateOne(
@@ -59,19 +60,19 @@ export class GamesRepository {
}
async getGamesWithoutReleaseDates(amount) {
- return (
- await this.#dbClient
- .get("games")
- .aggregate([
- {
- $match: {
- $or: [{ releaseDate: { $eq: "" } }, { releaseDate: { $gt: new Date() } }],
- },
+ const response = await this.#dbClient
+ .get("games")
+ .aggregate([
+ {
+ $match: {
+ $or: [{ releaseDate: { $eq: "" } }, { releaseDate: { $gt: new Date() } }],
},
- { $limit: amount },
- ])
- .toArray()
- ).map((dbEntry) => Game.fromDbEntry(dbEntry));
+ },
+ { $limit: amount },
+ ])
+ .toArray();
+
+ return new GamesAggregate(response);
}
async updateReleaseDates(games) {
diff --git a/backend/src/core/repositories/games.repository.spec.js b/backend/src/core/repositories/games.repository.spec.js
index 85e6a13dd..a34e0e446 100644
--- a/backend/src/core/repositories/games.repository.spec.js
+++ b/backend/src/core/repositories/games.repository.spec.js
@@ -9,6 +9,7 @@ import {
getTrendingGamesMockData,
} from "../models/game.mocks.js";
import { Game } from "../models/game.js";
+import { GamesAggregate } from "../models/games.aggregate.js";
describe("GamesRepository", function () {
describe(".insertManyGames inserts multiple games into the collection.", function () {
@@ -141,34 +142,38 @@ describe("GamesRepository", function () {
this.databaseClient.disconnect();
});
+ it("the result is an instance of GamesAggregate", function () {
+ expect(this.result).toBeInstanceOf(GamesAggregate);
+ });
+
it("three games are returned", function () {
- expect(this.result.length).toBe(3);
+ expect(this.result.content.length).toBe(3);
});
it("the games are an instance of Game", function () {
- expect(this.result[0]).toBeInstanceOf(Game);
- expect(this.result[1]).toBeInstanceOf(Game);
- expect(this.result[2]).toBeInstanceOf(Game);
+ expect(this.result.content[0]).toBeInstanceOf(Game);
+ expect(this.result.content[1]).toBeInstanceOf(Game);
+ expect(this.result.content[2]).toBeInstanceOf(Game);
});
it("the first game is missing the developers", function () {
- expect(this.result[0].id).toBe(232090);
- expect(this.result[0].developers).toEqual([]);
+ expect(this.result.content[0].id).toBe(232090);
+ expect(this.result.content[0].developers).toEqual([]);
});
it("the second game is missing the genres", function () {
- expect(this.result[1].id).toBe(881100);
- expect(this.result[1].genres).toEqual([]);
+ expect(this.result.content[1].id).toBe(881100);
+ expect(this.result.content[1].genres).toEqual([]);
});
it("the third game is missing the description", function () {
- expect(this.result[2].id).toBe(620);
- expect(this.result[2].description).toEqual("");
+ expect(this.result.content[2].id).toBe(620);
+ expect(this.result.content[2].description).toEqual("");
});
});
});
- describe(".updateGameDetails", function () {
+ describe(".updateGameDetailsFrom", function () {
describe("When the details of 1 game are to be updated,", function () {
beforeAll(async function () {
this.databaseClient = await initiateInMemoryDatabase(["games"]);
@@ -179,7 +184,7 @@ describe("GamesRepository", function () {
this.games = getOneGameWithDetails();
- await gamesRepo.updateGameDetails(this.games);
+ await gamesRepo.updateGameDetailsFrom(this.games);
this.result = await gamesRepo.getOneGameById(this.games[0].id);
});
@@ -213,29 +218,33 @@ describe("GamesRepository", function () {
this.databaseClient.disconnect();
});
+ it("the result is an instance of GamesAggregate", function () {
+ expect(this.result).toBeInstanceOf(GamesAggregate);
+ });
+
it("three games are returned", function () {
- expect(this.result.length).toBe(3);
+ expect(this.result.content.length).toBe(3);
});
it("the games are an instance of Game", function () {
- expect(this.result[0]).toBeInstanceOf(Game);
- expect(this.result[1]).toBeInstanceOf(Game);
- expect(this.result[2]).toBeInstanceOf(Game);
+ expect(this.result.content[0]).toBeInstanceOf(Game);
+ expect(this.result.content[1]).toBeInstanceOf(Game);
+ expect(this.result.content[2]).toBeInstanceOf(Game);
});
it("the first game has the correct date", function () {
- expect(this.result[0].id).toBe(227300);
- expect(this.result[0].releaseDate).toEqual(new Date("Thu Oct 17 2999"));
+ expect(this.result.content[0].id).toBe(227300);
+ expect(this.result.content[0].releaseDate).toEqual(new Date("Thu Oct 17 2999"));
});
it("the second game is missing the release date", function () {
- expect(this.result[1].id).toBe(2218750);
- expect(this.result[1].releaseDate).toBe("");
+ expect(this.result.content[1].id).toBe(2218750);
+ expect(this.result.content[1].releaseDate).toBe("");
});
it("the third game is missing the release date", function () {
- expect(this.result[2].id).toBe(239140);
- expect(this.result[2].releaseDate).toBe("");
+ expect(this.result.content[2].id).toBe(239140);
+ expect(this.result.content[2].releaseDate).toBe("");
});
});
});
diff --git a/backend/src/core/repositories/steam.apps.repository.js b/backend/src/core/repositories/steam.apps.repository.js
index cd848f575..1f8deb57e 100644
--- a/backend/src/core/repositories/steam.apps.repository.js
+++ b/backend/src/core/repositories/steam.apps.repository.js
@@ -1,5 +1,5 @@
import { SteamApp } from "../models/steam.app.js";
-import { ValidDataSources } from "../models/valid.data.sources.js";
+import { SteamAppsAggregate } from "../models/steam.apps.aggregate.js";
export class SteamAppsRepository {
#dbClient;
@@ -42,12 +42,13 @@ export class SteamAppsRepository {
);
}
- async getSteamWebUntriedFilteredSteamApps(amount) {
- const response = await this.#steamAppsCollection
+ async getSourceUntriedFilteredSteamApps(amount, source) {
+ const response = await this.#dbClient
+ .get("steam_apps")
.find({
$and: [
{ type: SteamApp.validTypes.unknown },
- { triedVia: { $ne: ValidDataSources.validDataSources.steamWeb } },
+ { triedVia: { $ne: source } },
{ name: { $not: { $regex: /soundtrack$/, $options: "i" } } },
{ name: { $not: { $regex: /dlc$/, $options: "i" } } },
{ name: { $not: { $regex: /demo$/, $options: "i" } } },
@@ -56,35 +57,13 @@ export class SteamAppsRepository {
.limit(amount)
.toArray();
- return SteamApp.manyFromDbEntries(response);
- }
-
- async getSteamchartsUntriedFilteredSteamApps(amount) {
- const response = await this.#steamAppsCollection
- .find({
- $and: [
- { type: SteamApp.validTypes.unknown },
- {
- $and: [
- { triedVia: { $ne: ValidDataSources.validDataSources.steamcharts } },
- { triedVia: ValidDataSources.validDataSources.steamWeb },
- ],
- },
- { name: { $not: { $regex: /soundtrack$/, $options: "i" } } },
- { name: { $not: { $regex: /dlc$/, $options: "i" } } },
- { name: { $not: { $regex: /demo$/, $options: "i" } } },
- ],
- })
- .limit(amount)
- .toArray();
-
- return SteamApp.manyFromDbEntries(response);
+ return new SteamAppsAggregate(response);
}
async getSteamAppsById(ids) {
const response = await Promise.all(ids.map((id) => this.getSteamAppById(id)));
- return SteamApp.manyFromDbEntries(response);
+ return new SteamAppsAggregate(response);
}
async getSteamAppById(id) {
diff --git a/backend/src/core/repositories/steam.apps.repository.spec.js b/backend/src/core/repositories/steam.apps.repository.spec.js
index 4b713d8f5..c8de5442b 100644
--- a/backend/src/core/repositories/steam.apps.repository.spec.js
+++ b/backend/src/core/repositories/steam.apps.repository.spec.js
@@ -1,13 +1,13 @@
import { getXGamesWithoutDetails } from "../models/game.mocks.js";
import { SteamApp } from "../models/steam.app.js";
import {
- getThreeSteamchartsUntriedFilteredSteamApps,
- getThreeSteamwebUntriedFilteredSteamApps,
+ getThreeSourceUntriedFilteredSteamApps,
getXSampleSteamApps,
} from "../models/steam.app.mocks.js";
import { ValidDataSources } from "../models/valid.data.sources.js";
import { initiateInMemoryDatabase } from "../../adapters/driven/db/in.memory.database.client.js";
import { SteamAppsRepository } from "./steam.apps.repository.js";
+import { SteamAppsAggregate } from "../models/steam.apps.aggregate.js";
describe("SteamAppsRepository", function () {
describe(".insertManyIfNotExist inserts all the non existing steam apps from a given array", function () {
@@ -211,366 +211,240 @@ describe("SteamAppsRepository", function () {
});
});
- describe(".getSteamWebUntriedFilteredSteamApps.", function () {
- describe("If three steam apps out of eigth match the filters, and the amount of 2 is provided", function () {
- beforeAll(async function () {
- this.databaseClient = await initiateInMemoryDatabase(["steam_apps"]);
-
- await insertManyApps(
- this.databaseClient,
- getThreeSteamwebUntriedFilteredSteamApps(),
- );
-
- const steamAppsRepo = new SteamAppsRepository(this.databaseClient);
-
- this.result = await steamAppsRepo.getSteamWebUntriedFilteredSteamApps(2);
- });
-
- afterAll(function () {
- this.databaseClient.disconnect();
- });
-
- it("the result has two games", function () {
- expect(this.result.length).toBe(2);
- });
-
- it("the first result is an instance of SteamApp", function () {
- expect(this.result[0]).toBeInstanceOf(SteamApp);
- });
-
- it("the first array has the correct values", function () {
- expect(this.result[0].appid).toBe(1);
- expect(this.result[0].name).toBe("Risk of Strain");
- expect(this.result[0].type).toBe("unknown");
- expect(this.result[0].triedVia[0]).toBe(
- ValidDataSources.validDataSources.steamcharts,
- );
- expect(this.result[0].failedVia).toEqual([]);
- });
-
- it("the second result is an instance of SteamApp", function () {
- expect(this.result[1]).toBeInstanceOf(SteamApp);
- });
-
- it("the second array has the correct values", function () {
- expect(this.result[1].appid).toBe(2);
- expect(this.result[1].name).toBe("Risk of Stain");
- expect(this.result[1].type).toBe("unknown");
- expect(this.result[1].triedVia).toEqual([]);
- expect(this.result[1].failedVia).toEqual([]);
+ describe(".getSourceUntriedFilteredSteamApps.", function () {
+ describe("via SteamWeb source", function () {
+ describe("If three steam apps out of eigth match the filters,", function () {
+ describe("and a limit of 2 is provided", function () {
+ beforeAll(async function () {
+ this.databaseClient = await initiateInMemoryDatabase(["steam_apps"]);
+
+ const source = ValidDataSources.validDataSources.steamWeb;
+
+ await insertManyApps(
+ this.databaseClient,
+ getThreeSourceUntriedFilteredSteamApps(8, source),
+ );
+
+ const steamAppsRepo = new SteamAppsRepository(this.databaseClient);
+
+ this.result = await steamAppsRepo.getSourceUntriedFilteredSteamApps(
+ 2,
+ source,
+ );
+ });
+
+ afterAll(function () {
+ this.databaseClient.disconnect();
+ });
+
+ it("the result is an instance of SteamAppsAggregate", function () {
+ expect(this.result).toBeInstanceOf(SteamAppsAggregate);
+ });
+
+ it("the result contains two steam apps", function () {
+ expect(this.result.content.length).toBe(2);
+ });
+
+ it("the first steam app is an instance of SteamApp", function () {
+ expect(this.result.content[0]).toBeInstanceOf(SteamApp);
+ });
+
+ it("the first steam app has the correct values", function () {
+ expect(this.result.content[0].appid).toBe(2);
+ expect(this.result.content[0].type).toBe("unknown");
+ expect(this.result.content[0].triedVia).toEqual([]);
+ });
+
+ it("the second steam app is an instance of SteamApp", function () {
+ expect(this.result.content[1]).toBeInstanceOf(SteamApp);
+ });
+
+ it("the second steam app has the correct values", function () {
+ expect(this.result.content[1].appid).toBe(4);
+ expect(this.result.content[1].type).toBe("unknown");
+ expect(this.result.content[1].triedVia).toEqual([]);
+ });
+ });
+
+ describe("and the amount of 0 is provided", function () {
+ beforeAll(async function () {
+ this.databaseClient = await initiateInMemoryDatabase(["steam_apps"]);
+
+ const source = ValidDataSources.validDataSources.steamWeb;
+
+ await insertManyApps(
+ this.databaseClient,
+ getThreeSourceUntriedFilteredSteamApps(8, source),
+ );
+
+ const steamAppsRepo = new SteamAppsRepository(this.databaseClient);
+
+ this.result = await steamAppsRepo.getSourceUntriedFilteredSteamApps(
+ 0,
+ source,
+ );
+ });
+
+ afterAll(function () {
+ this.databaseClient.disconnect();
+ });
+
+ it("the result is an instance of SteamAppsAggregate", function () {
+ expect(this.result).toBeInstanceOf(SteamAppsAggregate);
+ });
+
+ it("the result contains three steam apps", function () {
+ expect(this.result.content.length).toBe(3);
+ });
+
+ it("the first steam app an instance of SteamApp", function () {
+ expect(this.result.content[0]).toBeInstanceOf(SteamApp);
+ });
+
+ it("the first steam app has the correct values", function () {
+ expect(this.result.content[0].appid).toBe(2);
+ expect(this.result.content[0].type).toBe("unknown");
+ expect(this.result.content[0].triedVia).toEqual([]);
+ });
+
+ it("the second steam app is an instance of SteamApp", function () {
+ expect(this.result.content[1]).toBeInstanceOf(SteamApp);
+ });
+
+ it("the second steam app has the correct values", function () {
+ expect(this.result.content[1].appid).toBe(4);
+ expect(this.result.content[1].type).toBe("unknown");
+ expect(this.result.content[1].triedVia).toEqual([]);
+ });
+
+ it("the third steam app is an instance of SteamApp", function () {
+ expect(this.result.content[2]).toBeInstanceOf(SteamApp);
+ });
+
+ it("the third steam app has the correct values", function () {
+ expect(this.result.content[2].appid).toBe(7);
+ expect(this.result.content[2].type).toBe("unknown");
+ expect(this.result.content[2].triedVia).toEqual([]);
+ });
+ });
});
});
- describe("If three steam apps out of eigth match the filters, and the amount of 4 is provided", function () {
- beforeAll(async function () {
- this.databaseClient = await initiateInMemoryDatabase(["steam_apps"]);
-
- await insertManyApps(
- this.databaseClient,
- getThreeSteamwebUntriedFilteredSteamApps(),
- );
-
- const steamAppsRepo = new SteamAppsRepository(this.databaseClient);
-
- this.result = await steamAppsRepo.getSteamWebUntriedFilteredSteamApps(4);
- });
-
- afterAll(function () {
- this.databaseClient.disconnect();
- });
-
- it("the resulting array has a length of 3", function () {
- expect(this.result.length).toBe(3);
- });
-
- it("the first result is an instance of SteamApp", function () {
- expect(this.result[0]).toBeInstanceOf(SteamApp);
- });
-
- it("the first array has the correct values", function () {
- expect(this.result[0].appid).toBe(1);
- expect(this.result[0].name).toBe("Risk of Strain");
- expect(this.result[0].type).toBe("unknown");
- expect(this.result[0].triedVia[0]).toBe(
- ValidDataSources.validDataSources.steamcharts,
- );
- expect(this.result[0].failedVia).toEqual([]);
- });
-
- it("the second result is an instance of SteamApp", function () {
- expect(this.result[1]).toBeInstanceOf(SteamApp);
- });
-
- it("the second array has the correct values", function () {
- expect(this.result[1].appid).toBe(2);
- expect(this.result[1].name).toBe("Risk of Stain");
- expect(this.result[1].type).toBe("unknown");
- expect(this.result[1].triedVia).toEqual([]);
- expect(this.result[1].failedVia).toEqual([]);
- });
-
- it("the third result is an instance of SteamApp", function () {
- expect(this.result[2]).toBeInstanceOf(SteamApp);
- });
-
- it("the third array has the correct values", function () {
- expect(this.result[2].appid).toBe(8);
- expect(this.result[2].name).toBe("Risk of Crane");
- expect(this.result[2].type).toBe("unknown");
- expect(this.result[2].triedVia[0]).toBe(
- ValidDataSources.validDataSources.steamcharts,
- );
- expect(this.result[2].failedVia).toEqual([]);
- });
- });
-
- describe("If an amount of '0' is provided,", function () {
- beforeAll(async function () {
- this.databaseClient = await initiateInMemoryDatabase(["steam_apps"]);
-
- await insertManyApps(
- this.databaseClient,
- getThreeSteamwebUntriedFilteredSteamApps(),
- );
-
- const steamAppsRepo = new SteamAppsRepository(this.databaseClient);
-
- this.result = await steamAppsRepo.getSteamWebUntriedFilteredSteamApps(0);
- });
-
- afterAll(function () {
- this.databaseClient.disconnect();
- });
-
- it("the resulting array has a length of 3", function () {
- expect(this.result.length).toBe(3);
- });
-
- it("the first result is an instance of SteamApp", function () {
- expect(this.result[0]).toBeInstanceOf(SteamApp);
- });
-
- it("the first array has the correct values", function () {
- expect(this.result[0].appid).toBe(1);
- expect(this.result[0].name).toBe("Risk of Strain");
- expect(this.result[0].type).toBe("unknown");
- expect(this.result[0].triedVia[0]).toBe(
- ValidDataSources.validDataSources.steamcharts,
- );
- expect(this.result[0].failedVia).toEqual([]);
- });
-
- it("the second result is an instance of SteamApp", function () {
- expect(this.result[1]).toBeInstanceOf(SteamApp);
- });
-
- it("the second array has the correct values", function () {
- expect(this.result[1].appid).toBe(2);
- expect(this.result[1].name).toBe("Risk of Stain");
- expect(this.result[1].type).toBe("unknown");
- expect(this.result[1].triedVia).toEqual([]);
- expect(this.result[1].failedVia).toEqual([]);
- });
-
- it("the third result is an instance of SteamApp", function () {
- expect(this.result[2]).toBeInstanceOf(SteamApp);
- });
-
- it("the third array has the correct values", function () {
- expect(this.result[2].appid).toBe(8);
- expect(this.result[2].name).toBe("Risk of Crane");
- expect(this.result[2].type).toBe("unknown");
- expect(this.result[2].triedVia[0]).toBe(
- ValidDataSources.validDataSources.steamcharts,
- );
- expect(this.result[2].failedVia).toEqual([]);
- });
- });
- });
-
- describe(".getSteamchartsUntriedFilteredSteamApps.", function () {
- describe("If three steam apps out of ten match the filters, and the amount of 2 is provided", function () {
- beforeAll(async function () {
- this.databaseClient = await initiateInMemoryDatabase(["steam_apps"]);
-
- await insertManyApps(
- this.databaseClient,
- getThreeSteamchartsUntriedFilteredSteamApps(),
- );
-
- const steamAppsRepo = new SteamAppsRepository(this.databaseClient);
-
- this.result = await steamAppsRepo.getSteamchartsUntriedFilteredSteamApps(2);
- });
-
- afterAll(function () {
- this.databaseClient.disconnect();
- });
-
- it("the result has two games", function () {
- expect(this.result.length).toBe(2);
- });
-
- it("the first result is an instance of SteamApp", function () {
- expect(this.result[0]).toBeInstanceOf(SteamApp);
- });
-
- it("the first array has the correct values", function () {
- expect(this.result[0].appid).toBe(1);
- expect(this.result[0].name).toBe("Risk of Strain");
- expect(this.result[0].type).toBe("unknown");
- expect(this.result[0].triedVia[0]).toBe(
- ValidDataSources.validDataSources.steamWeb,
- );
- expect(this.result[0].failedVia).toEqual([]);
- });
-
- it("the second result is an instance of SteamApp", function () {
- expect(this.result[1]).toBeInstanceOf(SteamApp);
- });
-
- it("the second array has the correct values", function () {
- expect(this.result[1].appid).toBe(2);
- expect(this.result[1].name).toBe("Risk of Stain");
- expect(this.result[1].type).toBe("unknown");
- expect(this.result[1].triedVia[0]).toBe(
- ValidDataSources.validDataSources.steamWeb,
- );
- expect(this.result[1].failedVia).toEqual([]);
- });
- });
-
- describe("If three steam apps out of ten match the filters, and the amount of 4 is provided", function () {
- beforeAll(async function () {
- this.databaseClient = await initiateInMemoryDatabase(["steam_apps"]);
-
- await insertManyApps(
- this.databaseClient,
- getThreeSteamchartsUntriedFilteredSteamApps(),
- );
-
- const steamAppsRepo = new SteamAppsRepository(this.databaseClient);
-
- this.result = await steamAppsRepo.getSteamchartsUntriedFilteredSteamApps(4);
- });
-
- afterAll(function () {
- this.databaseClient.disconnect();
- });
-
- it("the resulting array has a length of 3", function () {
- expect(this.result.length).toBe(3);
- });
-
- it("the first result is an instance of SteamApp", function () {
- expect(this.result[0]).toBeInstanceOf(SteamApp);
- });
-
- it("the first array has the correct values", function () {
- expect(this.result[0].appid).toBe(1);
- expect(this.result[0].name).toBe("Risk of Strain");
- expect(this.result[0].type).toBe("unknown");
- expect(this.result[0].triedVia[0]).toBe(
- ValidDataSources.validDataSources.steamWeb,
- );
- expect(this.result[0].failedVia).toEqual([]);
- });
-
- it("the second result is an instance of SteamApp", function () {
- expect(this.result[1]).toBeInstanceOf(SteamApp);
- });
-
- it("the second array has the correct values", function () {
- expect(this.result[1].appid).toBe(2);
- expect(this.result[1].name).toBe("Risk of Stain");
- expect(this.result[1].type).toBe("unknown");
- expect(this.result[1].triedVia[0]).toBe(
- ValidDataSources.validDataSources.steamWeb,
- );
- expect(this.result[1].failedVia).toEqual([]);
- });
-
- it("the third result is an instance of SteamApp", function () {
- expect(this.result[2]).toBeInstanceOf(SteamApp);
- });
-
- it("the third array has the correct values", function () {
- expect(this.result[2].appid).toBe(3);
- expect(this.result[2].name).toBe("Risk of Gain");
- expect(this.result[2].type).toBe("unknown");
- expect(this.result[2].triedVia[0]).toBe(
- ValidDataSources.validDataSources.steamWeb,
- );
- expect(this.result[2].failedVia).toEqual([
- ValidDataSources.validDataSources.steamWeb,
- ]);
- });
- });
-
- describe("If '0' amount is provided,", function () {
- beforeAll(async function () {
- this.databaseClient = await initiateInMemoryDatabase(["steam_apps"]);
-
- await insertManyApps(
- this.databaseClient,
- getThreeSteamchartsUntriedFilteredSteamApps(),
- );
-
- const steamAppsRepo = new SteamAppsRepository(this.databaseClient);
-
- this.result = await steamAppsRepo.getSteamchartsUntriedFilteredSteamApps(0);
- });
-
- afterAll(function () {
- this.databaseClient.disconnect();
- });
-
- it("the resulting array has a length of 3", function () {
- expect(this.result.length).toBe(3);
- });
-
- it("the first result is an instance of SteamApp", function () {
- expect(this.result[0]).toBeInstanceOf(SteamApp);
- });
-
- it("the first array has the correct values", function () {
- expect(this.result[0].appid).toBe(1);
- expect(this.result[0].name).toBe("Risk of Strain");
- expect(this.result[0].type).toBe("unknown");
- expect(this.result[0].triedVia[0]).toBe(
- ValidDataSources.validDataSources.steamWeb,
- );
- expect(this.result[0].failedVia).toEqual([]);
- });
-
- it("the second result is an instance of SteamApp", function () {
- expect(this.result[1]).toBeInstanceOf(SteamApp);
- });
-
- it("the second array has the correct values", function () {
- expect(this.result[1].appid).toBe(2);
- expect(this.result[1].name).toBe("Risk of Stain");
- expect(this.result[1].type).toBe("unknown");
- expect(this.result[1].triedVia[0]).toBe(
- ValidDataSources.validDataSources.steamWeb,
- );
- expect(this.result[1].failedVia).toEqual([]);
- });
-
- it("the third result is an instance of SteamApp", function () {
- expect(this.result[2]).toBeInstanceOf(SteamApp);
- });
-
- it("the third array has the correct values", function () {
- expect(this.result[2].appid).toBe(3);
- expect(this.result[2].name).toBe("Risk of Gain");
- expect(this.result[2].type).toBe("unknown");
- expect(this.result[2].triedVia[0]).toBe(
- ValidDataSources.validDataSources.steamWeb,
- );
- expect(this.result[2].failedVia[0]).toBe(
- ValidDataSources.validDataSources.steamWeb,
- );
+ describe("via Steamcharts source", function () {
+ describe("If three steam apps out of eigth match the filters,", function () {
+ describe("and the limit of 2 is provided", function () {
+ beforeAll(async function () {
+ this.databaseClient = await initiateInMemoryDatabase(["steam_apps"]);
+
+ const source = ValidDataSources.validDataSources.steamcharts;
+
+ await insertManyApps(
+ this.databaseClient,
+ getThreeSourceUntriedFilteredSteamApps(8, source),
+ );
+
+ const steamAppsRepo = new SteamAppsRepository(this.databaseClient);
+
+ this.result = await steamAppsRepo.getSourceUntriedFilteredSteamApps(
+ 2,
+ source,
+ );
+ });
+
+ afterAll(function () {
+ this.databaseClient.disconnect();
+ });
+
+ it("the result is an instance of SteamAppsAggregate", function () {
+ expect(this.result).toBeInstanceOf(SteamAppsAggregate);
+ });
+
+ it("the result contains two steam app", function () {
+ expect(this.result.content.length).toBe(2);
+ });
+
+ it("the first steam app is an instance of SteamApp", function () {
+ expect(this.result.content[0]).toBeInstanceOf(SteamApp);
+ });
+
+ it("the first steam apphas the correct values", function () {
+ expect(this.result.content[0].appid).toBe(2);
+ expect(this.result.content[0].type).toBe("unknown");
+ expect(this.result.content[0].triedVia).toEqual([]);
+ });
+
+ it("the second steam app is an instance of SteamApp", function () {
+ expect(this.result.content[1]).toBeInstanceOf(SteamApp);
+ });
+
+ it("the second steam app has the correct values", function () {
+ expect(this.result.content[1].appid).toBe(4);
+ expect(this.result.content[1].type).toBe("unknown");
+ expect(this.result.content[1].triedVia).toEqual([]);
+ });
+ });
+
+ describe("and the limit of 0 is provided", function () {
+ beforeAll(async function () {
+ this.databaseClient = await initiateInMemoryDatabase(["steam_apps"]);
+
+ const source = ValidDataSources.validDataSources.steamcharts;
+
+ await insertManyApps(
+ this.databaseClient,
+ getThreeSourceUntriedFilteredSteamApps(8, source),
+ );
+
+ const steamAppsRepo = new SteamAppsRepository(this.databaseClient);
+
+ this.result = await steamAppsRepo.getSourceUntriedFilteredSteamApps(
+ 0,
+ source,
+ );
+ });
+
+ afterAll(function () {
+ this.databaseClient.disconnect();
+ });
+
+ it("the result is an instance of SteamAppsAggregate", function () {
+ expect(this.result).toBeInstanceOf(SteamAppsAggregate);
+ });
+
+ it("the result contains three steam apps", function () {
+ expect(this.result.content.length).toBe(3);
+ });
+
+ it("the first steam app is an instance of SteamApp", function () {
+ expect(this.result.content[0]).toBeInstanceOf(SteamApp);
+ });
+
+ it("the first steam app has the correct values", function () {
+ expect(this.result.content[0].appid).toBe(2);
+ expect(this.result.content[0].type).toBe("unknown");
+ expect(this.result.content[0].triedVia).toEqual([]);
+ });
+
+ it("the second steam app is an instance of SteamApp", function () {
+ expect(this.result.content[1]).toBeInstanceOf(SteamApp);
+ });
+
+ it("the second steam app has the correct values", function () {
+ expect(this.result.content[1].appid).toBe(4);
+ expect(this.result.content[1].type).toBe("unknown");
+ expect(this.result.content[1].triedVia).toEqual([]);
+ });
+
+ it("the third steam app is an instance of SteamApp", function () {
+ expect(this.result.content[2]).toBeInstanceOf(SteamApp);
+ });
+
+ it("the third steam app has the correct values", function () {
+ expect(this.result.content[2].appid).toBe(7);
+ expect(this.result.content[2].type).toBe("unknown");
+ expect(this.result.content[2].triedVia).toEqual([]);
+ });
+ });
});
});
});
@@ -593,21 +467,25 @@ describe("SteamAppsRepository", function () {
this.databaseClient.disconnect();
});
+ it("the result is an instance of SteamAppsAggregate", function () {
+ expect(this.result).toBeInstanceOf(SteamAppsAggregate);
+ });
+
it("two steam apps are returned", function () {
- expect(this.result.length).toBe(2);
+ expect(this.result.content.length).toBe(2);
});
it("the steam apps are an instance of SteamApp", function () {
- expect(this.result[0]).toBeInstanceOf(SteamApp);
- expect(this.result[1]).toBeInstanceOf(SteamApp);
+ expect(this.result.content[0]).toBeInstanceOf(SteamApp);
+ expect(this.result.content[1]).toBeInstanceOf(SteamApp);
});
it("the first steam app has the correct values", function () {
- expect(this.result[0].appid).toBe(1);
+ expect(this.result.content[0].appid).toBe(1);
});
it("the second steam app has the correct values", function () {
- expect(this.result[1].appid).toBe(2);
+ expect(this.result.content[1].appid).toBe(2);
});
});
});
diff --git a/backend/src/core/services/game.service.js b/backend/src/core/services/game.service.js
deleted file mode 100644
index a464d0547..000000000
--- a/backend/src/core/services/game.service.js
+++ /dev/null
@@ -1,195 +0,0 @@
-import { Game } from "../models/game.js";
-import { SteamApp } from "../models/steam.app.js";
-import { parseHTML } from "linkedom";
-
-export function getSteamAppType(httpDetailsPage) {
- const { document } = parseHTML(httpDetailsPage);
-
- const breadcrumbElement = document.querySelector(".blockbg");
-
- if (!breadcrumbElement) return SteamApp.validTypes.unknown;
-
- const breadcrumbText = breadcrumbElement.children[0].textContent;
-
- if (breadcrumbText !== "All Software" && breadcrumbText !== "All Games")
- return SteamApp.validTypes.unknown;
-
- for (let child of breadcrumbElement.children) {
- if (child.textContent === "Downloadable Content")
- return SteamApp.validTypes.downloadableContent;
- }
-
- return SteamApp.validTypes.game;
-}
-
-export function discoverGamesFromSteamWeb(steamApps, htmlDetailsPages) {
- return htmlDetailsPages
- .map((page, i) => {
- if (getSteamAppType(page) === SteamApp.validTypes.game) {
- return Game.fromSteamApp(
- steamApps[i],
- getReleaseDate(page),
- getDevelopers(page),
- getGenres(page),
- getGameDescription(page),
- );
- }
- })
- .filter((game) => !!game);
-}
-
-export function getReleaseDate(page) {
- const { document } = parseHTML(page);
-
- const releaseDateElement = document.querySelector(".release_date .date");
-
- if (!releaseDateElement) return "";
-
- const releaseDate = new Date(`${releaseDateElement.textContent.trim()} UTC`);
-
- return releaseDate == "Invalid Date" ? "" : releaseDate;
-}
-
-export function getDevelopers(page) {
- const { document } = parseHTML(page);
-
- const developers = document.querySelector(".dev_row #developers_list");
-
- if (!developers) return [];
-
- return Array.from(developers.children).map((developer) => developer.textContent.trim());
-}
-
-export function getGenres(page) {
- const { document } = parseHTML(page);
-
- const genres = document.querySelector("#genresAndManufacturer span");
-
- if (!genres) return [];
-
- return Array.from(genres.children)
- .map((genre) => genre.textContent.trim())
- .filter((genre) => !!genre);
-}
-
-export function getGameDescription(page) {
- const { document } = parseHTML(page);
-
- const description = document.querySelector(".game_description_snippet");
-
- if (!description) return "";
-
- return description.textContent.trim();
-}
-
-export function updateTypeSideEffectFree(steamApps, htmlDetailsPages) {
- return htmlDetailsPages.map((page, i) => {
- const copy = steamApps[i].copy();
- const appType = getSteamAppType(page);
-
- copy.triedViaSteamWeb();
- if (page === "") copy.failedViaSteamWeb();
-
- copy.appType = appType;
-
- return copy;
- });
-}
-
-export function identifyGames(updatedSteamApps) {
- const games = updatedSteamApps
- .filter((steamApp) => steamApp.isGame())
- .map((steamApp) => Game.fromSteamcharts(steamApp));
-
- return games;
-}
-
-export function assignType(result, steamApp) {
- if (result) steamApp.appType = SteamApp.validTypes.game;
- return steamApp;
-}
-
-export function recordAttemptsViaSteamDb(steamApps, htmlDetailsPages) {
- return steamApps.map((app) => {
- const appCopy = app.copy();
- appCopy.triedViaSteamDb();
-
- const currentPage = htmlDetailsPages.find((page) => page.id == app.appid);
- if (currentPage.page === "") appCopy.failedViaSteamDb();
-
- return appCopy;
- });
-}
-
-export function updateMissingDetails(games, htmlDetailsPages) {
- htmlDetailsPages.forEach(({ page }, i) => {
- games[i].updateGameDetails(
- getSteamDbDevelopers(page),
- getSteamDbGenres(page),
- getSteamDbDescription(page),
- );
- });
-}
-
-export function getSteamDbDevelopers(page) {
- const { document } = parseHTML(page);
-
- const developers = document.querySelector(
- "table.table.table-bordered.table-hover.table-responsive-flex tbody tr:nth-child(3) td:last-child",
- );
-
- if (!developers) return [];
-
- return Array.from(developers.children).map((developer) => developer.textContent);
-}
-
-export function getSteamDbGenres(page) {
- const { document } = parseHTML(page);
-
- const domTableBody = document.querySelector("#info tbody");
-
- if (!domTableBody) return [];
-
- const genresNodes = Array.from(domTableBody.children).filter(
- (tableEntry) => tableEntry.children[0].textContent === "Store Genres",
- )[0].children[1].childNodes;
-
- return Array.from(genresNodes)
- .filter((genre) => genre.constructor.name === "Text")
- .map((genre) => genre.nodeValue.replace(",", "").trim());
-}
-
-export function getSteamDbDescription(page) {
- const { document } = parseHTML(page);
-
- const description = document.querySelector(".header-description");
-
- if (!description) return "";
-
- return description.textContent;
-}
-
-export function updateMissingReleaseDates(games, htmlDetailsPages) {
- games.forEach((game, i) => {
- game.updateReleaseDate(getSteamDbReleaseDate(htmlDetailsPages[i].page));
- });
-}
-
-export function getSteamDbReleaseDate(page) {
- const { document } = parseHTML(page);
-
- const releaseDateElement = document.querySelector(
- "table.table.table-bordered.table-hover.table-responsive-flex tbody tr:last-child td:last-child",
- );
-
- if (!releaseDateElement) return "";
-
- const releaseDateString = releaseDateElement.textContent;
-
- const releaseDate = new Date(`
- ${releaseDateString.slice(0, releaseDateString.indexOf("–") - 1)} UTC`);
-
- if (releaseDate == "Invalid Date") return "";
-
- return releaseDate;
-}
diff --git a/backend/src/core/services/game.service.spec.js b/backend/src/core/services/game.service.spec.js
deleted file mode 100644
index d9af4fe60..000000000
--- a/backend/src/core/services/game.service.spec.js
+++ /dev/null
@@ -1,863 +0,0 @@
-import {
- getSteamAppType,
- discoverGamesFromSteamWeb,
- updateTypeSideEffectFree,
- identifyGames,
- assignType,
- getReleaseDate,
- getDevelopers,
- getGenres,
- getGameDescription,
- updateMissingDetails,
- getSteamDbReleaseDate,
- getSteamDbDevelopers,
- getSteamDbGenres,
- getSteamDbDescription,
- updateMissingReleaseDates,
- recordAttemptsViaSteamDb,
-} from "./game.service.js";
-import { animaddicts2gameHtmlDetailsPage } from "../../../assets/steam-details-pages/animaddicts.2.game.html.details.page.js";
-import { feartressGameHtmlDetailsPage } from "../../../assets/steam-details-pages/feartress.game.html.details.page.js";
-import { glitchhikersSoundtrackHtmlDetailsPage } from "../../../assets/steam-details-pages/glitchhikers.soundtrack.html.details.page.js";
-import { gta5ageRestrictedHtmlDetailsPage } from "../../../assets/steam-details-pages/gta.5.age.restricted.html.details.page.js";
-import { padakVideoHtmlDetailsPage } from "../../../assets/steam-details-pages/padak.video.html.details.page.js";
-import { theSims4dlcHtmlDetailsPage } from "../../../assets/steam-details-pages/the.sims.4.dlc.html.details.page.js";
-import { Game } from "../models/game.js";
-import { SteamApp } from "../models/steam.app.js";
-import { ValidDataSources } from "../models/valid.data.sources.js";
-import { mortalDarknessGameHtmlDetailsPage } from "../../../assets/steam-details-pages/mortal.darkness.game.html.details.page.js";
-import { crusaderKingsDetailsPage } from "../../../assets/steam-details-pages/crusader.kings.multiple.developers.html.details.page.js";
-import { riskOfRainHtmlDetailsPageMissingInfo } from "../../../assets/steam-details-pages/risk.of.rain.missing.additional.info.page.js";
-import { counterStrikeHtmlDetailsSteamDb } from "../../../assets/steamdb-details-pages/counter.strike.html.details.page.js";
-import { riskOfRainHtmlDetailsSteamDb } from "../../../assets/steamdb-details-pages/risk.of.rain.html.details.page.js";
-import { karmazooHtmlDetailsPageSteamDb } from "../../../assets/steamdb-details-pages/karmazoo.html.details.page.js";
-import { getXsteamchartsInstantiatedGames } from "../models/game.mocks.js";
-import { createHtmlDetailsPages } from "../../../assets/html.details.pages.mock.js";
-import { getXSampleSteamApps } from "../models/steam.app.mocks.js";
-
-describe("game.service.js", () => {
- describe(".getSteamAppType", () => {
- describe("game is age restricted - there is no .blockbg class on the page", () => {
- let appType;
-
- beforeAll(async () => {
- appType = getSteamAppType(gta5ageRestrictedHtmlDetailsPage);
- });
-
- it("the function returns 'unknown'", () => {
- expect(appType).toBe(SteamApp.validTypes.unknown);
- });
- });
-
- describe("if there is no 'All Software' or 'All Games' in the first breadcrumb child text", () => {
- let appType;
-
- beforeAll(async () => {
- appType = getSteamAppType(padakVideoHtmlDetailsPage);
- });
-
- it("the function returns 'unknown'", () => {
- expect(appType).toBe(SteamApp.validTypes.unknown);
- });
- });
-
- describe("if the text 'Downloadable Content' is in one of the breadcrumbs", () => {
- let appType;
-
- beforeAll(async () => {
- appType = getSteamAppType(theSims4dlcHtmlDetailsPage);
- });
-
- it("the function returns 'downloadableContent'", () => {
- expect(appType).toBe(SteamApp.validTypes.downloadableContent);
- });
- });
-
- describe(".blockbg class is on the page, 'All Software' or 'All Games' is in the first breadcrumb and there is no 'Downloadable Content' text in the breadcrumbs", () => {
- let appType;
-
- beforeAll(async () => {
- appType = getSteamAppType(feartressGameHtmlDetailsPage);
- });
-
- it("the function returns 'game'", () => {
- expect(appType).toBe(SteamApp.validTypes.game);
- });
- });
- });
-
- describe(".discoverGamesFromSteamWeb", function () {
- describe("discovers one game out of a batch of one stemApp, so", function () {
- beforeAll(function () {
- this.steamApps = [
- {
- appid: 1,
- name: "Animaddicts",
- },
- ];
- this.htmlDetailsPages = [animaddicts2gameHtmlDetailsPage];
-
- this.games = discoverGamesFromSteamWeb(this.steamApps, this.htmlDetailsPages);
- });
-
- it("the length of games is 1", function () {
- expect(this.games.length).toBe(1);
- });
-
- it("the name of the first game array entry is 'Animaddicts'", function () {
- expect(this.games[0].name).toBe("Animaddicts");
- });
-
- it("the first entry in the games array is an instance of game", function () {
- expect(this.games[0]).toBeInstanceOf(Game);
- });
- });
-
- describe("discovers one game out of a batch of two steamApps, so", function () {
- beforeAll(function () {
- this.steamApps = [
- {
- appid: 1,
- name: "Animaddicts",
- },
- {
- appid: 2,
- name: "Glitchhikers Soundtrack 2",
- },
- ];
-
- this.htmlDetailsPages = [
- animaddicts2gameHtmlDetailsPage,
- glitchhikersSoundtrackHtmlDetailsPage,
- ];
-
- this.games = discoverGamesFromSteamWeb(this.steamApps, this.htmlDetailsPages);
- });
-
- it("the length of games is 1", function () {
- expect(this.games.length).toBe(1);
- });
-
- it("the name of the first game array entry is 'Animaddicts'", function () {
- expect(this.games[0].name).toBe("Animaddicts");
- });
-
- it("the first entry in the games array is an instance of game", function () {
- expect(this.games[0]).toBeInstanceOf(Game);
- });
- });
-
- describe("discovers two games out of a batch of three steamApps, so", function () {
- beforeAll(function () {
- this.steamApps = [
- {
- appid: 1,
- name: "Animaddicts",
- },
- {
- appid: 2,
- name: "Glitchhikers Soundtrack 2",
- },
- {
- appid: 3,
- name: "Feartress",
- },
- ];
-
- this.htmlDetailsPages = [
- animaddicts2gameHtmlDetailsPage,
- glitchhikersSoundtrackHtmlDetailsPage,
- feartressGameHtmlDetailsPage,
- ];
-
- this.games = discoverGamesFromSteamWeb(this.steamApps, this.htmlDetailsPages);
- });
-
- it("the length of games is 1", function () {
- expect(this.games.length).toBe(2);
- });
-
- it("the name of the first game array entry is 'Animaddicts'", function () {
- expect(this.games[0].name).toBe("Animaddicts");
- });
-
- it("the first entry in the games array is an instance of game", function () {
- expect(this.games[0]).toBeInstanceOf(Game);
- });
-
- it("the name of the second game array entry is 'Feartress'", function () {
- expect(this.games[1].name).toBe("Feartress");
- });
-
- it("the first entry in the games array is an instance of game", function () {
- expect(this.games[1]).toBeInstanceOf(Game);
- });
- });
- });
-
- describe(".getReleaseDate checks for a release date in the provided HTML page.", function () {
- describe("if the provided HTML page does not include a release date section,", function () {
- beforeAll(function () {
- this.result = getReleaseDate(riskOfRainHtmlDetailsPageMissingInfo);
- });
-
- it("the result is an empty string", function () {
- expect(this.result).toBe("");
- });
- });
-
- describe("if the provided HTML page includes a release date,", function () {
- beforeAll(function () {
- this.result = getReleaseDate(mortalDarknessGameHtmlDetailsPage);
- });
-
- it("the result is a date", function () {
- expect(this.result).toBeInstanceOf(Date);
- });
- it("the result is the correct date'", function () {
- expect(this.result.toISOString()).toEqual("2023-08-01T00:00:00.000Z");
- });
- });
- });
-
- describe(".getDevelopers checks for developers in the provided HTML page.", function () {
- describe("if the provided HTML page does not include any developers,", function () {
- beforeAll(function () {
- this.result = getDevelopers(riskOfRainHtmlDetailsPageMissingInfo);
- });
-
- it("the result is an empty array", function () {
- expect(this.result).toEqual([]);
- });
- });
-
- describe("if the provided HTML page includes one developer,", function () {
- beforeAll(function () {
- this.result = getDevelopers(mortalDarknessGameHtmlDetailsPage);
- });
-
- it("the result is an array with one value", function () {
- expect(this.result.length).toBe(1);
- });
-
- it("the result is 'Dark Faction Games'", function () {
- expect(this.result[0]).toBe("Dark Faction Games");
- });
- });
-
- describe("if the provided HTML page includes two developers,", function () {
- beforeAll(function () {
- this.result = getDevelopers(crusaderKingsDetailsPage);
- });
-
- it("the result is an array with two values", function () {
- expect(this.result.length).toBe(2);
- });
-
- it("the first result is 'Paradox Development Studio'", function () {
- expect(this.result[0]).toBe("Paradox Development Studio");
- });
-
- it("the second result is 'Paradox Thalassic'", function () {
- expect(this.result[1]).toBe("Paradox Thalassic");
- });
- });
- });
-
- describe(".getGenres checks for genres in the provided HTML page.", function () {
- describe("if the provided HTML page does not include any genres,", function () {
- beforeAll(function () {
- this.result = getGenres(riskOfRainHtmlDetailsPageMissingInfo);
- });
-
- it("the result is an empty array", function () {
- expect(this.result).toEqual([]);
- });
- });
-
- describe("if the provided HTML page includes genres,", function () {
- beforeAll(function () {
- this.result = getGenres(mortalDarknessGameHtmlDetailsPage);
- });
-
- it("the resulting array has a length of 4", function () {
- expect(this.result.length).toBe(4);
- });
- it("the first result is 'Action'", function () {
- expect(this.result[0]).toBe("Action");
- });
- it("the fourth result is 'RPG'", function () {
- expect(this.result[3]).toBe("RPG");
- });
- });
- });
-
- describe(".getDescription checks for a game's description in the provided HTML page.", function () {
- describe("if the provided HTML page does not include a game description,", function () {
- beforeAll(function () {
- this.result = getGameDescription(riskOfRainHtmlDetailsPageMissingInfo);
- });
-
- it("the result is an empty string", function () {
- expect(this.result).toEqual("");
- });
- });
-
- describe("if the provided HTML page includes a description,", function () {
- beforeAll(function () {
- this.result = getGameDescription(mortalDarknessGameHtmlDetailsPage);
- });
-
- it("the resulting is a specific string", function () {
- expect(this.result).toBe(
- "“One grim dawn and noble I wake, The darkness is rampant, our oath shall break. A noble warrior soon shall rise, and clear the air of the darkened skies.”",
- );
- });
- });
- });
-
- describe(".updateTypeSideEffectFree", function () {
- describe("discovers one steamApp out of a batch of one, so", function () {
- beforeAll(function () {
- this.apps = [
- {
- appid: 1,
- name: "Glitchhikers Soundtrack 2",
- },
- ];
-
- this.steamApps = SteamApp.manyFromSteamApi(this.apps);
-
- this.htmlDetailsPages = [glitchhikersSoundtrackHtmlDetailsPage];
-
- this.updatedSteamApps = updateTypeSideEffectFree(
- this.steamApps,
- this.htmlDetailsPages,
- );
- });
-
- it("the length of updatedSteamApps is 1", function () {
- expect(this.updatedSteamApps.length).toBe(1);
- });
-
- it("the first entry in the updatedSteamApps array is an instance of SteamApp", function () {
- expect(this.updatedSteamApps[0]).toBeInstanceOf(SteamApp);
- });
-
- it("the name of the first updatedSteamApps array entry is 'Glitchhikers Soundtrack 2'", function () {
- expect(this.updatedSteamApps[0].name).toBe(this.apps[0].name);
- });
-
- it("the first array entry in updatedSteamApps has a property 'type', and it's value is 'unknown'", function () {
- expect(this.updatedSteamApps[0].type).toBe(SteamApp.validTypes.unknown);
- });
- });
-
- describe("discovers one game and one downloadable content out of a batch of three steamApps,", function () {
- describe("with one html details page being empty", function () {
- beforeAll(function () {
- this.apps = [
- {
- appid: 1,
- name: "Glitchhikers Soundtrack 2",
- },
- {
- appid: 2,
- name: "Animaddicts",
- },
- {
- appid: 3,
- name: "The Sims 4 Cats and Dogs DLC",
- },
- ];
-
- this.steamApps = SteamApp.manyFromSteamApi(this.apps);
-
- this.htmlDetailsPages = [
- "",
- animaddicts2gameHtmlDetailsPage,
- theSims4dlcHtmlDetailsPage,
- ];
-
- this.updatedSteamApps = updateTypeSideEffectFree(
- this.steamApps,
- this.htmlDetailsPages,
- );
- });
-
- it("the length of updatedSteamApps is 3", function () {
- expect(this.updatedSteamApps.length).toBe(3);
- });
-
- it("the first entry in the updatedSteamApps array is an instance of SteamApp", function () {
- expect(this.updatedSteamApps[0]).toBeInstanceOf(SteamApp);
- });
-
- it("the second entry in the updatedSteamApps array is an instance of SteamApp", function () {
- expect(this.updatedSteamApps[1]).toBeInstanceOf(SteamApp);
- });
-
- it("the third entry in the updatedSteamApps array is an instance of SteamApp", function () {
- expect(this.updatedSteamApps[2]).toBeInstanceOf(SteamApp);
- });
-
- it("the name of the first updatedSteamApps array entry is 'Glitchhikers Soundtrack 2'", function () {
- expect(this.updatedSteamApps[0].name).toBe(this.apps[0].name);
- });
-
- it("the name of the second updatedSteamApps array entry is 'Animaddicts'", function () {
- expect(this.updatedSteamApps[1].name).toBe(this.apps[1].name);
- });
-
- it("the name of the third updatedSteamApps array entry is 'The Sims 4 Cats and Dogs DLC'", function () {
- expect(this.updatedSteamApps[2].name).toBe(this.apps[2].name);
- });
-
- it("the first array entry in updatedSteamApps has a property 'triedVia', and it's value is 'steamWeb'", function () {
- expect(this.updatedSteamApps[0].triedVia[0]).toBe(
- ValidDataSources.validDataSources.steamWeb,
- );
- });
-
- it("the second array entry in updatedSteamApps has a property 'triedVia', and it's value is 'steamWeb'", function () {
- expect(this.updatedSteamApps[1].triedVia[0]).toBe(
- ValidDataSources.validDataSources.steamWeb,
- );
- });
-
- it("the third array entry in updatedSteamApps has a property 'triedVia', and it's value is 'steamWeb'", function () {
- expect(this.updatedSteamApps[2].triedVia[0]).toBe(
- ValidDataSources.validDataSources.steamWeb,
- );
- });
-
- it("the first array entry in updatedSteamApps has a property 'failedVia', and it's value is 'steamWeb'", function () {
- expect(this.updatedSteamApps[0].failedVia[0]).toBe(
- ValidDataSources.validDataSources.steamWeb,
- );
- });
-
- it("the first entry in updatedSteamApps has a property 'type', and it's value is 'unknown'", function () {
- expect(this.updatedSteamApps[0].type).toBe(SteamApp.validTypes.unknown);
- });
-
- it("the second entry in updatedSteamApps has a property 'type', and it's value is 'game'", function () {
- expect(this.updatedSteamApps[1].type).toBe(SteamApp.validTypes.game);
- });
-
- it("the third entry in updatedSteamApps has a property 'type', and it's value is 'downloadableContent'", function () {
- expect(this.updatedSteamApps[2].type).toBe(
- SteamApp.validTypes.downloadableContent,
- );
- });
- });
- });
- });
-
- describe(".identifyGames", function () {
- describe("checks which steam apps are games and instantiates them, so", function () {
- describe("when no games out of a batch of one steamApp is passed in,", function () {
- beforeAll(function () {
- this.updatedSteamApps = [
- {
- appid: 1,
- name: "Glitchiker Soundtrack",
- },
- ];
-
- this.instantiatedApps = SteamApp.manyFromSteamApi(this.updatedSteamApps);
- this.result = identifyGames(this.instantiatedApps);
- });
-
- it("the method returns an empty array", function () {
- expect(this.result).toEqual([]);
- });
- });
-
- describe("when one game out of a batch of two steamApps is passed in,", function () {
- beforeAll(function () {
- this.updatedSteamApps = [
- {
- appid: 1,
- name: "Glitchiker Soundtrack",
- },
- {
- appid: 2,
- name: "Feartress",
- },
- ];
-
- this.instantiatedApps = SteamApp.manyFromSteamApi(this.updatedSteamApps);
- this.instantiatedApps[1].type = SteamApp.validTypes.game;
-
- this.result = identifyGames(this.instantiatedApps);
- });
-
- it("the returned array length is one", function () {
- expect(this.result.length).toBe(1);
- });
-
- it("the name property in the first returned array index is 'Feartress'", function () {
- expect(this.result[0].name).toBe(this.updatedSteamApps[1].name);
- });
- });
-
- describe("when two games out of a batch of three steamApps is passed in,", function () {
- beforeAll(function () {
- this.updatedSteamApps = [
- {
- appid: 1,
- name: "Glitchiker Soundtrack",
- },
- {
- appid: 2,
- name: "Feartress",
- },
- {
- appid: 3,
- name: "Elden Ring",
- },
- ];
-
- this.instantiatedApps = SteamApp.manyFromSteamApi(this.updatedSteamApps);
- this.instantiatedApps[1].type = SteamApp.validTypes.game;
- this.instantiatedApps[2].type = SteamApp.validTypes.game;
-
- this.result = identifyGames(this.instantiatedApps);
- });
-
- it("the returned array length is two", function () {
- expect(this.result.length).toBe(2);
- });
-
- it("the name property in the first returned array index is 'Feartress'", function () {
- expect(this.result[0].name).toBe(this.updatedSteamApps[1].name);
- });
-
- it("the name property in the first returned array index is 'Elden Ring'", function () {
- expect(this.result[1].name).toBe(this.updatedSteamApps[2].name);
- });
- });
- });
- });
-
- describe(".assignType", function () {
- describe("checks if result contains a value. If so, sets the type property to 'games'. So", function () {
- describe("when result does not contain a value,", function () {
- beforeAll(function () {
- this.app = { id: 1, name: "Feartress" };
- this.steamApp = SteamApp.oneFromSteamApi(this.app);
-
- this.result = assignType(undefined, this.steamApp);
- });
-
- it("the function returns the steamApp. The type property remains 'unknown'", function () {
- expect(this.result.type).toBe(SteamApp.validTypes.unknown);
- });
- });
-
- describe("when the result contains a value,", function () {
- beforeAll(function () {
- this.app = { id: 1, name: "Feartress" };
- this.steamApp = SteamApp.oneFromSteamApi(this.app);
-
- this.result = assignType(true, this.steamApp);
- });
-
- it("the function returns the steamApp. The type property is 'game'", function () {
- expect(this.result.type).toBe(SteamApp.validTypes.game);
- });
- });
- });
- });
-
- describe(".recordAttemptsViaSteamDb", function () {
- describe("if one of the pages is empty", function () {
- beforeAll(function () {
- this.apps = getXSampleSteamApps(2);
-
- this.pages = createHtmlDetailsPages([counterStrikeHtmlDetailsSteamDb, ""]);
-
- this.result = recordAttemptsViaSteamDb(this.apps, this.pages);
- });
-
- it("the first app has the correct values", function () {
- expect(this.result[0].triedVia).toEqual([
- ValidDataSources.validDataSources.steamDb,
- ]);
- expect(this.result[0].failedVia).toEqual([]);
- });
-
- it("the second app has the correct values", function () {
- expect(this.result[1].triedVia).toEqual([
- ValidDataSources.validDataSources.steamDb,
- ]);
- expect(this.result[1].failedVia).toEqual([
- ValidDataSources.validDataSources.steamDb,
- ]);
- });
- });
-
- describe("if none of the pages are empty", function () {
- beforeAll(function () {
- this.apps = getXSampleSteamApps(2);
-
- this.pages = createHtmlDetailsPages([
- counterStrikeHtmlDetailsSteamDb,
- karmazooHtmlDetailsPageSteamDb,
- ]);
-
- this.result = recordAttemptsViaSteamDb(this.apps, this.pages);
- });
-
- it("the first app has the correct values", function () {
- expect(this.result[0].triedVia).toEqual([
- ValidDataSources.validDataSources.steamDb,
- ]);
- expect(this.result[0].failedVia).toEqual([]);
- });
-
- it("the second app has the correct values", function () {
- expect(this.result[1].triedVia).toEqual([
- ValidDataSources.validDataSources.steamDb,
- ]);
- expect(this.result[1].failedVia).toEqual([]);
- });
- });
-
- describe("when the result contains a value,", function () {
- beforeAll(function () {
- this.app = getXSampleSteamApps(1);
- this.steamApp = SteamApp.oneFromSteamApi(this.app);
-
- this.result = assignType(true, this.steamApp);
- });
-
- it("the function returns the steamApp. The type property is 'game'", function () {
- expect(this.result.type).toBe(SteamApp.validTypes.game);
- });
- });
- });
-
- describe(".updateMissingDetails.", function () {
- describe("When we try to update two games with missing details,", function () {
- beforeAll(function () {
- this.games = getXsteamchartsInstantiatedGames(2);
-
- const htmlDetailsPages = createHtmlDetailsPages([
- counterStrikeHtmlDetailsSteamDb,
- riskOfRainHtmlDetailsSteamDb,
- ]);
-
- updateMissingDetails(this.games, htmlDetailsPages);
- });
-
- it("two games are returned", function () {
- expect(this.games.length).toBe(2);
- });
-
- it("the first game's details are updated", function () {
- expect(this.games[0].developers).toEqual(["Valve", "Hidden Path Entertainment"]);
- expect(this.games[0].genres).toEqual(["Action", "Free to Play"]);
- expect(this.games[0].description).toBe(
- "Counter-Strike: Global Offensive (CS: GO) expands upon the team-based action gameplay that it pioneered when it was launched 19 years ago. CS: GO features new maps, characters, weapons, and game modes, and delivers updated versions of the classic CS content (de_dust2, etc.).",
- );
- });
-
- it("the second game's details are updated", function () {
- expect(this.games[1].developers).toEqual(["Hopoo Games"]);
- expect(this.games[1].genres).toEqual(["Action", "Indie"]);
- expect(this.games[1].description).toBe(
- "Escape a chaotic alien planet by fighting through hordes of frenzied monsters – with your friends, or on your own. Combine loot in surprising ways and master each character until you become the havoc you feared upon your first crash landing.",
- );
- });
- });
- });
-
- describe(".getSteamDbReleaseDate.", function () {
- describe("When we provide a html page that doesn't contain a valid date,", function () {
- beforeAll(function () {
- this.result = getSteamDbReleaseDate(karmazooHtmlDetailsPageSteamDb);
- });
-
- it("an empty string is returned", function () {
- expect(this.result).toBe("");
- });
- });
-
- describe("When we provide a html page that contains a valid date,", function () {
- beforeAll(function () {
- this.date = new Date("11 August 2020 UTC");
-
- this.result = getSteamDbReleaseDate(riskOfRainHtmlDetailsSteamDb);
- });
-
- it("a date is returned'", function () {
- expect(this.result).toBeInstanceOf(Date);
- });
-
- it("the result is the correct date", function () {
- expect(this.result.toISOString()).toEqual("2020-08-11T00:00:00.000Z");
- });
- });
-
- describe("When we provide a html page that doesn't contain a date section", function () {
- beforeAll(function () {
- this.result = getSteamDbReleaseDate(riskOfRainHtmlDetailsPageMissingInfo);
- });
-
- it("an empty string is returned", function () {
- expect(this.result).toBe("");
- });
- });
- });
-
- describe(".getSteamDbDevelopers.", function () {
- describe("When we provide a html page that contains two developers,", function () {
- beforeAll(function () {
- this.result = getSteamDbDevelopers(counterStrikeHtmlDetailsSteamDb);
- });
-
- it("two developers are returned", function () {
- expect(this.result.length).toBe(2);
- });
-
- it("the developer is 'Valve'", function () {
- expect(this.result[0]).toBe("Valve");
- });
-
- it("the developer is 'Hidden Path Entertainment'", function () {
- expect(this.result[1]).toBe("Hidden Path Entertainment");
- });
- });
-
- describe("When we provide a html page that doesn't contain a developer section", function () {
- beforeAll(function () {
- this.result = getSteamDbDevelopers(riskOfRainHtmlDetailsPageMissingInfo);
- });
-
- it("an empty array is returned", function () {
- expect(this.result).toEqual([]);
- });
- });
- });
-
- describe(".getSteamDbGenres.", function () {
- describe("When we provide a html page that contains the genres,", function () {
- beforeAll(function () {
- this.result = getSteamDbGenres(riskOfRainHtmlDetailsSteamDb);
- });
-
- it("two genres are returned", function () {
- expect(this.result.length).toBe(2);
- });
-
- it("the first genre is 'Action'", function () {
- expect(this.result[0]).toBe("Action");
- });
-
- it("the second genre is 'Indie'", function () {
- expect(this.result[1]).toBe("Indie");
- });
- });
-
- describe("When we provide a html page that doesn't contain a genres section,", function () {
- beforeAll(function () {
- this.result = getSteamDbGenres(riskOfRainHtmlDetailsPageMissingInfo);
- });
-
- it("an empty array is returned", function () {
- expect(this.result).toEqual([]);
- });
- });
- });
-
- describe(".getSteamDbDescription.", function () {
- describe("When we provide a html page that contains the description,", function () {
- beforeAll(function () {
- this.result = getSteamDbDescription(riskOfRainHtmlDetailsSteamDb);
- });
-
- it("the returned value is the game's description'", function () {
- expect(this.result).toEqual(
- "Escape a chaotic alien planet by fighting through hordes of frenzied monsters – with your friends, or on your own. Combine loot in surprising ways and master each character until you become the havoc you feared upon your first crash landing.",
- );
- });
- });
-
- describe("When we provide a html page that doesn't contain a description section,", function () {
- beforeAll(function () {
- this.result = getSteamDbDescription(riskOfRainHtmlDetailsPageMissingInfo);
- });
-
- it("an empty string is returned", function () {
- expect(this.result).toEqual("");
- });
- });
- });
-
- describe(".updateMissingReleaseDates.", function () {
- describe("When we try to update two games with missing release dates,", function () {
- beforeAll(function () {
- this.games = getXsteamchartsInstantiatedGames(2);
-
- const htmlDetailsPages = createHtmlDetailsPages([
- counterStrikeHtmlDetailsSteamDb,
- riskOfRainHtmlDetailsSteamDb,
- ]);
-
- updateMissingReleaseDates(this.games, htmlDetailsPages);
- });
-
- it("two games are returned", function () {
- expect(this.games.length).toBe(2);
- });
-
- it("the first game's release date is updated", function () {
- expect(this.games[0].releaseDate).toEqual(new Date("21 August 2012 UTC"));
- });
-
- it("the second game's release date is updated", function () {
- expect(this.games[1].releaseDate).toEqual(new Date("11 August 2020 UTC"));
- });
- });
- });
-
- describe(".getSteamDbReleaseDate.", function () {
- describe("When we provide a html page that doesn't contain a valid release date,", function () {
- beforeAll(function () {
- this.result = getSteamDbReleaseDate(karmazooHtmlDetailsPageSteamDb);
- });
-
- it("an empty string is returned", function () {
- expect(this.result).toBe("");
- });
- });
-
- describe("When we provide a html page that contains a valid release date,", function () {
- beforeAll(function () {
- this.date = new Date("11 August 2020 UTC");
-
- this.result = getSteamDbReleaseDate(riskOfRainHtmlDetailsSteamDb);
- });
-
- it("a date is returned'", function () {
- expect(this.result).toBeInstanceOf(Date);
- });
-
- it("the correct date is returned", function () {
- expect(this.result).toEqual(this.date);
- });
- });
-
- describe("When we provide a html page that doesn't contain a date section", function () {
- beforeAll(function () {
- this.result = getSteamDbReleaseDate(riskOfRainHtmlDetailsPageMissingInfo);
- });
-
- it("an empty string is returned", function () {
- expect(this.result).toBe("");
- });
- });
- });
-});
diff --git a/backend/src/main.js b/backend/src/main.js
index 879d6075e..2ac048cac 100644
--- a/backend/src/main.js
+++ b/backend/src/main.js
@@ -1,12 +1,13 @@
import httpClient from "axios";
import { DatabaseClient } from "./adapters/driven/db/database.client.js";
import { SteamClient } from "./adapters/driven/http/steam.client.js";
-import { SteamAppsAggregator } from "./core/features/steam-apps-aggregator/steam.apps.aggregator.js";
-import { GameIdentifier } from "./core/features/game-identifier/game.identifier.js";
-import { PlayerHistoryAggregator } from "./core/features/player-history-aggregator/player.history.aggregator.js";
+import { Runner } from "./adapters/driving/runner/runner.js";
import { WebServer } from "./adapters/driving/rest/web.server.js";
import { GameQueriesController } from "./adapters/driving/rest/game-queries/game.queries.controller.js";
import { GameQueriesRouter } from "./adapters/driving/rest/game-queries/game.queries.router.js";
+import { SteamAppsAggregator } from "./core/features/steam-apps-aggregator/steam.apps.aggregator.js";
+import { GameIdentifier } from "./core/features/game-identifier/game.identifier.js";
+import { PlayerHistoryAggregator } from "./core/features/player-history-aggregator/player.history.aggregator.js";
import { GamesRepository } from "./core/repositories/games.repository.js";
import { SteamAppsRepository } from "./core/repositories/steam.apps.repository.js";
import { SteamAppsUpdateTimestampsRepository } from "./core/repositories/steam.apps.update.timestamps.repository.js";
@@ -14,7 +15,8 @@ import { PlayerHistoryRepository } from "./core/repositories/player.history.repo
import { HistoryChecksRepository } from "./core/repositories/history.checks.repository.js";
import { config } from "./common/config.loader.js";
import { Logger } from "./common/logger.js";
-import { Runner } from "./adapters/driving/runner/runner.js";
+import { ValidDataSources } from "./core/models/valid.data.sources.js";
+import { parseHTML } from "linkedom";
// our entry point = main
async function main() {
@@ -48,6 +50,7 @@ async function main() {
historyChecksRepository,
logger,
config.features,
+ parseHTML,
);
const playerHistoryAggregator = new PlayerHistoryAggregator(
steamClient,
@@ -73,11 +76,15 @@ async function main() {
? { func: steamAppsAggregator.collectSteamAppsDiffOnDbLayer }
: { func: steamAppsAggregator.collectSteamApps };
+ const steamWeb = ValidDataSources.validDataSources.steamWeb;
+ const steamcharts = ValidDataSources.validDataSources.steamcharts;
+
const runnables = [
steamAppsAggregatorRunnable,
- { func: gameIdentifier.tryViaSteamWeb },
- { func: gameIdentifier.tryViaSteamchartsWeb },
+ { func: () => gameIdentifier.checkIfGameViaSource(steamWeb) },
+ { func: () => gameIdentifier.checkIfGameViaSource(steamcharts) },
{ func: gameIdentifier.updateGamesWithoutDetails },
+ { func: gameIdentifier.updateGamesWithoutReleaseDates },
{ func: playerHistoryAggregator.addPlayerHistoryFromSteamcharts },
{ func: playerHistoryAggregator.addCurrentPlayers },
];