diff --git a/test/index-test.js b/test/index-test.js deleted file mode 100644 index 6935022..0000000 --- a/test/index-test.js +++ /dev/null @@ -1,40 +0,0 @@ -"use strict"; - -// Test suite -const api = require("./suites/api-test.js").suite; -const credentials = require("./suites/credentials-test.js").suite; -const network = require("./suites/network-helper-test.js").suite; -const platform = require("./suites/platform-data-test.js").suite; -const scraper = require("./suites/scraper-test.js").suite; -const searcher = require("./suites/searcher-test.js").suite; -const uScraper = require("./suites/user-scraper-test.js").suite; -const prefixParser = require("./suites/prefix-parser-test.js").suite; - -describe("Test basic function", function testBasic() { - //#region Set-up - this.timeout(30000); // All tests in this suite get 30 seconds before timeout - //#endregion Set-up - - describe("Test credentials class", credentials.bind(this)); - describe("Test network helper", network.bind(this)); - describe("Test prefix parser", prefixParser.bind(this)); -}); - -describe("Test F95 modules", function testF95Modules() { - //#region Set-up - this.timeout(15000); // All tests in this suite get 15 seconds before timeout - //#endregion Set-up - - describe("Test platform data fetch", platform.bind(this)); - describe("Test scraper methods", scraper.bind(this)); - describe("Test searcher methods", searcher.bind(this)); - describe("Test user scraper methods", uScraper.bind(this)); -}); - -describe("Test complete API", function testAPI() { - //#region Set-up - this.timeout(15000); // All tests in this suite get 15 seconds before timeout - //#endregion Set-up - - describe("Test API", api.bind(this)); -}); \ No newline at end of file diff --git a/test/suites/api-test.js b/test/suites/api-test.js deleted file mode 100644 index 16557ec..0000000 --- a/test/suites/api-test.js +++ /dev/null @@ -1,120 +0,0 @@ -"use strict"; - -// Public module from npm -const expect = require("chai").expect; -const dotenv = require("dotenv"); -const { - isEqual -} = require("lodash"); - -// Modules from file -const F95API = require("../../app/index.js"); - -// Configure the .env reader -dotenv.config(); - -// Global variables -const USERNAME = process.env.F95_USERNAME; -const PASSWORD = process.env.F95_PASSWORD; - -module.exports.suite = function suite() { - // Global suite variables - const gameURL = "https://f95zone.to/threads/perverted-education-v0-9601-april-ryan.1854/"; - const updatedGameURL = "https://f95zone.to/threads/noxian-nights-v1-2-4-hreinn-games.2/"; - - it("Test login", async function testLogin() { - const result = await F95API.login(USERNAME, PASSWORD); - expect(result.success).to.be.true; - expect(F95API.isLogged()).to.be.true; - }); - - it("Test user data fetching", async function testUserDataFetch() { - const userdata = await F95API.getUserData(); - expect(userdata.username).to.be.equal(USERNAME); - }); - - it("Test game for existing update", async function checkUpdateByURL() { - // We force the creation of a GameInfo object, - // knowing that the checkIfGameHasUpdate() function - // only needs the game URL - const info = new F95API.GameInfo(); - - // The gameURL identifies a game for which we know there is an update - info.url = gameURL; - - // Check for updates - const update = await F95API.checkIfGameHasUpdate(info); - expect(update).to.be.true; - }); - - it("Test game for non existing update", async function checkUpdateByVersion() { - // We force the creation of a GameInfo object, - // knowing that the checkIfGameHasUpdate() function - // only needs the game URL - const info = new F95API.GameInfo(); - - // The updatedGameURL identifies a game for which - // we know there is **not** an update - info.url = updatedGameURL; - info.version = "1.2.4"; // The hame is marked as "Completed" so it shouldn't change it's version - - // Check for updates - const update = await F95API.checkIfGameHasUpdate(info); - expect(update).to.be.false; - }); - - it("Test game for fake update", async function checkFakeUpdateByVersion() { - // We force the creation of a GameInfo object, - // knowing that the checkIfGameHasUpdate() function - // only needs the game URL - const info = new F95API.GameInfo(); - - // The updatedGameURL identifies a game for which - // we know there is **not** an update - info.url = updatedGameURL; - info.version = "ThisIsAFakeVersion"; // The real version is "1.2.4" - - // Check for updates - const update = await F95API.checkIfGameHasUpdate(info); - expect(update).to.be.true; - }); - - it("Test game data fetching", async function testGameDataFetch() { - // Search a game by name - const gameList = await F95API.getGameData("perverted education", false); - - // We know that there is only one game with the selected name - expect(gameList.length).to.be.equal(1, `There should be only one game, not ${gameList.length}`); - const game = gameList[0]; - - // Than we fetch a game from URL - const gameFromURL = await F95API.getGameDataFromURL(game.url); - - // The two games must be equal - const equal = isEqual(game, gameFromURL); - expect(equal).to.be.true; - }); - - it("Test latest games fetching", async function testLatestFetch() { - // Prepare a search query - const query = { - datelimit: 0, - tags: ["male protagonist", "3dcg"], - prefixes: ["Completed", "Unity"], - sorting: "views", - }; - - // TODO - // First test the parameters validation - // assert.throws(() => { F95API.getLatestUpdates(query, 0); }, - // Error, - // "Error thrown if limit is <= 0"); - - // Now we fetch certain games that are "stables" as per 2020 - const LIMIT = 3; - const result = await F95API.getLatestUpdates(query, LIMIT); - expect(result[0].id).to.be.equal(3691, "The game should be: 'Man of the house'"); - expect(result[1].id).to.be.equal(5483, "The game should be: 'Lucky mark'"); - expect(result[2].id).to.be.equal(5949, "The game should be: 'Timestamps, Unconditional Love'"); - }); -}; \ No newline at end of file diff --git a/test/suites/credentials-test.js b/test/suites/credentials-test.js deleted file mode 100644 index 3bf60e2..0000000 --- a/test/suites/credentials-test.js +++ /dev/null @@ -1,52 +0,0 @@ -"use strict"; - -// Public module from npm -const expect = require("chai").expect; - -// Modules from file -const Credentials = require("../../app/scripts/classes/credentials.js"); - -module.exports.suite = function suite() { - it("Check token formatting", async function testValidToken() { - // Token example: - // 1604309951,0338213c00fcbd894fd9415e6ba08403 - // 1604309986,ebdb75502337699381f0f55c86353555 - // 1604310008,2d50d55808e5ec3a157ec01953da9d26 - - // Fetch token (is a GET request, we don't need the credentials) - const cred = new Credentials(null, null); - await cred.fetchToken(); - - // Parse token for assert - const splitted = cred.token.split(","); - const unique = splitted[0]; - const hash = splitted[1]; - expect(splitted.length).to.be.equal(2, "The token consists of two parts"); - - // Check type of parts - expect(isNumeric(unique)).to.be.true; - expect(isNumeric(hash)).to.be.false; - - // The second part is most probably the MD5 hash of something - expect(hash.length).to.be.equal(32, "Hash should have 32 hex chars"); - }); -}; - -//#region Private methods -/** - * @private - * Check if a string is a number - * @param {String} str - * @author Dan, Ben Aston - * @see https://preview.tinyurl.com/y46jqwkt - */ -function isNumeric(str) { - // We only process strings! - if (typeof str != "string") return false; - - // Use type coercion to parse the _entirety_ of the string - // (`parseFloat` alone does not do this) and ensure strings - // of whitespace fail - return !isNaN(str) && !isNaN(parseFloat(str)); -} -//#endregion \ No newline at end of file diff --git a/test/suites/network-helper-test.js b/test/suites/network-helper-test.js deleted file mode 100644 index a650c99..0000000 --- a/test/suites/network-helper-test.js +++ /dev/null @@ -1,107 +0,0 @@ -"use strict"; - -// Public module from npm -const expect = require("chai").expect; -const dotenv = require("dotenv"); - -// Modules from file -const Credentials = require("../../app/scripts/classes/credentials.js"); -const networkHelper = require("../../app/scripts/network-helper.js"); -const { - F95_SEARCH_URL -} = require("../../app/scripts/constants/url.js"); - -// Configure the .env reader -dotenv.config(); - -// Global variables -const USERNAME = process.env.F95_USERNAME; -const PASSWORD = process.env.F95_PASSWORD; -const FAKE_USERNAME = "Fake_Username091276"; -const FAKE_PASSWORD = "fake_password"; - -module.exports.suite = function suite() { - // Global suite variables - const gameURL = "https://f95zone.to/threads/perverted-education-v0-9601-april-ryan.1854/"; - - it("Check if URL exists", async function checkURLExistence() { - // Check generic URLs... - let exists = await networkHelper.urlExists("https://www.google.com/"); - expect(exists, "Complete valid URL").to.be.true; - - exists = await networkHelper.urlExists("www.google.com"); - expect(exists, "URl without protocol prefix").to.be.false; - - exists = await networkHelper.urlExists("https://www.google/"); - expect(exists, "URL without third level domain").to.be.false; - - // Now check for more specific URLs (with redirect)... - exists = await networkHelper.urlExists(gameURL); - expect(exists, "URL with redirect without check").to.be.true; - - exists = await networkHelper.urlExists(gameURL, true); - expect(exists, "URL with redirect with check").to.be.false; - }); - - it("Check if URL belong to the platform", function checkIfURLIsF95() { - let belong = networkHelper.isF95URL(gameURL); - expect(belong).to.be.true; - - belong = networkHelper.isF95URL("https://www.google/"); - expect(belong).to.be.false; - }); - - it("Enforce secure URLs", function testSecureURLEnforcement() { - // This URL is already secure, should remain the same - let enforced = networkHelper.enforceHttpsUrl(gameURL); - expect(enforced).to.be.equal(gameURL, "The game URL is already secure"); - - // This URL is not secure - enforced = networkHelper.enforceHttpsUrl("http://www.google.com"); - expect(enforced).to.be.equal("https://www.google.com", "The URL was without SSL/TLS (HTTPs)"); - - // Finally, we check when we pass a invalid URL - enforced = networkHelper.enforceHttpsUrl("http://invalidurl"); - expect(enforced).to.be.null; - }); - - it("Check URL redirect", async function checkURLRedirect() { - // gameURL is an old URL it has been verified that it generates a redirect - const redirectURL = await networkHelper.getUrlRedirect(gameURL); - expect(redirectURL).to.not.be.equal(gameURL, "The original URL has redirect"); - - // If we recheck the new URL, we find that no redirect happens - const secondRedirectURL = await networkHelper.getUrlRedirect(redirectURL); - expect(secondRedirectURL).to.be.equal(redirectURL, "The URL has no redirect"); - }); - - it("Check response to GET request", async function testGETResponse() { - // We should be able to fetch a game page - let response = await networkHelper.fetchGETResponse(gameURL); - expect(response.status).to.be.equal(200, "The operation must be successful"); - - // We should NOT be able to fetch the search page (we must be logged) - response = await networkHelper.fetchGETResponse(F95_SEARCH_URL); - expect(response).to.be.null; - }); - - it("Test for authentication to platform", async function testAuthentication() { - // Try to authenticate with valid credentials - const creds = new Credentials(USERNAME, PASSWORD); - await creds.fetchToken(); - const validResult = await networkHelper.authenticate(creds); - expect(validResult.success).to.be.true; - - // Now we use fake credentials - const fakeCreds = new Credentials(FAKE_USERNAME, FAKE_PASSWORD); - await fakeCreds.fetchToken(); - const invalidResult = await networkHelper.authenticate(fakeCreds, true); - expect(invalidResult.success).to.be.false; - }); - - it("Test fetching HTML", async function testFetchHTML() { - // This should return the HTML code of the page - const html = await networkHelper.fetchHTML(gameURL); - expect(html.startsWith("")).to.be.true; - }); -}; \ No newline at end of file diff --git a/test/suites/platform-data-test.js b/test/suites/platform-data-test.js deleted file mode 100644 index e00272a..0000000 --- a/test/suites/platform-data-test.js +++ /dev/null @@ -1,65 +0,0 @@ -"use strict"; - -// Public module from npm -const expect = require("chai").expect; -const dotenv = require("dotenv"); -const { isEqual } = require("lodash"); - -// Core modules -const fs = require("fs"); - -// Modules from file -const shared = require("../../app/scripts/shared.js"); -const platform = require("../../app/scripts/platform-data.js"); -const Credentials = require("../../app/scripts/classes/credentials.js"); -const { authenticate } = require("../../app/scripts/network-helper.js"); - -// Configure the .env reader -dotenv.config(); - -// Global variables -const USERNAME = process.env.F95_USERNAME; -const PASSWORD = process.env.F95_PASSWORD; - -module.exports.suite = function suite() { - //#region Setup - before(async function beforeAll() { - // Authenticate - const creds = new Credentials(USERNAME, PASSWORD); - await creds.fetchToken(); - await authenticate(creds); - }); - //#endregion Setup - - it("Fetch new platform data", async function fetchNewPlatformData() { - // Delete the current platform data (if exists) - if(fs.existsSync(shared.cachePath)) fs.unlinkSync(shared.cachePath); - - // Fetch data - await platform.fetchPlatformData(); - - // Check data - const enginesEquality = isEqual({}, shared.engines); - const statusEquality = isEqual({}, shared.statuses); - const tagsEquality = isEqual({}, shared.tags); - expect(enginesEquality, "Should not be empty").to.be.false; - expect(statusEquality, "Should not be empty").to.be.false; - expect(tagsEquality, "Should not be empty").to.be.false; - - // Check if the file exists - expect(fs.existsSync(shared.cachePath)).to.be.true; - }); - - it("Fetch cached platform data", async function fetchCachedPlatformData() { - // Fetch data - await platform.fetchPlatformData(); - - // Check data - const enginesEquality = isEqual({}, shared.engines); - const statusEquality = isEqual({}, shared.statuses); - const tagsEquality = isEqual({}, shared.tags); - expect(enginesEquality, "Should not be empty").to.be.false; - expect(statusEquality, "Should not be empty").to.be.false; - expect(tagsEquality, "Should not be empty").to.be.false; - }); -}; diff --git a/test/suites/prefix-parser-test.js b/test/suites/prefix-parser-test.js deleted file mode 100644 index dd02f5e..0000000 --- a/test/suites/prefix-parser-test.js +++ /dev/null @@ -1,45 +0,0 @@ -"use strict"; - -// Public module from npm -const expect = require("chai").expect; -const dotenv = require("dotenv"); -const { isEqual } = require("lodash"); - -// Modules from file -const Credentials = require("../../app/scripts/classes/credentials.js"); -const PrefixParser = require("../../app/scripts/classes/prefix-parser.js"); -const { authenticate } = require("../../app/scripts/network-helper.js"); -const { fetchPlatformData } = require("../../app/scripts/platform-data.js"); - -// Configure the .env reader -dotenv.config(); - -// Global variables -const USERNAME = process.env.F95_USERNAME; -const PASSWORD = process.env.F95_PASSWORD; - -module.exports.suite = function suite() { - //#region Setup - before(async function beforeAll() { - // Authenticate - const creds = new Credentials(USERNAME, PASSWORD); - await creds.fetchToken(); - await authenticate(creds); - await fetchPlatformData(); - }); - //#endregion Setup - - it("Parse prefixes", async function testPrefixParser() { - // Create a new parser - const parser = new PrefixParser(); - - const testPrefixes = ["corruption", "pregnancy", "slave", "VN", "RPGM", "Ren'Py", "Abandoned"]; - const ids = parser.prefixesToIDs(testPrefixes); - const tags = parser.idsToPrefixes(ids); - - const tagsEquality = isEqual(testPrefixes, tags); - expect(tagsEquality, "The tags must be the same").to.be.true; - const idsEquality = isEqual([103, 225, 44, 13, 2, 7, 22], ids); - expect(idsEquality, "The IDs must be the same").to.be.true; - }); -}; \ No newline at end of file diff --git a/test/suites/scraper-test.js b/test/suites/scraper-test.js deleted file mode 100644 index 07a6072..0000000 --- a/test/suites/scraper-test.js +++ /dev/null @@ -1,56 +0,0 @@ -"use strict"; - -// Public module from npm -const expect = require("chai").expect; -const { isEqual } = require("lodash"); -const GameInfo = require("../../app/scripts/classes/game-info.js"); - -// Modules from file -const scraper = require("../../app/scripts/scraper.js"); - -module.exports.suite = function suite() { - // Global suite variables - const gameURL = "https://f95zone.to/threads/kingdom-of-deception-v0-10-8-hreinn-games.2733/"; - const modURL = "https://f95zone.to/threads/witch-trainer-silver-mod-v1-39-silver-studio-games.1697/"; - const previewSrc = "https://attachments.f95zone.to/2018/09/162821_f9nXfwF.png"; - const modPreviewSrc = "https://attachments.f95zone.to/2018/10/178357_banner.png"; - - it("Search game", async function () { - // This test depend on the data on F95Zone at gameURL - const result = await scraper.getGameInfo(gameURL); - - // Test only the main information - expect(result.name).to.equal("Kingdom of Deception"); - expect(result.author).to.equal("Hreinn Games"); - expect(result.isMod, "Should be false").to.be.false; - expect(result.engine).to.equal("Ren'Py"); - expect(result.previewSrc).to.equal(previewSrc, "Preview not equals"); - }); - - it("Search mod", async function () { - // This test depend on the data on F95Zone at modURL - const result = await scraper.getGameInfo(modURL); - - // Test only the main information - expect(result.name).to.equal("Witch Trainer: Silver Mod"); - expect(result.author).to.equal("Silver Studio Games"); - expect(result.isMod, "Should be true").to.be.true; - expect(result.engine).to.equal("Ren'Py"); - expect(result.previewSrc).to.equal(modPreviewSrc, "Preview not equals"); - }); - - it("Test game serialization", async function testGameSerialization() { - // This test depend on the data on F95Zone at gameURL - const testGame = await scraper.getGameInfo(gameURL); - - // Serialize... - const json = JSON.stringify(testGame); - - // Deserialize... - const parsedGameInfo = GameInfo.fromJSON(json); - - // Compare with lodash - const result = isEqual(parsedGameInfo, testGame); - expect(result).to.be.true; - }); -}; diff --git a/test/suites/searcher-test.js b/test/suites/searcher-test.js deleted file mode 100644 index ce6617f..0000000 --- a/test/suites/searcher-test.js +++ /dev/null @@ -1,65 +0,0 @@ -"use strict"; - -// Public module from npm -const expect = require("chai").expect; -const dotenv = require("dotenv"); - -// Modules from file -const Credentials = require("../../app/scripts/classes/credentials.js"); -const searcher = require("../../app/scripts/searcher.js"); -const { authenticate } = require("../../app/scripts/network-helper.js"); -const { fetchPlatformData } = require("../../app/scripts/platform-data.js"); - -// Configure the .env reader -dotenv.config(); - -// Global variables -const USERNAME = process.env.F95_USERNAME; -const PASSWORD = process.env.F95_PASSWORD; - -module.exports.suite = function suite() { - // TODO: - // This method should delete the store F95Zone cookies, - // but what if the other tests require them? - - // it("Search game when not logged", async function searchGameWhenNotLogged() { - // // Search for a game that we know has only one result - // // but without logging in first - // const urls = await searcher.searchGame("kingdom of deception"); - // expect(urls.lenght).to.be.equal(0, "There should not be any URL"); - // }); - - it("Search game", async function searchGame() { - // Authenticate - const result = await auth(); - expect(result.success, "Authentication should be successful").to.be.true; - - // Search for a game that we know has only one result - const urls = await searcher.searchGame("kingdom of deception"); - expect(urls.length).to.be.equal(1, `There should be only one game result instead of ${urls.length}`); - }); - - it("Search mod", async function searchMod() { - // Authenticate - const result = await auth(); - expect(result.success, "Authentication should be successful").to.be.true; - - // Search for a mod that we know has only one result - const urls = await searcher.searchMod("kingdom of deception jdmod"); - expect(urls.length).to.be.equal(1, `There should be only one mod result instead of ${urls.length}`); - }); -}; - -//#region Private methods -/** - * @private - * Simple wrapper for authentication. - */ -async function auth() { - const creds = new Credentials(USERNAME, PASSWORD); - await creds.fetchToken(); - const result = await authenticate(creds); - if (result.success) await fetchPlatformData(); - return result; -} -//#endregion Private methods \ No newline at end of file diff --git a/test/suites/user-scraper-test.js b/test/suites/user-scraper-test.js deleted file mode 100644 index 650eaa9..0000000 --- a/test/suites/user-scraper-test.js +++ /dev/null @@ -1,55 +0,0 @@ -"use strict"; - -// Public module from npm -const expect = require("chai").expect; -const dotenv = require("dotenv"); - -// Modules from file -const Credentials = require("../../app/scripts/classes/credentials.js"); -const uScraper = require("../../app/scripts/user-scraper.js"); -const { authenticate } = require("../../app/scripts/network-helper.js"); -const { fetchPlatformData } = require("../../app/scripts/platform-data.js"); - -// Configure the .env reader -dotenv.config(); - -// Global variables -const USERNAME = process.env.F95_USERNAME; -const PASSWORD = process.env.F95_PASSWORD; - -module.exports.suite = function suite() { - // TODO: - // This method should delete the store F95Zone cookies, - // but what if the other tests require them? - - // it("Fetch data when not logged", async function fetchUserDataWhenLogged() { - // const data = await uScraper.getUserData(); - // expect(data.username).to.be.equal(""); - // expect(data.avatarSrc).to.be.equal(""); - // expect(data.watchedThreads.length).to.be.equal(0); - // }); - - it("Fetch data when logged", async function fetchUserDataWhenNotLogged() { - // Authenticate - const result = await auth(); - expect(result.success, "Authentication should be successful").to.be.true; - - // We test only for the username, the other test data depends on the user logged - const data = await uScraper.getUserData(); - expect(data.username).to.be.equal(USERNAME); - }); -}; - -//#region Private methods -/** - * @private - * Simple wrapper for authentication. - */ -async function auth() { - const creds = new Credentials(USERNAME, PASSWORD); - await creds.fetchToken(); - const result = await authenticate(creds); - if (result.success) await fetchPlatformData(); - return result; -} -//#endregion Private methods \ No newline at end of file