diff --git a/src/utils/getSubmissionUUID.ts b/src/utils/getSubmissionUUID.ts index aafec805..af6e6641 100644 --- a/src/utils/getSubmissionUUID.ts +++ b/src/utils/getSubmissionUUID.ts @@ -1,14 +1,14 @@ import { getHash } from "./getHash"; import { HashedValue } from "../types/hash.model"; import { ActionType, VideoID, Service, Category } from "../types/segments.model"; -import { UserID } from "../types/user.model"; +import { HashedUserID } from "../types/user.model"; export function getSubmissionUUID( videoID: VideoID, category: Category, actionType: ActionType, description: string, - userID: UserID, + userID: HashedUserID, startTime: number, endTime: number, service: Service diff --git a/test/case_boilerplate.txt b/test/case_boilerplate.txt new file mode 100644 index 00000000..41f9dbcf --- /dev/null +++ b/test/case_boilerplate.txt @@ -0,0 +1,22 @@ +import { db } from "../../src/databases/databases"; +import assert from "assert"; +import { client } from "../utils/httpClient"; +import { genUsers, User } from "../utils/genUser"; +import { insertSegment, insertVip } from "../utils/queryGen"; + +const endpoint = "/api/endpoint"; + +const postTestEndpoint = () => client({ + method: "POST", + url: endpoint, + data: { + } +}); + +const cases = [ + "firstCase", + "secondCase", + "thirdCase" +]; +const users = genUsers("endpoint", cases); +const vipUser = genUser("endpoint", "vip"); \ No newline at end of file diff --git a/test/cases/addFeatures.ts b/test/cases/addFeatures.ts index 657555e2..304222d2 100644 --- a/test/cases/addFeatures.ts +++ b/test/cases/addFeatures.ts @@ -1,68 +1,57 @@ import assert from "assert"; import { db } from "../../src/databases/databases"; -import { Feature, HashedUserID } from "../../src/types/user.model"; +import { Feature } from "../../src/types/user.model"; import { hasFeature } from "../../src/utils/features"; -import { getHash } from "../../src/utils/getHash"; import { client } from "../utils/httpClient"; +import { grantFeature, insertVip } from "../utils/queryGen"; +import { User, genUser, genUsers } from "../utils/genUser"; const endpoint = "/api/feature"; -const postAddFeatures = (userID: string, adminUserID: string, feature: Feature, enabled: string) => client({ +const postAddFeatures = (userID: string, adminUserID: string, feature: Feature, enabled: boolean) => client({ method: "POST", url: endpoint, data: { userID, feature, - enabled, + enabled: String(enabled), adminUserID } }); -const privateVipUserID = "VIPUser-addFeatures"; -const vipUserID = getHash(privateVipUserID); +const cases = [ + "grant", + "remove", + "update" +]; +const users = genUsers("addFeatures", cases); +const vipUser = genUser("addFeatures", "vip"); -const hashedUserID1 = "user1-addFeatures" as HashedUserID; -const hashedUserID2 = "user2-addFeatures" as HashedUserID; -const hashedUserID3 = "user3-addFeatures" as HashedUserID; +const testedFeature = Feature.ChapterSubmitter; +const validFeatures = [testedFeature]; -const validFeatures = [Feature.ChapterSubmitter]; +const updateValidateFeature = (user: User, feature: Feature, grant: boolean, issuer: User): Promise => + postAddFeatures(user.pubID, issuer.privID, feature, grant) + .then(res => assert.strictEqual(res.status, 200)) // ensure request was successful + .then(() => hasFeature(user.pubID, feature)) + .then(result => assert.strictEqual(result, grant)); // ensure user has new feature describe("addFeatures", () => { - before(() => { - const userFeatureQuery = `INSERT INTO "userFeatures" ("userID", "feature", "issuerUserID", "timeSubmitted") VALUES(?, ?, ?, ?)`; - - return Promise.all([ - db.prepare("run", `INSERT INTO "vipUsers" ("userID") VALUES (?)`, [vipUserID]), - - db.prepare("run", userFeatureQuery, [hashedUserID2, Feature.ChapterSubmitter, "some-user", 0]), - db.prepare("run", userFeatureQuery, [hashedUserID3, Feature.ChapterSubmitter, "some-user", 0]) - ]); + before(async () => { + await insertVip(db, vipUser.pubID); + await grantFeature(db, users["remove"].pubID, testedFeature, vipUser.pubID); + await grantFeature(db, users["update"].pubID, testedFeature, vipUser.pubID); }); - it("can add features", async () => { + it("can add features", (done) => { for (const feature of validFeatures) { - const result = await postAddFeatures(hashedUserID1, privateVipUserID, feature, "true"); - assert.strictEqual(result.status, 200); - - assert.strictEqual(await hasFeature(hashedUserID1, feature), true); + updateValidateFeature(users["grant"], feature, true, vipUser) + .catch(err => done(err)); } + done(); }); - it("can remove features", async () => { - const feature = Feature.ChapterSubmitter; + it("can remove features", () => updateValidateFeature(users["remove"], testedFeature, false, vipUser)); - const result = await postAddFeatures(hashedUserID2, privateVipUserID, feature, "false"); - assert.strictEqual(result.status, 200); - - assert.strictEqual(await hasFeature(hashedUserID2, feature), false); - }); - - it("can update features", async () => { - const feature = Feature.ChapterSubmitter; - - const result = await postAddFeatures(hashedUserID3, privateVipUserID, feature, "true"); - assert.strictEqual(result.status, 200); - - assert.strictEqual(await hasFeature(hashedUserID3, feature), true); - }); + it("can update features", () => updateValidateFeature(users["update"], testedFeature, true, vipUser)); }); \ No newline at end of file diff --git a/test/cases/addUserAsVIP.ts b/test/cases/addUserAsVIP.ts index ebbcd6fc..a7ee90ff 100644 --- a/test/cases/addUserAsVIP.ts +++ b/test/cases/addUserAsVIP.ts @@ -1,19 +1,19 @@ -import { getHash } from "../../src/utils/getHash"; import { HashedUserID } from "../../src/types/user.model"; import { client } from "../utils/httpClient"; import { db } from "../../src/databases/databases"; import assert from "assert"; +import { genAnonUser, genUsers } from "../utils/genUser"; // helpers const checkUserVIP = (publicID: string) => db.prepare("get", `SELECT "userID" FROM "vipUsers" WHERE "userID" = ?`, [publicID]); +const cases = [ + "vip-1", +]; +const users = genUsers("endpoint", cases); + +// hardcoded into test code const adminPrivateUserID = "testUserId"; -const permVIP1 = "addVIP_permaVIPOne"; -const publicPermVIP1 = getHash(permVIP1) as HashedUserID; -const permVIP2 = "addVIP_permaVIPTwo"; -const publicPermVIP2 = getHash(permVIP2) as HashedUserID; -const permVIP3 = "addVIP_permaVIPThree"; -const publicPermVIP3 = getHash(permVIP3) as HashedUserID; const endpoint = "/api/addUserAsVIP"; const addUserAsVIP = (userID: string, enabled: boolean, adminUserID = adminPrivateUserID) => client({ @@ -26,116 +26,68 @@ const addUserAsVIP = (userID: string, enabled: boolean, adminUserID = adminPriva } }); +const testVIPUpdate = (target: HashedUserID, enabled: boolean, adminID: string = adminPrivateUserID) => + addUserAsVIP(target, enabled, adminID) + .then(res => assert.strictEqual(res.status, 200)) + .then(() => checkUserVIP(target)) + .then(row => assert.ok(Boolean(row) == enabled)); + +const statusTest = (status: number, data: Record) => + client({ + method: "POST", + url: endpoint, + params: data + }).then(res => assert.strictEqual(res.status, status)); + describe("addVIP test", function() { - it("User should not already be VIP", (done) => { - checkUserVIP(publicPermVIP1) - .then(result => { - assert.ok(!result); - done(); - }) - .catch(err => done(err)); - }); - it("Should be able to add user as VIP", (done) => { - addUserAsVIP(publicPermVIP1, true) - .then(async res => { - assert.strictEqual(res.status, 200); - const row = await checkUserVIP(publicPermVIP1); - assert.ok(row); - done(); - }) - .catch(err => done(err)); - }); - it("Should be able to add second user as VIP", (done) => { - addUserAsVIP(publicPermVIP2, true) - .then(async res => { - assert.strictEqual(res.status, 200); - const row = await checkUserVIP(publicPermVIP2); - assert.ok(row); - done(); - }) - .catch(err => done(err)); - }); - it("Should return 403 with invalid adminID", (done) => { - addUserAsVIP(publicPermVIP1, true, "Invalid_Admin_User_ID") - .then(res => { - assert.strictEqual(res.status, 403); - done(); - }) - .catch(err => done(err)); - }); - it("Should return 400 with missing adminID", (done) => { - client({ - method: "POST", - url: endpoint, - params: { - userID: publicPermVIP1, - enabled: String(true) - } + it("User should not already be VIP", () => + checkUserVIP(users["vip-1"].pubID) + .then(result => assert.ok(!result)) + ); + it("Should be able to add user as VIP", () => + testVIPUpdate(users["vip-1"].pubID, true) + ); + it("Should be able to remove VIP", () => + testVIPUpdate(users["vip-1"].pubID, false) + ); + it("Should be able to add second user as VIP", () => + testVIPUpdate(genAnonUser().pubID, true) + ); + it("Should return 403 with invalid adminID", () => + addUserAsVIP(genAnonUser().pubID, true, genAnonUser().privID) + .then(res => assert.strictEqual(res.status, 403)) + ); + it("Should return 400 with missing adminID", () => + statusTest(400, { + userID: genAnonUser().pubID, + enabled: String(true) }) - .then(res => { - assert.strictEqual(res.status, 400); - done(); - }) - .catch(err => done(err)); - }); - it("Should return 400 with missing userID", (done) => { - client({ - method: "POST", - url: endpoint, - params: { - enabled: String(true), - adminUserID: adminPrivateUserID - } + ); + it("Should return 400 with missing userID", () => + statusTest(400, { + enabled: String(true), + adminUserID: adminPrivateUserID }) - .then(res => { - assert.strictEqual(res.status, 400); - done(); - }) - .catch(err => done(err)); - }); - it("Should be able to remove VIP", (done) => { - addUserAsVIP(publicPermVIP1, false) - .then(async res => { - assert.strictEqual(res.status, 200); - const row = await checkUserVIP(publicPermVIP1); - assert.ok(!row); - done(); - }) - .catch(err => done(err)); - }); - it("Should remove VIP if enabled is false", (done) => { - client({ - method: "POST", - url: endpoint, - params: { - userID: publicPermVIP2, + ); + it("Should remove VIP if enabled is not true", () => { + const user = genAnonUser(); + return testVIPUpdate(user.pubID, true) + .then(() => statusTest(200, { + userID: user.pubID, adminUserID: adminPrivateUserID, enabled: "invalid-text" - } - }) - .then(async res => { - assert.strictEqual(res.status, 200); - const row = await checkUserVIP(publicPermVIP2); - assert.ok(!row); - done(); - }) - .catch(err => done(err)); + })) + .then(() => checkUserVIP(user.pubID)) + .then(row => assert.ok(!row)); }); - it("Should remove VIP if enabled is missing", (done) => { - client({ - method: "POST", - url: endpoint, - params: { - userID: publicPermVIP3, - adminUserID: adminPrivateUserID - } - }) - .then(async res => { - assert.strictEqual(res.status, 200); - const row = await checkUserVIP(publicPermVIP3); - assert.ok(!row); - done(); - }) - .catch(err => done(err)); + it("Should remove VIP if enabled is missing", () => { + const user = genAnonUser(); + return testVIPUpdate(user.pubID, true) + .then(() => statusTest(200, { + userID: user.pubID, + adminUserID: adminPrivateUserID, + })) + .then(() => checkUserVIP(user.pubID)) + .then(row => assert.ok(!row)); }); }); \ No newline at end of file diff --git a/test/cases/eTag.ts b/test/cases/eTag.ts index 162b2059..f98dddca 100644 --- a/test/cases/eTag.ts +++ b/test/cases/eTag.ts @@ -16,14 +16,10 @@ describe("eTag", () => { }); const endpoint = "/etag"; - it("Should reject weak etag", (done) => { + it("Should reject weak etag", () => { const etagKey = `W/test-etag-${genRandom()}`; - client.get(endpoint, { headers: { "If-None-Match": etagKey } }) - .then(res => { - assert.strictEqual(res.status, 404); - done(); - }) - .catch(err => done(err)); + return client.get(endpoint, { headers: { "If-None-Match": etagKey } }) + .then(res => assert.strictEqual(res.status, 404)); }); }); @@ -34,32 +30,29 @@ describe("304 etag validation", () => { const endpoint = "/etag"; for (const hashType of ["skipSegments", "skipSegmentsHash", "videoLabel", "videoLabelHash"]) { - it(`${hashType} etag should return 304`, (done) => { + it(`${hashType} etag should return 304`, () => { const etagKey = `${hashType};${genRandom};YouTube;${Date.now()}`; - redis.setEx(etagKey, 8400, "test").then(() => + return redis.setEx(etagKey, 8400, "test").then(() => client.get(endpoint, { headers: { "If-None-Match": etagKey } }).then(res => { assert.strictEqual(res.status, 304); const etag = res.headers?.etag ?? ""; assert.ok(validateEtag(etagKey, etag)); - done(); - }).catch(err => done(err)) + }) ); }); } - it(`other etag type should not return 304`, (done) => { + it(`other etag type should not return 304`, () => { const etagKey = `invalidHashType;${genRandom};YouTube;${Date.now()}`; - client.get(endpoint, { headers: { "If-None-Match": etagKey } }).then(res => { + return client.get(endpoint, { headers: { "If-None-Match": etagKey } }).then(res => { assert.strictEqual(res.status, 404); - done(); - }).catch(err => done(err)); + }); }); - it(`outdated etag type should not return 304`, (done) => { + it(`outdated etag type should not return 304`, () => { const etagKey = `skipSegments;${genRandom};YouTube;5000`; - client.get(endpoint, { headers: { "If-None-Match": etagKey } }).then(res => { + return client.get(endpoint, { headers: { "If-None-Match": etagKey } }).then(res => { assert.strictEqual(res.status, 404); - done(); - }).catch(err => done(err)); + }); }); }); \ No newline at end of file diff --git a/test/cases/getChapterNames.ts b/test/cases/getChapterNames.ts index c73c923f..01bb7c53 100644 --- a/test/cases/getChapterNames.ts +++ b/test/cases/getChapterNames.ts @@ -3,59 +3,43 @@ import { db } from "../../src/databases/databases"; import { Postgres } from "../../src/databases/Postgres"; import { client } from "../utils/httpClient"; import { partialDeepEquals } from "../utils/partialDeepEquals"; - -// Only works with Postgres -if (db instanceof Postgres) { - - describe("getChapterNames", function () { - const endpoint = "/api/chapterNames"; - - const chapterNamesVid1 = "chapterNamesVid"; - const chapterChannelID = "chapterChannelID"; - - before(async () => { - const query = 'INSERT INTO "sponsorTimes" ("videoID", "startTime", "endTime", "votes", "locked", "UUID", "userID", "timeSubmitted", "views", "category", "actionType", "service", "videoDuration", "hidden", "shadowHidden", "description") VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'; - await db.prepare("run", query, [chapterNamesVid1, 60, 80, 2, 0, "chapterNamesVid-1", "testman", 0, 50, "chapter", "chapter", "YouTube", 0, 0, 0, "Weird name"]); - await db.prepare("run", query, [chapterNamesVid1, 70, 75, 2, 0, "chapterNamesVid-2", "testman", 0, 50, "chapter", "chapter", "YouTube", 0, 0, 0, "A different one"]); - await db.prepare("run", query, [chapterNamesVid1, 71, 76, 2, 0, "chapterNamesVid-3", "testman", 0, 50, "chapter", "chapter", "YouTube", 0, 0, 0, "Something else"]); - - await db.prepare("run", `INSERT INTO "videoInfo" ("videoID", "channelID", "title", "published") - SELECT ?, ?, ?, ?`, [ - chapterNamesVid1, chapterChannelID, "", 0 - ]); - }); - - it("Search for 'weird'", async () => { - const result = await client.get(`${endpoint}?description=weird&channelID=${chapterChannelID}`); - const expected = [{ - description: "Weird name", - }]; - - assert.strictEqual(result.status, 200); - assert.strictEqual(result.data.length, 3); - assert.ok(partialDeepEquals(result.data, expected)); - }); - - it("Search for 'different'", async () => { - const result = await client.get(`${endpoint}?description=different&channelID=${chapterChannelID}`); - const expected = [{ - description: "A different one", - }]; - - assert.strictEqual(result.status, 200); - assert.strictEqual(result.data.length, 3); - assert.ok(partialDeepEquals(result.data, expected)); - }); - - it("Search for 'something'", async () => { - const result = await client.get(`${endpoint}?description=something&channelID=${chapterChannelID}`); - const expected = [{ - description: "Something else", - }]; - - assert.strictEqual(result.status, 200); - assert.strictEqual(result.data.length, 3); - assert.ok(partialDeepEquals(result.data, expected)); - }); +import { insertChapter } from "../utils/segmentQueryGen"; +import { genRandomValue } from "../utils/getRandom"; +import { insertVideoInfo } from "../utils/queryGen"; + +describe("getChapterNames", function () { + const endpoint = "/api/chapterNames"; + + const chapterNamesVid1 = genRandomValue("video", "getChapterNames"); + const chapterChannelID = genRandomValue("channel", "getChapterNames"); + const chapterNames = [ + "Weird name", + "A different one", + "Something else", + ]; + + const nameSearch = (query: string, expected: string): Promise => { + const expectedData = [{ + description: expected + }]; + return client.get(`${endpoint}?description=${query}&channelID=${chapterChannelID}`) + .then(res => { + assert.strictEqual(res.status, 200); + assert.strictEqual(res.data.length, chapterNames.length); + assert.ok(partialDeepEquals(res.data, expectedData)); + }); + }; + + before(async function() { + if (!(db instanceof Postgres)) this.skip(); // only works with Postgres + await insertChapter(db, chapterNames[0], { videoID: chapterNamesVid1, startTime: 60, endTime: 80 }); + await insertChapter(db, chapterNames[1], { videoID: chapterNamesVid1, startTime: 70, endTime: 75 }); + await insertChapter(db, chapterNames[2], { videoID: chapterNamesVid1, startTime: 71, endTime: 76 }); + + await insertVideoInfo(db, chapterNamesVid1, chapterChannelID); }); -} \ No newline at end of file + + it("Search for 'weird'", () => nameSearch("weird", chapterNames[0])); + it("Search for 'different'", () => nameSearch("different", chapterNames[1])); + it("Search for 'something'", () => nameSearch("something", chapterNames[2])); +}); \ No newline at end of file diff --git a/test/cases/getIP.ts b/test/cases/getIP.ts index f761e01b..c4db5f99 100644 --- a/test/cases/getIP.ts +++ b/test/cases/getIP.ts @@ -50,9 +50,8 @@ describe("getIP stubs", () => { before(() => stub = sinon.stub(config, "mode").value(mode)); after(() => stub.restore()); - it("Should return production mode if stub worked", (done) => { + it("Should return production mode if stub worked", () => { assert.strictEqual(config.mode, mode); - done(); }); }); @@ -64,22 +63,20 @@ describe("getIP array tests", () => { }); for (const [key, value] of Object.entries(expectedIP4)) { - it(`Should return correct IPv4 from ${key}`, (done) => { + it(`Should return correct IPv4 from ${key}`, () => { stub2 = sinon.stub(config, "behindProxy").value(key); const ip = getIP(v4MockRequest); assert.strictEqual(config.behindProxy, key); assert.strictEqual(ip, value); - done(); }); } for (const [key, value] of Object.entries(expectedIP6)) { - it(`Should return correct IPv6 from ${key}`, (done) => { + it(`Should return correct IPv6 from ${key}`, () => { stub2 = sinon.stub(config, "behindProxy").value(key); const ip = getIP(v6MockRequest); assert.strictEqual(config.behindProxy, key); assert.strictEqual(ip, value); - done(); }); } }); @@ -91,19 +88,17 @@ describe("getIP true tests", () => { stub2.restore(); }); - it(`Should return correct IPv4 from with bool true`, (done) => { + it(`Should return correct IPv4 from with bool true`, () => { stub2 = sinon.stub(config, "behindProxy").value(true); const ip = getIP(v4MockRequest); assert.strictEqual(config.behindProxy, "X-Forwarded-For"); assert.strictEqual(ip, expectedIP4["X-Forwarded-For"]); - done(); }); - it(`Should return correct IPv4 from with string true`, (done) => { + it(`Should return correct IPv4 from with string true`, () => { stub2 = sinon.stub(config, "behindProxy").value("true"); const ip = getIP(v4MockRequest); assert.strictEqual(config.behindProxy, "X-Forwarded-For"); assert.strictEqual(ip, expectedIP4["X-Forwarded-For"]); - done(); }); }); \ No newline at end of file diff --git a/test/cases/getIsUserVIP.ts b/test/cases/getIsUserVIP.ts index 8f4c7f07..ae82239f 100644 --- a/test/cases/getIsUserVIP.ts +++ b/test/cases/getIsUserVIP.ts @@ -1,54 +1,42 @@ import { db } from "../../src/databases/databases"; -import { getHash } from "../../src/utils/getHash"; +import { genUsers, User } from "../utils/genUser"; import { client } from "../utils/httpClient"; import assert from "assert"; +import { insertVip } from "../utils/queryGen"; -const VIPUser = "isUserVIPVIP"; -const normalUser = "isUserVIPNormal"; const endpoint = "/api/isUserVIP"; const vipUserRequest = (userID: string) => client.get(endpoint, { params: { userID } }); +const checkVipStatus = (user: User, expected: boolean) => + vipUserRequest(user.privID) + .then(res => { + assert.strictEqual(res.status, 200); + assert.strictEqual(res.data.vip, expected); + }); + +const cases = [ + "vip", + "normal", +]; +const users = genUsers("endpoint", cases); describe("getIsUserVIP", () => { - before(() => { - db.prepare("run", 'INSERT INTO "vipUsers" ("userID") VALUES (?)', [getHash(VIPUser)]); + before(async () => { + await insertVip(db, users["vip"].pubID); }); - it("Should be able to get a 200", (done) => { - vipUserRequest(VIPUser) - .then(res => { - assert.strictEqual(res.status, 200, "response should be 200"); - done(); - }) - .catch(err => done(err)); - }); + // status checks + it("Should be able to get a 200", () => + vipUserRequest(users["vip"].privID) + .then(res => assert.strictEqual(res.status, 200)) + ); - it("Should get a 400 if no userID", (done) => { + it("Should get a 400 if no userID", () => client.get(endpoint) - .then(res => { - assert.strictEqual(res.status, 400, "response should be 400"); - done(); - }) - .catch(err => done(err)); - }); + .then(res => assert.strictEqual(res.status, 400, "response should be 400")) + ); - it("Should say a VIP is a VIP", (done) => { - vipUserRequest(VIPUser) - .then(res => { - assert.strictEqual(res.status, 200); - assert.strictEqual(res.data.vip, true); - done(); - }) - .catch(err => done(err)); - }); - - it("Should say a normal user is not a VIP", (done) => { - vipUserRequest(normalUser) - .then(res => { - assert.strictEqual(res.status, 200); - assert.strictEqual(res.data.vip, false); - done(); - }) - .catch(err => done(err)); - }); + // user checks + it("Should say a VIP is a VIP", () => checkVipStatus(users["vip"], true)); + it("Should say a normal user is not a VIP", () => checkVipStatus(users["normal"], false)); }); diff --git a/test/cases/getLockCategories.ts b/test/cases/getLockCategories.ts index cf8e6aca..21f0eb7d 100644 --- a/test/cases/getLockCategories.ts +++ b/test/cases/getLockCategories.ts @@ -1,26 +1,60 @@ -import { getHash } from "../../src/utils/getHash"; import { db } from "../../src/databases/databases"; import assert from "assert"; import { client } from "../utils/httpClient"; -import { mixedDeepEquals } from "../utils/partialDeepEquals"; +import { insertLock } from "../utils/queryGen"; +import { multiGenRandomValue } from "../utils/getRandom"; + const endpoint = "/api/lockCategories"; const defaultActionTypes = ["skip", "mute"]; + const getLockCategories = (videoID: string, actionType = defaultActionTypes, service = "YouTube") => client.get(endpoint, { params: { videoID, actionType, service } }); +const queryStatusCheck = (status: number, queryString: string) => + client.get(`${endpoint}${queryString}`) + .then(res => assert.strictEqual(res.status, status)); + +type lockResponse = { + categories?: string[], + reason?: string, + actionTypes?: string[] +} +type lockOverrides = { + actionTypes?: string[], + service?: string +} +const validateResponse = (videoID: string, overrides: lockOverrides = {}, expected: lockResponse): Promise => { + const actionTypes = overrides.actionTypes ?? defaultActionTypes; + const service = overrides.service ?? "YouTube"; + const defaultExpected = { categories: [ "sponsor" ], reason: "", actionTypes: defaultActionTypes }; + const expectedResponse = { ...defaultExpected, ...expected }; + return getLockCategories(videoID, actionTypes, service) + .then(res => { + assert.strictEqual(res.status, 200); + // modify both categories to sort() + res.data.categories?.sort(); + expectedResponse.categories?.sort(); + assert.deepStrictEqual(res.data, expectedResponse); + }); +}; + +const validate404 = (videoID: string, overrides: lockOverrides = {}): Promise => { + const actionTypes = overrides.actionTypes || defaultActionTypes; + const service = overrides.service || "YouTube"; + return getLockCategories(videoID, actionTypes, service) + .then(res => assert.strictEqual(res.status, 404)); +}; + +const videoIDs = multiGenRandomValue("video", "getLockCategories", 3); describe("getLockCategories", () => { before(async () => { - const insertVipUserQuery = 'INSERT INTO "vipUsers" ("userID") VALUES (?)'; - await db.prepare("run", insertVipUserQuery, [getHash("getLockCategoriesVIP")]); + await insertLock(db, { videoID: videoIDs[0], reason: "1-short" }); + await insertLock(db, { videoID: videoIDs[0], reason: "1-longer-reason", actionType: "mute", category: "interaction" }); - const insertLockCategoryQuery = 'INSERT INTO "lockCategories" ("userID", "videoID", "actionType","category", "reason", "service") VALUES (?, ?, ?, ?, ?, ?)'; - await db.prepare("run", insertLockCategoryQuery, [getHash("getLockCategoriesVIP"), "getLockCategory1", "skip", "sponsor", "1-short", "YouTube"]); - await db.prepare("run", insertLockCategoryQuery, [getHash("getLockCategoriesVIP"), "getLockCategory1", "mute", "interaction", "1-longer-reason", "YouTube"]); + await insertLock(db, { videoID: videoIDs[1], reason: "2-reason", category: "preview" }); - await db.prepare("run", insertLockCategoryQuery, [getHash("getLockCategoriesVIP"), "getLockCategory2", "skip", "preview", "2-reason", "YouTube"]); - - await db.prepare("run", insertLockCategoryQuery, [getHash("getLockCategoriesVIP"), "getLockCategory3", "mute", "nonmusic", "3-reason", "PeerTube"]); - await db.prepare("run", insertLockCategoryQuery, [getHash("getLockCategoriesVIP"), "getLockCategory3", "skip", "sponsor", "3-reason", "YouTube"]); - await db.prepare("run", insertLockCategoryQuery, [getHash("getLockCategoriesVIP"), "getLockCategory3", "full", "outro", "3-longer-reason", "YouTube"]); + await insertLock(db, { videoID: videoIDs[2], reason: "3-reason", category: "nonmusic", actionType: "mute", service: "PeerTube" }); + await insertLock(db, { videoID: videoIDs[2], reason: "3-reason" }); + await insertLock(db, { videoID: videoIDs[2], reason: "3-longer-reason", category: "selfpromo", actionType: "full" }); }); it("Should update the database version when starting the application", async () => { @@ -28,198 +62,87 @@ describe("getLockCategories", () => { assert.ok(version >= 29, `Version isn't greater than 29. Version is ${version}`); }); - it("Should be able to get multiple locks", (done) => { - getLockCategories("getLockCategory1") - .then(res => { - assert.strictEqual(res.status, 200); - const expected = { - categories: [ - "sponsor", - "interaction" - ], - reason: "1-longer-reason", - actionTypes: defaultActionTypes - }; - assert.ok(mixedDeepEquals(res.data, expected)); - done(); - }) - .catch(err => done(err)); - }); - - it("Should be able to get single locks", (done) => { - getLockCategories("getLockCategory2") - .then(res => { - assert.strictEqual(res.status, 200); - const expected = { - categories: [ - "preview" - ], - reason: "2-reason", - actionTypes: defaultActionTypes - }; - assert.deepStrictEqual(res.data, expected); - done(); - }) - .catch(err => done(err)); - }); - - it("should return 404 if no lock exists", (done) => { - getLockCategories("getLockCategoryNull") - .then(res => { - assert.strictEqual(res.status, 404); - done(); - }) - .catch(err => done(err)); - }); - - it("should return 400 if no videoID specified", (done) => { - client.get(endpoint) - .then(res => { - assert.strictEqual(res.status, 400); - done(); - }) - .catch(err => done(err)); - }); - - it("Should be able to get multiple locks with service", (done) => { - getLockCategories("getLockCategory1", defaultActionTypes, "YouTube") - .then(res => { - assert.strictEqual(res.status, 200); - const expected = { - categories: [ - "sponsor", - "interaction" - ], - reason: "1-longer-reason", - actionTypes: defaultActionTypes - }; - assert.ok(mixedDeepEquals(res.data, expected)); - done(); - }) - .catch(err => done(err)); - }); - - it("Should be able to get single locks with service", (done) => { - getLockCategories("getLockCategory3", defaultActionTypes, "PeerTube") - .then(res => { - assert.strictEqual(res.status, 200); - const expected = { - categories: [ - "nonmusic" - ], - reason: "3-reason", - actionTypes: defaultActionTypes - }; - assert.deepStrictEqual(res.data, expected); - done(); - }) - .catch(err => done(err)); - }); - - it("Should be able to get single locks with service", (done) => { - getLockCategories("getLockCategory3", defaultActionTypes, "Youtube") - .then(res => { - assert.strictEqual(res.status, 200); - const expected = { - categories: [ - "sponsor" - ], - reason: "3-reason", - actionTypes: defaultActionTypes - }; - assert.deepStrictEqual(res.data, expected); - done(); - }) - .catch(err => done(err)); - }); - - it("should return result from Youtube service if service not match", (done) => { - getLockCategories("getLockCategory3", defaultActionTypes, "Dailymotion") - .then(res => { - assert.strictEqual(res.status, 200); - const expected = { - categories: [ - "sponsor" - ], - reason: "3-reason", - actionTypes: defaultActionTypes - }; - assert.deepStrictEqual(res.data, expected); - done(); - }) - .catch(err => done(err)); - }); - - it("should return 404 if invalid actionTypes specified", (done) => { - getLockCategories("getLockCategory1", ["ban"]) - .then(res => { - assert.strictEqual(res.status, 404); - done(); - }) - .catch(err => done(err)); - }); - - it("should be able to get with specific actionType", (done) => { - getLockCategories("getLockCategory1", ["mute"]) - .then(res => { - assert.strictEqual(res.status, 200); - const expected = { - categories: [ - "interaction" - ], - reason: "1-longer-reason", - actionTypes: ["mute"] - }; - mixedDeepEquals(res.data, expected); - done(); - }) - .catch(err => done(err)); - }); - - it("Should be able to get skip, mute, full", (done) => { + // 200 tests + it("should return 200 by single actionType", () => queryStatusCheck(200, `?videoID=${videoIDs[0]}&actionType=mute`)); + it("should return 200 by single actionTypes JSON", () => queryStatusCheck(200, `?videoID=${videoIDs[0]}&actionTypes=["mute"]`)); + it("should return 200 by repeating actionTypes", () => queryStatusCheck(200, `?videoID=${videoIDs[0]}&actionType=mute&actionType=skip`) ); + + // 404 tests + it("should return 404 if no lock exists", () => validate404("getLockCategoryNull")); + it("should return 404 if invalid actionTypes specified", () => validate404(videoIDs[0], { actionTypes: ["ban"] })); + + // 400 tests + it("should return 400 if no videoID specified", () => queryStatusCheck(400, "")); + + // complicated response tests + it("Should be able to get multiple locks", () => + validateResponse(videoIDs[0], {}, { + categories: [ + "sponsor", + "interaction" + ], + reason: "1-longer-reason" + }) + ); + + it("Should be able to get single locks", () => + validateResponse(videoIDs[1], {}, { + categories: [ + "preview" + ], + reason: "2-reason", + }) + ); + + it("Should be able to get multiple locks with service", () => + validateResponse(videoIDs[0], {}, { + categories: [ + "sponsor", + "interaction" + ], + reason: "1-longer-reason", + }) + ); + + it("Should be able to get single locks with service", () => + validateResponse(videoIDs[2], { service: "PeerTube" }, { + categories: [ "nonmusic" ], + reason: "3-reason", + }) + ); + + it("Should be able to get single locks with service", () => + validateResponse(videoIDs[2], { service: "Youtube" }, { + reason: "3-reason", + }) + ); + + it("should return result from Youtube service if service not match", () => + validateResponse(videoIDs[2], { service: "Dailymotion" }, { + reason: "3-reason", + }) + ); + + it("should be able to get with specific actionType", () => + validateResponse(videoIDs[0], { actionTypes: ["mute"] }, { + categories: [ + "interaction" + ], + reason: "1-longer-reason", + actionTypes: ["mute"] + }) + ); + + it("Should be able to get skip, mute, full", () => { const actionTypes = [...defaultActionTypes, "full"]; - getLockCategories("getLockCategory3", actionTypes) - .then(res => { - assert.strictEqual(res.status, 200); - const expected = { - categories: [ - "sponsor", - "nonmusic", - "outro" - ], - reason: "3-longer-reason", - actionTypes - }; - mixedDeepEquals(res.data, expected); - done(); - }) - .catch(err => done(err)); - }); - - it("should return 200 by single actionType", (done) => { - client.get(`${endpoint}?videoID=getLockCategory1&actionType=mute`) - .then(res => { - assert.strictEqual(res.status, 200); - done(); - }) - .catch(err => done(err)); - }); - - it("should return 200 by single actionTypes JSON", (done) => { - client.get(`${endpoint}?videoID=getLockCategory1&actionTypes=["mute"]`) - .then(res => { - assert.strictEqual(res.status, 200); - done(); - }) - .catch(err => done(err)); - }); - - it("should return 200 by repeating actionTypes", (done) => { - client.get(`${endpoint}?videoID=getLockCategory1&actionType=mute&actionType=skip`) - .then(res => { - assert.strictEqual(res.status, 200); - done(); - }) - .catch(err => done(err)); + return validateResponse(videoIDs[2], { actionTypes }, { + categories: [ + "sponsor", + "selfpromo", + // "nonmusic", // no nonmusic since it's on other service + ], + reason: "3-longer-reason", + actionTypes + }); }); }); diff --git a/test/cases/getStatus.ts b/test/cases/getStatus.ts index f471404b..9b0b5dab 100644 --- a/test/cases/getStatus.ts +++ b/test/cases/getStatus.ts @@ -11,7 +11,7 @@ describe("getStatus", () => { dbVersion = (await db.prepare("get", "SELECT key, value FROM config where key = ?", ["version"])).value; }); - it("Should be able to get status", (done) => { + it("Should be able to get status", () => client.get(endpoint) .then(res => { assert.strictEqual(res.status, 200); @@ -22,106 +22,86 @@ describe("getStatus", () => { assert.ok(data.startTime); assert.ok(data.processTime >= 0); assert.ok(data.loadavg.length == 2); - done(); }) - .catch(err => done(err)); - }); + ); - it("Should be able to get uptime only", (done) => { + it("Should be able to get uptime only", () => client.get(`${endpoint}/uptime`) .then(res => { assert.strictEqual(res.status, 200); assert.ok(Number(res.data) >= 1); // uptime should be greater than 1s - done(); }) - .catch(err => done(err)); - }); + ); - it("Should be able to get commit only", (done) => { + it("Should be able to get commit only", () => client.get(`${endpoint}/commit`) .then(res => { assert.strictEqual(res.status, 200); assert.strictEqual(res.data, "test"); // commit should be test - done(); }) - .catch(err => done(err)); - }); + ); - it("Should be able to get db only", (done) => { + it("Should be able to get db only", () => client.get(`${endpoint}/db`) .then(res => { assert.strictEqual(res.status, 200); assert.strictEqual(Number(res.data), Number(dbVersion)); // commit should be test - done(); }) - .catch(err => done(err)); - }); + ); - it("Should be able to get startTime only", (done) => { + it("Should be able to get startTime only", () => client.get(`${endpoint}/startTime`) .then(res => { assert.strictEqual(res.status, 200); const now = Date.now(); assert.ok(Number(res.data) <= now); // startTime should be more than now - done(); }) - .catch(err => done(err)); - }); + ); - it("Should be able to get processTime only", (done) => { + it("Should be able to get processTime only", () => client.get(`${endpoint}/processTime`) .then(res => { assert.strictEqual(res.status, 200); assert.ok(Number(res.data) >= 0); - done(); }) - .catch(err => done(err)); - }); + ); - it("Should be able to get loadavg only", (done) => { + it("Should be able to get loadavg only", () => client.get(`${endpoint}/loadavg`) .then(res => { assert.strictEqual(res.status, 200); assert.ok(Number(res.data[0]) >= 0); assert.ok(Number(res.data[1]) >= 0); - done(); }) - .catch(err => done(err)); - }); + ); - it("Should be able to get statusRequests only", function (done) { + it("Should be able to get statusRequests only", function () { if (!config.redis?.enabled) this.skip(); - client.get(`${endpoint}/statusRequests`) + return client.get(`${endpoint}/statusRequests`) .then(res => { assert.strictEqual(res.status, 200); assert.ok(Number(res.data) > 1); - done(); - }) - .catch(err => done(err)); + }); }); - it("Should be able to get status with statusRequests", function (done) { + it("Should be able to get status with statusRequests", function () { if (!config.redis?.enabled) this.skip(); - client.get(endpoint) + return client.get(endpoint) .then(res => { assert.strictEqual(res.status, 200); const data = res.data; assert.ok(data.statusRequests > 2); - done(); - }) - .catch(err => done(err)); + }); }); - it("Should be able to get redis latency", function (done) { + it("Should be able to get redis latency", function () { if (!config.redis?.enabled) this.skip(); - client.get(endpoint) + return client.get(endpoint) .then(res => { assert.strictEqual(res.status, 200); const data = res.data; assert.ok(data.redisProcessTime >= 0); - done(); - }) - .catch(err => done(err)); + }); }); it("Should return commit unkown if not present", (done) => { diff --git a/test/cases/getSubmissionUUID.ts b/test/cases/getSubmissionUUID.ts index 93d6ae3e..ac22d5b3 100644 --- a/test/cases/getSubmissionUUID.ts +++ b/test/cases/getSubmissionUUID.ts @@ -1,12 +1,61 @@ import { getSubmissionUUID } from "../../src/utils/getSubmissionUUID"; import assert from "assert"; import { ActionType, VideoID, Service, Category } from "../../src/types/segments.model"; -import { UserID } from "../../src/types/user.model"; +import { HashedUserID } from "../../src/types/user.model"; +import { getHash } from "../../src/utils/getHash"; +import { HashedValue } from "../../src/types/hash.model"; +import { genAnonUser } from "../utils/genUser"; +import { genRandomValue } from "../utils/getRandom"; + +function testHash (segment: segment, version: number): HashedValue { + const manualHash = getHash(Object.values(segment).join(""), 1) as HashedValue; + const generatedHash = getSubmissionUUID(segment.videoID, segment.category, segment.actionType, segment.description, segment.userID, segment.startTime, segment.endTime, segment.service); + assert.strictEqual(version, Number(generatedHash.at(-1)), "version should match passed in version"); + assert.strictEqual(`${manualHash}${version}`, generatedHash); + return generatedHash; +} + +interface segment { + videoID: VideoID, + startTime: number, + endTime: number, + userID: HashedUserID, + description: string, + category: Category, + actionType: ActionType, + service: Service +} + +const version = 7; describe("getSubmissionUUID", () => { - it("Should return the hashed value", () => { - assert.strictEqual( - getSubmissionUUID("video001" as VideoID, "sponsor" as Category, "skip" as ActionType, "", "testuser001" as UserID, 13.33337, 42.000001, Service.YouTube), - "2a473bca993dd84d8c2f6a4785989b20948dfe0c12c00f6f143bbda9ed561dca7"); + it("Should return the hashed value identical to manually generated value", () => { + const segment: segment = { + videoID: "video001" as VideoID, + startTime: 13.33337, + endTime: 42.000001, + userID: "testuser001" as HashedUserID, + description: "", + category: "sponsor" as Category, + actionType: "skip" as ActionType, + service: Service.YouTube + }; + const testedHash = testHash(segment, version); + // test against baked hash + assert.strictEqual(testedHash, "2a473bca993dd84d8c2f6a4785989b20948dfe0c12c00f6f143bbda9ed561dca7"); + }); + it ("Should return identical hash for randomly generated values", () => { + const user = genAnonUser(); + const segment: segment = { + videoID: genRandomValue("video", "getUUID") as VideoID, + startTime: Math.random()*1000, + endTime: Math.random()*500, + userID: user.pubID, + description: genRandomValue("description", "getUUID"), + category: "sponsor" as Category, + actionType: "skip" as ActionType, + service: Service.YouTube + }; + testHash(segment, version); }); }); diff --git a/test/cases/getUserID.ts b/test/cases/getUserID.ts index a2558169..21d728b6 100644 --- a/test/cases/getUserID.ts +++ b/test/cases/getUserID.ts @@ -1,315 +1,120 @@ import { db } from "../../src/databases/databases"; -import { getHash } from "../../src/utils/getHash"; import assert from "assert"; import { client } from "../utils/httpClient"; import { AxiosResponse } from "axios"; +import { UsernameUser, genUser, genUsersUsername } from "../utils/genUser"; +import { insertUsernameBulk } from "../utils/queryGen"; const endpoint = "/api/userID"; -const getUserName = (username: string): Promise => client.get(endpoint, { params: { username } }); +const getUserName = (username: string, exact: any = false): Promise => client.get(endpoint, { params: { username, exact } }); + +const validateSearch = (query: string, users: UsernameUser[], exact: number | boolean = false): Promise => + getUserName(query, exact) + .then(res => { + assert.strictEqual(res.status, 200); + const expected = users.map(user => ({ + userName: user.username, + userID: user.pubID + })); + assert.deepStrictEqual(res.data, expected); + }); + +const validateSearchWithUser = (user: UsernameUser, exact = false): Promise => + validateSearch(user.username, [user], exact); + +const cases = new Map([ + ["fuzzy_1", "fuzzy user 01"], + ["fuzzy_2", "fuzzy user 02"], + ["specific_1", "specific user 03"], + ["repeating_1", "repeating"], + ["repeating_2", "repeating"], + ["redos_1", "0redis0"], + ["redos_2", "%redos%"], + ["redos_3", "_redos_"], + ["redos_4", "redos\\%"], + ["redos_5", "\\\\\\"], + ["exact_1", "a"], +]); + +const userPublicOne = genUser("getUserID", "public_1"); +const users = genUsersUsername("getUserID", cases); +users["public_1"] = { ...userPublicOne, username: userPublicOne.pubID }; describe("getUserID", () => { before(async () => { - const insertUserNameQuery = 'INSERT INTO "userNames" ("userID", "userName") VALUES(?, ?)'; - await db.prepare("run", insertUserNameQuery, [getHash("getuserid_user_01"), "fuzzy user 01"]); - await db.prepare("run", insertUserNameQuery, [getHash("getuserid_user_02"), "fuzzy user 02"]); - await db.prepare("run", insertUserNameQuery, [getHash("getuserid_user_03"), "specific user 03"]); - await db.prepare("run", insertUserNameQuery, [getHash("getuserid_user_04"), "repeating"]); - await db.prepare("run", insertUserNameQuery, [getHash("getuserid_user_05"), "repeating"]); - await db.prepare("run", insertUserNameQuery, [getHash("getuserid_user_06"), getHash("getuserid_user_06")]); - await db.prepare("run", insertUserNameQuery, [getHash("getuserid_user_07"), "0redos0"]); - await db.prepare("run", insertUserNameQuery, [getHash("getuserid_user_08"), "%redos%"]); - await db.prepare("run", insertUserNameQuery, [getHash("getuserid_user_09"), "_redos_"]); - await db.prepare("run", insertUserNameQuery, [getHash("getuserid_user_10"), "redos\\%"]); - await db.prepare("run", insertUserNameQuery, [getHash("getuserid_user_11"), "\\\\\\"]); - await db.prepare("run", insertUserNameQuery, [getHash("getuserid_user_12"), "a"]); + await insertUsernameBulk(db, users); }); - it("Should be able to get a 200", (done) => { + // status tests + it("Should be able to get a 200", () => getUserName("fuzzy user 01") - .then(res => { - assert.strictEqual(res.status, 200); - done(); - }) - .catch(err => done(err)); - }); - - it("Should be able to get a 400 (No username parameter)", (done) => { - client.get(endpoint) - .then(res => { - assert.strictEqual(res.status, 400); - done(); - }) - .catch(err => done(err)); - }); - - it("Should be able to get a 200 (username is public id)", (done) => { - client.get(endpoint, { params: { username: getHash("getuserid_user_06") } }) - .then(res => { - assert.strictEqual(res.status, 200); - done(); - }) - .catch(err => done(err)); - }); - - it("Should be able to get a 400 (username longer than 64 chars)", (done) => { - client.get(endpoint, { params: { username: `${getHash("getuserid_user_06")}0` } }) - .then(res => { - assert.strictEqual(res.status, 400); - done(); - }) - .catch(err => done(err)); - }); - - it("Should be able to get single username", (done) => { - client.get(endpoint, { params: { username: "fuzzy user 01" } }) - .then(res => { - assert.strictEqual(res.status, 200); - const expected = [{ - userName: "fuzzy user 01", - userID: getHash("getuserid_user_01") - }]; - assert.deepStrictEqual(res.data, expected); - done(); - }) - .catch(err => done(err)); - }); - - it("Should be able to get multiple fuzzy user info from start", (done) => { - getUserName("fuzzy user") - .then(res => { - assert.strictEqual(res.status, 200); - const expected = [{ - userName: "fuzzy user 01", - userID: getHash("getuserid_user_01") - }, { - userName: "fuzzy user 02", - userID: getHash("getuserid_user_02") - }]; - assert.deepStrictEqual(res.data, expected); - done(); - }) - .catch(err => done(err)); - }); - - it("Should be able to get multiple fuzzy user info from middle", (done) => { - getUserName("user") - .then(res => { - assert.strictEqual(res.status, 200); - const expected = [{ - userName: "fuzzy user 01", - userID: getHash("getuserid_user_01") - }, { - userName: "fuzzy user 02", - userID: getHash("getuserid_user_02") - }, { - userName: "specific user 03", - userID: getHash("getuserid_user_03") - }]; - assert.deepStrictEqual(res.data, expected); - done(); - }) - .catch(err => done(err)); - }); - - it("Should be able to get with public ID", (done) => { - const userID = getHash("getuserid_user_06"); - getUserName(userID) - .then(res => { - assert.strictEqual(res.status, 200); - const expected = [{ - userName: userID, - userID - }]; - assert.deepStrictEqual(res.data, expected); - done(); - }) - .catch(err => done(err)); - }); - - it("Should be able to get with fuzzy public ID", (done) => { - const userID = getHash("getuserid_user_06"); - getUserName(userID.substr(10,60)) - .then(res => { - assert.strictEqual(res.status, 200); - const expected = [{ - userName: userID, - userID - }]; - assert.deepStrictEqual(res.data, expected); - done(); - }) - .catch(err => done(err)); - }); - - it("Should be able to get repeating username", (done) => { - getUserName("repeating") - .then(res => { - assert.strictEqual(res.status, 200); - const expected = [{ - userName: "repeating", - userID: getHash("getuserid_user_04") - }, { - userName: "repeating", - userID: getHash("getuserid_user_05") - }]; - assert.deepStrictEqual(res.data, expected); - done(); - }) - .catch(err => done(err)); - }); - - it("Should be able to get repeating fuzzy username", (done) => { - getUserName("peat") - .then(res => { - assert.strictEqual(res.status, 200); - const expected = [{ - userName: "repeating", - userID: getHash("getuserid_user_04") - }, { - userName: "repeating", - userID: getHash("getuserid_user_05") - }]; - assert.deepStrictEqual(res.data, expected); - done(); - }) - .catch(err => done(err)); - }); - - it("should avoid ReDOS with _", (done) => { - getUserName("_redos_") - .then(res => { - assert.strictEqual(res.status, 200); - const expected = [{ - userName: "_redos_", - userID: getHash("getuserid_user_09") - }]; - assert.deepStrictEqual(res.data, expected); - done(); - }) - .catch(err => done(err)); - }); - - it("should avoid ReDOS with %", (done) => { - getUserName("%redos%") - .then(res => { - assert.strictEqual(res.status, 200); - const expected = [{ - userName: "%redos%", - userID: getHash("getuserid_user_08") - }]; - assert.deepStrictEqual(res.data, expected); - done(); - }) - .catch(err => done(err)); - }); - - it("should return 404 if escaped backslashes present", (done) => { - getUserName("%redos\\\\_") - .then(res => { - assert.strictEqual(res.status, 404); - done(); - }) - .catch(err => done(err)); - }); - - it("should return 404 if backslashes present", (done) => { - getUserName(`\\%redos\\_`) - .then(res => { - assert.strictEqual(res.status, 404); - done(); - }) - .catch(err => done(err)); - }); - - it("should return user if just backslashes", (done) => { - getUserName(`\\\\\\`) - .then(res => { - assert.strictEqual(res.status, 200); - const expected = [{ - userName: "\\\\\\", - userID: getHash("getuserid_user_11") - }]; - assert.deepStrictEqual(res.data, expected); - done(); - }) - .catch(err => done(err)); - }); - - it("should not allow usernames more than 64 characters", (done) => { - getUserName("0".repeat(65)) - .then(res => { - assert.strictEqual(res.status, 400); - done(); - }) - .catch(err => done(err)); - }); - - it("should not allow usernames less than 3 characters", (done) => { - getUserName("aa") - .then(res => { - assert.strictEqual(res.status, 400); - done(); - }) - .catch(err => done(err)); - }); - - it("should allow exact match", (done) => { - client.get(endpoint, { params: { username: "a", exact: true } }) - .then(res => { - assert.strictEqual(res.status, 200); - const expected = [{ - userName: "a", - userID: getHash("getuserid_user_12") - }]; - assert.deepStrictEqual(res.data, expected); - done(); - }) - .catch(err => done(err)); - }); - - it("Should be able to get repeating username with exact username", (done) => { - client.get(endpoint, { params: { username: "repeating", exact: true } }) - .then(res => { - assert.strictEqual(res.status, 200); - const expected = [{ - userName: "repeating", - userID: getHash("getuserid_user_04") - }, { - userName: "repeating", - userID: getHash("getuserid_user_05") - }]; - assert.deepStrictEqual(res.data, expected); - done(); - }) - .catch(err => done(err)); - }); + .then(res => assert.strictEqual(res.status, 200)) + ); + + it("Should be able to get a 200 (username is public id)", () => + getUserName(users["public_1"].username) + .then(res => assert.strictEqual(res.status, 200)) + ); + + // individual user tests + it("Should be able to get single username", () => validateSearchWithUser(users["fuzzy_1"])); + it("Should be able to get with public ID", () => validateSearchWithUser(users["public_1"])); + + // individual user ReDOS + it("should avoid ReDOS with _", () => validateSearchWithUser(users["redos_3"])); + it("should avoid ReDOS with %", () => validateSearchWithUser(users["redos_2"])); + it("should return user if just backslashes", () => validateSearchWithUser(users["redos_5"])); + it("should allow exact match", () => validateSearchWithUser(users["exact_1"], true)); + + // fuzzy tests + it("Should be able to get multiple fuzzy user info from start", () => + validateSearch("fuzzy user", + [users["fuzzy_1"], users["fuzzy_2"]] + ) + ); + + it("Should be able to get multiple fuzzy user info from middle", () => { + validateSearch("user", + [users["fuzzy_1"], users["fuzzy_2"], users["specific_1"]] + ); + }); + + it("Should be able to get with fuzzy public ID", () => { + const userID = users["public_1"].pubID.substring(0,60); + return validateSearch(userID, + [users["public_1"]] + ); + }); + + it("Should be able to get repeating username", () => + validateSearch("repeating", [users["repeating_1"], users["repeating_2"]]) + ); + + it("Should be able to get repeating fuzzy username", () => + validateSearch("peat", [users["repeating_1"], users["repeating_2"]]) + ); + + it("Should be able to get repeating username with exact username", () => + validateSearch("repeating", [users["repeating_1"], users["repeating_2"]], true) + ); + + it("Should not get exact unless explicitly set to true", () => + validateSearch("user", [users["fuzzy_1"], users["fuzzy_2"], users["specific_1"]], 1) + ); +}); - it("Should not get exact unless explicitly set to true", (done) => { - client.get(endpoint, { params: { username: "user", exact: 1 } }) - .then(res => { - assert.strictEqual(res.status, 200); - const expected = [{ - userName: "fuzzy user 01", - userID: getHash("getuserid_user_01") - }, { - userName: "fuzzy user 02", - userID: getHash("getuserid_user_02") - }, { - userName: "specific user 03", - userID: getHash("getuserid_user_03") - }]; - assert.deepStrictEqual(res.data, expected); - done(); - }) - .catch(err => done(err)); - }); +describe("getUserID 400/ 404", () => { + const validateStatus = (query: string, status: number) => + getUserName(query) + .then(res => assert.strictEqual(res.status, status)); - it("should return 400 if no username parameter specified", (done) => { + it("Should be able to get a 400 (No username parameter)", () => client.get(endpoint) - .then(res => { - assert.strictEqual(res.status, 400); - done(); - }) - .catch(() => ("couldn't call endpoint")); - }); -}); + .then(res => assert.strictEqual(res.status, 400)) + ); + + it("Should not allow usernames more than 64 characters", () => validateStatus("0".repeat(65), 400)); + it("Should not allow usernames less than 3 characters", () => validateStatus("aa", 400)); + it("Should return 404 if escaped backslashes present", () => validateStatus("%redos\\\\_", 404)); + it("Should return 404 if backslashes present", () => validateStatus(`\\%redos\\_`, 404)); +}); \ No newline at end of file diff --git a/test/cases/getUserInfo.ts b/test/cases/getUserInfo.ts index 6df7443d..6f8249df 100644 --- a/test/cases/getUserInfo.ts +++ b/test/cases/getUserInfo.ts @@ -1,163 +1,123 @@ import { partialDeepEquals } from "../utils/partialDeepEquals"; import { db } from "../../src/databases/databases"; -import { getHash } from "../../src/utils/getHash"; import assert from "assert"; import { client } from "../utils/httpClient"; +import { insertSegment, insertThumbnail, insertThumbnailVote, insertTitle, insertTitleVote } from "../utils/segmentQueryGen"; +import { genUsers, User } from "../utils/genUser"; +import { genRandomValue } from "../utils/getRandom"; +import { insertBan, insertUsername, insertWarning } from "../utils/queryGen"; describe("getUserInfo", () => { const endpoint = "/api/userInfo"; - before(async () => { - const insertUserNameQuery = 'INSERT INTO "userNames" ("userID", "userName") VALUES(?, ?)'; - await db.prepare("run", insertUserNameQuery, [getHash("getuserinfo_user_01"), "Username user 01"]); - - const sponsorTimesQuery = 'INSERT INTO "sponsorTimes" ("videoID", "startTime", "endTime", "votes", "UUID", "userID", "timeSubmitted", views, category, "actionType", "shadowHidden") VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'; - await db.prepare("run", sponsorTimesQuery, ["getUserInfo0", 1, 11, 2, "uuid000001", getHash("getuserinfo_user_01"), 1, 10, "sponsor", "skip", 0]); - await db.prepare("run", sponsorTimesQuery, ["getUserInfo0", 1, 11, 2, "uuid000002", getHash("getuserinfo_user_01"), 2, 10, "sponsor", "skip", 0]); - await db.prepare("run", sponsorTimesQuery, ["getUserInfo1", 1, 11, -1, "uuid000003", getHash("getuserinfo_user_01"), 3, 10, "sponsor", "skip", 0]); - await db.prepare("run", sponsorTimesQuery, ["getUserInfo1", 1, 11, -2, "uuid000004", getHash("getuserinfo_user_01"), 4, 10, "sponsor", "skip", 1]); - await db.prepare("run", sponsorTimesQuery, ["getUserInfo2", 1, 11, -5, "uuid000005", getHash("getuserinfo_user_01"), 5, 10, "sponsor", "skip", 1]); - await db.prepare("run", sponsorTimesQuery, ["getUserInfo0", 1, 11, 2, "uuid000007", getHash("getuserinfo_user_02"), 7, 10, "sponsor", "skip", 1]); - await db.prepare("run", sponsorTimesQuery, ["getUserInfo0", 1, 11, 2, "uuid000008", getHash("getuserinfo_user_02"), 8, 10, "sponsor", "skip", 1]); - await db.prepare("run", sponsorTimesQuery, ["getUserInfo0", 0, 36000, 2,"uuid000009", getHash("getuserinfo_user_03"), 8, 10, "sponsor", "skip", 0]); - await db.prepare("run", sponsorTimesQuery, ["getUserInfo3", 1, 11, 2, "uuid000006", getHash("getuserinfo_user_02"), 6, 10, "sponsor", "skip", 0]); - await db.prepare("run", sponsorTimesQuery, ["getUserInfo4", 1, 11, 2, "uuid000010", getHash("getuserinfo_user_04"), 9, 10, "chapter", "chapter", 0]); - await db.prepare("run", sponsorTimesQuery, ["getUserInfo5", 1, 11, 2, "uuid000011", getHash("getuserinfo_user_05"), 9, 10, "sponsor", "skip", 0]); - await db.prepare("run", sponsorTimesQuery, ["getUserInfo6", 1, 11, 2, "uuid000012", getHash("getuserinfo_user_06"), 9, 10, "sponsor", "skip", 1]); - await db.prepare("run", sponsorTimesQuery, ["getUserInfo7", 1, 11, 2, "uuid000013", getHash("getuserinfo_ban_02"), 9, 10, "sponsor", "skip", 1]); - - const titlesQuery = 'INSERT INTO "titles" ("videoID", "title", "original", "userID", "service", "hashedVideoID", "timeSubmitted", "UUID") VALUES (?, ?, ?, ?, ?, ?, ?, ?)'; - const titleVotesQuery = 'INSERT INTO "titleVotes" ("UUID", "votes", "locked", "shadowHidden") VALUES (?, ?, ?, 0);'; - const thumbnailsQuery = 'INSERT INTO "thumbnails" ("videoID", "original", "userID", "service", "hashedVideoID", "timeSubmitted", "UUID") VALUES (?, ?, ?, ?, ?, ?, ?)'; - const thumbnailVotesQuery = 'INSERT INTO "thumbnailVotes" ("UUID", "votes", "locked", "shadowHidden") VALUES (?, ?, ?, 0)'; - await db.prepare("run", titlesQuery, ["getUserInfo6", "title0", 1, getHash("getuserinfo_user_01"), "YouTube", getHash("getUserInfo0"), 1, "uuid000001"]); - await db.prepare("run", titleVotesQuery, ["uuid000001", 0, 0]); - await db.prepare("run", thumbnailsQuery, ["getUserInfo6", 0, getHash("getuserinfo_user_01"), "YouTube", getHash("getUserInfo0"), 1, "uuid000002"]); - await db.prepare("run", thumbnailVotesQuery, ["uuid000002", 0, 0]); - await db.prepare("run", titlesQuery, ["getUserInfo6", "title1", 0, getHash("getuserinfo_user_01"), "YouTube", getHash("getUserInfo0"), 2, "uuid000003"]); - await db.prepare("run", titleVotesQuery, ["uuid000003", -1, 0]); - - const insertWarningQuery = 'INSERT INTO warnings ("userID", "issueTime", "issuerUserID", "enabled", "reason") VALUES (?, ?, ?, ?, ?)'; - await db.prepare("run", insertWarningQuery, [getHash("getuserinfo_warning_0"), 10, "getuserinfo_vip", 1, "warning0-0"]); - await db.prepare("run", insertWarningQuery, [getHash("getuserinfo_warning_1"), 20, "getuserinfo_vip", 1, "warning1-0"]); - await db.prepare("run", insertWarningQuery, [getHash("getuserinfo_warning_1"), 30, "getuserinfo_vip", 1, "warning1-1"]); - await db.prepare("run", insertWarningQuery, [getHash("getuserinfo_warning_2"), 40, "getuserinfo_vip", 0, "warning2-0"]); - await db.prepare("run", insertWarningQuery, [getHash("getuserinfo_warning_3"), 50, "getuserinfo_vip", 1, "warning3-0"]); - await db.prepare("run", insertWarningQuery, [getHash("getuserinfo_warning_3"), 60, "getuserinfo_vip", 0, "warning3-1"]); - - const insertBanQuery = 'INSERT INTO "shadowBannedUsers" ("userID") VALUES (?)'; - await db.prepare("run", insertBanQuery, [getHash("getuserinfo_ban_01")]); - await db.prepare("run", insertBanQuery, [getHash("getuserinfo_ban_02")]); - }); - it("Should be able to get a 200", (done) => { - client.get(endpoint, { params: { userID: "getuserinfo_user_01" } }) - .then(res => { - assert.strictEqual(res.status, 200); - done(); - }) - .catch(err => done(err)); - }); + const cases = [ + "n-0", + "n-1", + "n-2", + "n-3", + "n-4", + "n-5", + "n-6", + "null", + "vip", + "warn-0", + "warn-1", + "warn-2", + "warn-3", + "ban-1", + "ban-2", + ]; - it("Should be able to get a 400 (No userID parameter)", (done) => { - client.get(endpoint, { params: { userID: "" } }) - .then(res => { - assert.strictEqual(res.status, 400); - done(); - }) - .catch(err => done(err)); - }); - - it("Should be able to get user info", (done) => { - client.get(endpoint, { params: { userID: "getuserinfo_user_01" } }) - .then(res => { - assert.strictEqual(res.status, 200); - const expected = { - userName: "Username user 01", - userID: "66e7c974039ffb870a500a33eca3a3989861018909b938c313cf1a8a366800b8", - minutesSaved: 5, - viewCount: 30, - ignoredViewCount: 20, - segmentCount: 3, - ignoredSegmentCount: 2, - reputation: -1.5, - lastSegmentID: "uuid000005", - vip: false, - warnings: 0, - warningReason: "" - }; - assert.deepStrictEqual(res.data, expected); - done(); - }) - .catch(err => done(err)); - }); + const users = genUsers("endpoint", cases); + for (const [id, user] of Object.entries(users)) + // generate last segment UUIDs + user.info["last"] = genRandomValue("uuid", id); - it("Should get warning data", (done) => { - client.get(endpoint, { params: { userID: "getuserinfo_warning_0", value: "warnings" } }) + const checkValues = (user: User, expected: Record) => + client.get(endpoint, { params: { userID: user.privID, value: Object.keys(expected) } }) .then(res => { assert.strictEqual(res.status, 200); - const expected = { - warnings: 1 - }; assert.ok(partialDeepEquals(res.data, expected)); - done(); - }) - .catch(err => done(err)); - }); + }); - it("Should get warning data with public ID", (done) => { - client.get(endpoint, { params: { publicUserID: getHash("getuserinfo_warning_0"), values: `["warnings"]` } }) - .then(res => { - assert.strictEqual(res.status, 200); - const expected = { - warnings: 1 - }; - assert.ok(partialDeepEquals(res.data, expected)); - done(); - }) - .catch(err => done(err)); - }); + before(async () => { + users["n-1"].info["username"] = genRandomValue("username", "n-1"); + await insertUsername(db, users["n-1"].pubID, users["n-1"].info["username"]); - it("Should get multiple warnings", (done) => { - client.get(endpoint, { params: { userID: "getuserinfo_warning_1", value: "warnings" } }) - .then(res => { - assert.strictEqual(res.status, 200); - const expected = { - warnings: 2 - }; - assert.ok(partialDeepEquals(res.data, expected)); - done(); - }) - .catch(err => done(err)); - }); + // insert segments + const defaultSegmentParams = { startTime: 0, endTime: 10, votes: 2, views: 10 }; + // user["n-1"] + await insertSegment(db, { ...defaultSegmentParams, userID: users["n-1"].pubID }); + await insertSegment(db, { ...defaultSegmentParams, userID: users["n-1"].pubID }); + await insertSegment(db, { ...defaultSegmentParams, userID: users["n-1"].pubID, votes: -1 }); + await insertSegment(db, { ...defaultSegmentParams, userID: users["n-1"].pubID, votes: -2 }); + await insertSegment(db, { ...defaultSegmentParams, userID: users["n-1"].pubID, votes: -5, timeSubmitted: 5, UUID: users["n-1"].info.last }); + // user["n-2"] + await insertSegment(db, { ...defaultSegmentParams, userID: users["n-2"].pubID, shadowHidden: true }); + await insertSegment(db, { ...defaultSegmentParams, userID: users["n-2"].pubID, shadowHidden: true }); + await insertSegment(db, { ...defaultSegmentParams, userID: users["n-2"].pubID, timeSubmitted: 5, UUID: users["n-2"].info.last }); + // users n-3 to n-6 + await insertSegment(db, { ...defaultSegmentParams, userID: users["n-3"].pubID, UUID: users["n-3"].info.last, endTime: 36000 }); + await insertSegment(db, { ...defaultSegmentParams, userID: users["n-4"].pubID, UUID: users["n-4"].info.last, category: "chapter", actionType: "chapter" }); + await insertSegment(db, { ...defaultSegmentParams, userID: users["n-5"].pubID, UUID: users["n-5"].info.last }); + await insertSegment(db, { ...defaultSegmentParams, userID: users["n-6"].pubID, UUID: users["n-6"].info.last, shadowHidden: true }); + // ban-2 + await insertSegment(db, { ...defaultSegmentParams, userID: users["ban-2"].pubID, UUID: users["ban-2"].info.last, shadowHidden: true }); - it("Should not get warnings if none", (done) => { - client.get(endpoint, { params: { userID: "getuserinfo_warning_2", value: "warnings" } }) - .then(res => { - assert.strictEqual(res.status, 200); - const expected = { - warnings: 0, - }; - assert.ok(partialDeepEquals(res.data, expected)); - done(); - }) - .catch(err => done(err)); + // user["n-1"] + const userN1Video = genRandomValue("video", "getUserInfo-n1"); + // title 1 + const userN1UUID1 = genRandomValue("uuid", "getUserInfo-n1-u1"); + await insertTitle(db, { userID: users["n-1"].pubID, timeSubmitted: 1, videoID: userN1Video, UUID: userN1UUID1 }); + await insertTitleVote(db, userN1UUID1, 0); + // title 2 + const userN1UUID2 = genRandomValue("uuid", "getUserInfo-n1-u2"); + await insertTitle(db, { userID: users["n-1"].pubID, timeSubmitted: 2, videoID: userN1Video, UUID: userN1UUID2 }); + await insertTitleVote(db, userN1UUID2, -1); + // thumbnail 1 + const userN1UUID3 = genRandomValue("uuid", "getUserInfo-n1-u3"); + await insertThumbnail(db, { userID: users["n-1"].pubID, UUID: userN1UUID3 }); + await insertThumbnailVote(db, userN1UUID3, 0); + + // warnings & bans + // warn-0 + insertWarning(db, users["warn-0"].pubID, { reason: "warning0-0", issueTime: 10 }); + // warn-1 + insertWarning(db, users["warn-1"].pubID, { reason: "warning1-0", issueTime: 20 }); + insertWarning(db, users["warn-1"].pubID, { reason: "warning1-1", issueTime: 30 }); + // warn -2 + insertWarning(db, users["warn-2"].pubID, { reason: "warning2-0", issueTime: 40, enabled: false }); + // warn-3 + insertWarning(db, users["warn-3"].pubID, { reason: "warning3-0", issueTime: 50 }); + insertWarning(db, users["warn-3"].pubID, { reason: "warning3-1", issueTime: 60, enabled: false }); + + // ban- + insertBan(db, users["ban-1"].pubID); + insertBan(db, users["ban-2"].pubID); }); - it("Should done(userID for userName (No userName set)", (done) => { - client.get(endpoint, { params: { userID: "getuserinfo_user_02", value: "userName" } }) - .then(res => { - assert.strictEqual(res.status, 200); - const expected = { - userName: "c2a28fd225e88f74945794ae85aef96001d4a1aaa1022c656f0dd48ac0a3ea0f" - }; - assert.ok(partialDeepEquals(res.data, expected)); - done(); - }) - .catch(err => done(err)); + it("Should be able to get a 200", () => statusTest(200, { userID: users["n-1"].privID })); + + // value tests + + it("Should get title and vote submission counts", () => + checkValues(users["n-1"], { + titleSubmissionCount: 1, + thumbnailSubmissionCount: 1 + }) + ); + + // fallback/ null tests + it("Should return publidID if no username set", () => { + const user = users["n-2"]; + return checkValues(user, { + userName: user.pubID, + }); }); it("Should return null segment if none", (done) => { - client.get(endpoint, { params: { userID: "getuserinfo_null", value: "lastSegmentID" } }) + const user = users["null"]; + client.get(endpoint, { params: { userID: user.privID, value: "lastSegmentID" } }) .then(res => { assert.strictEqual(res.status, 200); assert.strictEqual(res.data.lastSegmentID, null); @@ -167,7 +127,8 @@ describe("getUserInfo", () => { }); it("Should return zeroes if userid does not exist", (done) => { - client.get(endpoint, { params: { userID: "getuserinfo_null", value: "lastSegmentID" } }) + const user = users["null"]; + client.get(endpoint, { params: { userID: user.privID, value: "lastSegmentID" } }) .then(res => { const data = res.data; for (const value in data) { @@ -180,243 +141,174 @@ describe("getUserInfo", () => { .catch(err => done(err)); }); - it("Should get warning reason from from single enabled warning", (done) => { - client.get(endpoint, { params: { userID: "getuserinfo_warning_0", values: `["warningReason"]` } }) + // warnings + it("Should get warning data with public ID", (done) => { + const user = users["warn-0"]; + client.get(endpoint, { params: { publicUserID: user.pubID, values: `["warnings"]` } }) .then(res => { assert.strictEqual(res.status, 200); const expected = { - warningReason: "warning0-0", + warnings: 1 }; assert.ok(partialDeepEquals(res.data, expected)); - done(); // pass + done(); }) .catch(err => done(err)); }); - it("Should get most recent warning from two enabled warnings", (done) => { - client.get(endpoint, { params: { userID: "getuserinfo_warning_1", value: "warningReason" } }) - .then(res => { - assert.strictEqual(res.status, 200); - const expected = { - warningReason: "warning1-1" - }; - assert.ok(partialDeepEquals(res.data, expected)); - done(); // pass - }) - .catch(err => done(err)); - }); + it("Should get warning reason from from single enabled warning", () => + checkValues(users["warn-0"], { + warnings: 1, + warningReason: "warning0-0", + }) + ); - it("Should not get disabled warning", (done) => { - client.get(endpoint, { params: { userID: "getuserinfo_warning_2", values: `["warnings","warningReason"]` } }) - .then(res => { - assert.strictEqual(res.status, 200); - const expected = { - warnings: 0, - warningReason: "" - }; - assert.ok(partialDeepEquals(res.data, expected)); - done(); // pass - }) - .catch(err => done(err)); - }); + it("Should get most recent warning from two enabled warnings", () => + checkValues(users["warn-1"], { + warnings: 2, + warningReason: "warning1-1" + }) + ); - it("Should not get newer disabled warning", (done) => { - client.get(`${endpoint}?userID=getuserinfo_warning_3&value=warnings&value=warningReason`) - .then(res => { - assert.strictEqual(res.status, 200); - const expected = { - warnings: 1, - warningReason: "warning3-0" - }; - assert.ok(partialDeepEquals(res.data, expected)); - done(); // pass - }) - .catch(err => done(err)); - }); + it("Should not get disabled warning", () => + checkValues(users["warn-2"], { + warnings: 0, + warningReason: "" + }) + ); - it("Should get 400 if bad values specified", (done) => { - client.get(endpoint, { params: { userID: "getuserinfo_warning_3", value: "invalid-value" } }) - .then(res => { - assert.strictEqual(res.status, 400); - done(); // pass - }) - .catch(err => done(err)); - }); + it("Should not get newer disabled warning", () => + checkValues(users["warn-3"], { + warnings: 1, + warningReason: "warning3-0" + }) + ); - it("Should get ban data for banned user (only appears when specifically requested)", (done) => { - client.get(endpoint, { params: { userID: "getuserinfo_ban_01", value: "banned" } }) - .then(res => { - assert.strictEqual(res.status, 200); - const expected = { - banned: true - }; - assert.ok(partialDeepEquals(res.data, expected)); - done(); // pass - }) - .catch(err => done(err)); - }); + // shadowban tests + it("Should get ban data for banned user (only appears when specifically requested)", () => + checkValues(users["ban-1"], { + banned: true + }) + ); - it("Should get ban data for unbanned user (only appears when specifically requested)", (done) => { - client.get(endpoint, { params: { userID: "getuserinfo_notban_01", value: "banned" } }) - .then(res => { - assert.strictEqual(res.status, 200); - const expected = { - banned: false - }; - assert.ok(partialDeepEquals(res.data, expected)); - done(); // pass - }) - .catch(err => done(err)); - }); + it("Should return all segments of banned user", () => + checkValues(users["ban-2"], { + segmentCount: 1 + }) + ); - it("Should throw 400 on bad json in values", (done) => { - client.get(endpoint, { params: { userID: "x", values: `[userID]` } }) - .then(res => { - assert.strictEqual(res.status, 400); - done(); // pass - }) - .catch(err => done(err)); - }); + it("Should not return shadowhidden segments of not-banned user", () => + checkValues(users["n-6"], { + segmentCount: 0, + banned: false + }) + ); - it("Should throw 400 with invalid array", (done) => { - client.get(endpoint, { params: { userID: "x", values: 123 } }) + // error 400 testing + const statusTest = (status: number, params: Record) => + client.get(endpoint, { params }) .then(res => { - assert.strictEqual(res.status, 400); - done(); // pass - }) - .catch(err => done(err)); - }); + assert.strictEqual(res.status, status); + }); - it("Should return 200 on userID not found", (done) => { - client.get(endpoint, { params: { userID: "notused-userid" } }) - .then(res => { - assert.strictEqual(res.status, 200); - const expected = { - minutesSaved: 0, - segmentCount: 0, - ignoredSegmentCount: 0, - viewCount: 0, - ignoredViewCount: 0, - warnings: 0, - warningReason: "", - reputation: 0, - vip: false, - }; - assert.ok(partialDeepEquals(res.data, expected)); - done(); // pass - }) - .catch(err => done(err)); - }); + it("Should throw 400 on bad json in values", () => statusTest(400, { userID: "x", values: `[userID]` })); + it("Should throw 400 with invalid array", () => statusTest(400, { userID: "x", values: 123 })); + it("Should throw 400 with empty userID)", () => statusTest(400, { userID: "" })); + it("Should throw 400 if bad values specified", () => statusTest(400, { userID: users["warn-3"].privID, value: "invalid-value" })); - it("Should only count long segments as 10 minutes", (done) => { - client.get(endpoint, { params: { userID: "getuserinfo_user_03" } }) + // full user stats + const fullUserStats = (params: Record, expected: Record) => + client.get(endpoint, { params }) .then(res => { assert.strictEqual(res.status, 200); - const expected = { - userName: "807e0a5d0a62c9c4365fae3d403e4618a3226f231314a898fa1555a0e55eab9e", - userID: "807e0a5d0a62c9c4365fae3d403e4618a3226f231314a898fa1555a0e55eab9e", - minutesSaved: 100, - viewCount: 10, - ignoredViewCount: 0, - segmentCount: 1, - ignoredSegmentCount: 0, - reputation: 0, - lastSegmentID: "uuid000009", - vip: false, - warnings: 0, - warningReason: "" - }; assert.deepStrictEqual(res.data, expected); - done(); - }) - .catch(err => done(err)); - }); - - it("Should be able to get permissions", (done) => { - client.get(endpoint, { params: { userID: "getuserinfo_user_01", value: "permissions" } }) - .then(res => { - assert.strictEqual(res.status, 200); - const expected = { - permissions: { - sponsor: true, - selfpromo: true, - exclusive_access: true, - interaction: true, - intro: true, - outro: true, - preview: true, - music_offtopic: true, - filler: true, - poi_highlight: true, - chapter: false, - }, - }; - assert.ok(partialDeepEquals(res.data, expected)); - done(); // pass }); + + const defaultUserInfo = { + minutesSaved: 0, + segmentCount: 0, + ignoredSegmentCount: 0, + viewCount: 0, + ignoredViewCount: 0, + warnings: 0, + warningReason: "", + reputation: 0, + lastSegmentID: "", + vip: false, + }; + + it("Should be able to get user info", () => { + const user = users["n-1"]; + const params = { userID: user.privID }; + return fullUserStats(params, { + ...defaultUserInfo, + userName: user.info.username, + userID: user.pubID, + minutesSaved: 5, + viewCount: 30, + ignoredViewCount: 20, + segmentCount: 3, + ignoredSegmentCount: 2, + reputation: -1.5, + lastSegmentID: user.info.last, + }); }); - it("Should ignore chapters for saved time calculations", (done) => { - client.get(endpoint, { params: { userID: "getuserinfo_user_04" } }) - .then(res => { - assert.strictEqual(res.status, 200); - const expected = { - userName: "f187933817e7b0211a3f6f7d542a63ca9cc289d6cc8a8a79669d69a313671ccf", - userID: "f187933817e7b0211a3f6f7d542a63ca9cc289d6cc8a8a79669d69a313671ccf", - minutesSaved: 0, - viewCount: 10, - ignoredViewCount: 0, - segmentCount: 1, - ignoredSegmentCount: 0, - reputation: 0, - lastSegmentID: "uuid000010", - vip: false, - warnings: 0, - warningReason: "" - }; - assert.deepStrictEqual(res.data, expected); - done(); - }) - .catch(err => done(err)); + it("Should only count long segments as 10 minutes", () => { + const user = users["n-3"]; + const params = { userID: user.privID }; + return fullUserStats(params, { + ...defaultUserInfo, + userName: user.pubID, + userID: user.pubID, + minutesSaved: 100, + viewCount: 10, + segmentCount: 1, + lastSegmentID: user.info.last, + }); }); - it("Should get title and vote submission counts", (done) => { - client.get(endpoint, { params: { userID: "getuserinfo_user_01", value: ["titleSubmissionCount", "thumbnailSubmissionCount"] } }) - .then(res => { - assert.strictEqual(res.status, 200); - const expected = { - titleSubmissionCount: 1, - thumbnailSubmissionCount: 1 - }; - assert.ok(partialDeepEquals(res.data, expected)); - done(); - }) - .catch(err => done(err)); + it("Should be able to get permissions", () => { + const user = users["n-1"]; + const params = { userID: user.privID, value: "permissions" }; + return fullUserStats(params, { + permissions: { + sponsor: true, + selfpromo: true, + exclusive_access: true, + interaction: true, + intro: true, + outro: true, + preview: true, + music_offtopic: true, + filler: true, + poi_highlight: true, + chapter: false, + }, + }); }); - it("Should return all segments of banned user", (done) => { - client.get(endpoint, { params: { userID: "getuserinfo_ban_02", value: ["segmentCount"] } }) - .then(res => { - assert.strictEqual(res.status, 200); - const expected = { - segmentCount: 1 - }; - assert.ok(partialDeepEquals(res.data, expected)); - done(); // pass - }) - .catch(err => done(err)); + it("Should ignore chapters for saved time calculations", () => { + const user = users["n-4"]; + const params = { userID: user.privID }; + return fullUserStats(params, { + ...defaultUserInfo, + userName: user.pubID, + userID: user.pubID, + viewCount: 10, + segmentCount: 1, + lastSegmentID: user.info.last, + }); }); - it("Should not return shadowhidden segments of not-banned user", (done) => { - client.get(endpoint, { params: { userID: "getuserinfo_user_06", value: ["segmentCount"] } }) - .then(res => { - assert.strictEqual(res.status, 200); - const expected = { - segmentCount: 0 - }; - assert.ok(partialDeepEquals(res.data, expected)); - done(); // pass - }) - .catch(err => done(err)); + it("Should return 200 on userID not found", () => { + const user = users["null"]; + const params = { userID: user.privID }; + return fullUserStats(params, { + ...defaultUserInfo, + userName: user.pubID, + userID: user.pubID, + lastSegmentID: null + }); }); }); diff --git a/test/cases/getViewsForUser.ts b/test/cases/getViewsForUser.ts index 9471e18c..a95cb5c9 100644 --- a/test/cases/getViewsForUser.ts +++ b/test/cases/getViewsForUser.ts @@ -1,7 +1,8 @@ -import { getHash } from "../../src/utils/getHash"; import { db } from "../../src/databases/databases"; import { client } from "../utils/httpClient"; import assert from "assert"; +import { genUsers, User } from "../utils/genUser"; +import { insertSegment } from "../utils/segmentQueryGen"; // helpers const endpoint = "/api/getViewsForUser"; @@ -10,53 +11,46 @@ const getViewsForUser = (userID: string) => client({ params: { userID } }); -const getViewUserOne = "getViewUser1"; -const userOneViewsFirst = 30; -const userOneViewsSecond = 0; +const cases = [ + "u-1", + "u-2", + "u-3" +]; +const users = genUsers("getViewUser", cases); -const getViewUserTwo = "getViewUser2"; -const userTwoViews = 0; - -const getViewUserThree = "getViewUser3"; +// set views for users +users["u-1"].info["views1"] = 30; +users["u-1"].info["views2"] = 0; +users["u-1"].info["views"] = users["u-1"].info.views1 + users["u-1"].info.views2; +users["u-2"].info["views"] = 0; +users["u-3"].info["views"] = 0; +const checkUserViews = (user: User) => + getViewsForUser(user.privID) + .then(result => { + assert.strictEqual(result.status, 200); + assert.strictEqual(result.data.viewCount, user.info.views); + }); describe("getViewsForUser", function() { before(() => { - const insertSponsorTimeQuery = 'INSERT INTO "sponsorTimes" ("videoID", "startTime", "endTime", "votes", "UUID", "userID", "timeSubmitted", views, category, "actionType", "videoDuration", "shadowHidden", "hashedVideoID") VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'; - db.prepare("run", insertSponsorTimeQuery, ["getViewUserVideo", 0, 1, 0, "getViewUserVideo0", getHash(getViewUserOne), 0, userOneViewsFirst, "sponsor", "skip", 0, 0, "getViewUserVideo"]); - db.prepare("run", insertSponsorTimeQuery, ["getViewUserVideo", 0, 1, 0, "getViewUserVideo1", getHash(getViewUserOne), 0, userOneViewsSecond, "sponsor", "skip", 0, 0, "getViewUserVideo"]); - db.prepare("run", insertSponsorTimeQuery, ["getViewUserVideo", 0, 1, 0, "getViewUserVideo2", getHash(getViewUserTwo), 0, userTwoViews, "sponsor", "skip", 0, 0, "getViewUserVideo"]); - }); - it("Should get back views for user one", (done) => { - getViewsForUser(getViewUserOne) - .then(result => { - assert.strictEqual(result.data.viewCount, userOneViewsFirst + userOneViewsSecond); - done(); - }) - .catch(err => done(err)); - }); - it("Should get back views for user two", (done) => { - getViewsForUser(getViewUserTwo) - .then(result => { - assert.strictEqual(result.data.viewCount, userTwoViews); - done(); - }) - .catch(err => done(err)); + // add views for users + insertSegment(db, { userID: users["u-1"].pubID, views: users["u-1"].info.views1 }); + insertSegment(db, { userID: users["u-1"].pubID, views: users["u-1"].info.views2 }); + insertSegment(db, { userID: users["u-2"].pubID, views: users["u-2"].info.views }); }); - it("Should get 404 if no submissions", (done) => { - getViewsForUser(getViewUserThree) - .then(result => { - assert.strictEqual(result.status, 404); - done(); - }) - .catch(err => done(err)); - }); - it("Should return 400 if no userID provided", (done) => { + it("Should get back views for user one", () => + checkUserViews(users["u-1"]) + ); + it("Should get back views for user two", () => + checkUserViews(users["u-2"]) + ); + it("Should get 404 if no submissions", () => + getViewsForUser(users["u-3"].pubID) + .then(result => assert.strictEqual(result.status, 404)) + ); + it("Should return 400 if no userID provided", () => client({ url: endpoint }) - .then(res => { - assert.strictEqual(res.status, 400); - done(); - }) - .catch(err => done(err)); - }); + .then(res => assert.strictEqual(res.status, 400)) + ); }); \ No newline at end of file diff --git a/test/cases/highLoad.ts b/test/cases/highLoad.ts index c997f6e2..cbedd1df 100644 --- a/test/cases/highLoad.ts +++ b/test/cases/highLoad.ts @@ -13,24 +13,18 @@ describe("High load test", () => { sinon.restore(); }); - it("Should return 503 on getTopUsers", async () => { - await client.get("/api/getTopUsers?sortType=0") - .then(res => { - assert.strictEqual(res.status, 503); - }); - }); + it("Should return 503 on getTopUsers", () => + client.get("/api/getTopUsers?sortType=0") + .then(res => assert.strictEqual(res.status, 503)) + ); - it("Should return 503 on getTopCategoryUsers", async () => { - await client.get("/api/getTopCategoryUsers?sortType=0&category=sponsor") - .then(res => { - assert.strictEqual(res.status, 503); - }); - }); + it("Should return 503 on getTopCategoryUsers", () => + client.get("/api/getTopCategoryUsers?sortType=0&category=sponsor") + .then(res => assert.strictEqual(res.status, 503)) + ); - it("Should return 0 on getTotalStats", async () => { - await client.get("/api/getTotalStats") - .then(res => { - assert.strictEqual(res.status, 200); - }); - }); + it("Should return 0 on getTotalStats", () => + client.get("/api/getTotalStats") + .then(res => assert.strictEqual(res.status, 200)) + ); }); diff --git a/test/cases/lockCategoriesHttp.ts b/test/cases/lockCategoriesHttp.ts index 8525d462..496c4c7e 100644 --- a/test/cases/lockCategoriesHttp.ts +++ b/test/cases/lockCategoriesHttp.ts @@ -1,9 +1,11 @@ import assert from "assert"; import { client } from "../utils/httpClient"; -import { getHash } from "../../src/utils/getHash"; import { db } from "../../src/databases/databases"; import { UserID } from "../../src/types/user.model"; import { Category, VideoID } from "../../src/types/segments.model"; +import { insertVipUser } from "../utils/queryGen"; +import { genUser } from "../utils/genUser"; +import { genRandomValue } from "../utils/getRandom"; interface LockCategory { category: Category, @@ -11,12 +13,10 @@ interface LockCategory { videoID: VideoID, userID: UserID } -const lockVIPUser = "lockCategoriesHttpVIPUser"; -const lockVIPUserHash = getHash(lockVIPUser); const endpoint = "/api/lockCategories"; +const lockUser = genUser("lockCategoriesHttp", "vip"); const checkLockCategories = (videoID: string): Promise => db.prepare("all", 'SELECT * FROM "lockCategories" WHERE "videoID" = ?', [videoID]); - const goodResponse = (): any => ({ videoID: "test-videoid", userID: "not-vip-test-userid", @@ -24,229 +24,109 @@ const goodResponse = (): any => ({ actionTypes: ["skip"] }); +const errTest = (method = "POST", override: any): Promise => { + const data = { ...goodResponse(), ...override }; + return client(endpoint, { method, data }) + .then(res => assert.strictEqual(res.status, 400)); +}; + +const statusTest = (method = "POST", data: any, status: number): Promise => + client(endpoint, { method, data }) + .then(res => assert.strictEqual(res.status, status)); + describe("POST lockCategories HTTP submitting", () => { before(async () => { - const insertVipUserQuery = 'INSERT INTO "vipUsers" ("userID") VALUES (?)'; - await db.prepare("run", insertVipUserQuery, [lockVIPUserHash]); - }); - - it("Should update the database version when starting the application", async () => { - const version = (await db.prepare("get", "SELECT key, value FROM config where key = ?", ["version"])).value; - assert.ok(version > 1); + await insertVipUser(db, lockUser); }); - it("should be able to add poi type category by type skip", (done) => { - const videoID = "add-record-poi"; - client.post(endpoint, { + it("should be able to add poi type category by type skip", () => { + const videoID = genRandomValue("video","lockCategoriesHttp"); + const json = { videoID, - userID: lockVIPUser, + userID: lockUser.privID, categories: ["poi_highlight"], actionTypes: ["skip"] - }) - .then(res => { - assert.strictEqual(res.status, 200); - checkLockCategories(videoID) - .then(result => { - assert.strictEqual(result.length, 1); - assert.strictEqual(result[0], "poi_highlight"); - }); - done(); - }) - .catch(err => done(err)); + }; + return statusTest("POST", json, 200) + .then(() => checkLockCategories(videoID)) + .then(result => { + assert.strictEqual(result.length, 1); + assert.strictEqual(result[0].category, "poi_highlight"); + }); }); - it("Should not add lock of invalid type", (done) => { - const videoID = "add_invalid_type"; - client.post(endpoint, { + it("Should not add lock of invalid type", () => { + const videoID = genRandomValue("video","lockCategoriesHttp"); + const json = { videoID, - userID: lockVIPUser, + userID: lockUser.privID, categories: ["future_unused_invalid_type"], actionTypes: ["skip"] - }) - .then(res => { - assert.strictEqual(res.status, 200); - checkLockCategories(videoID) - .then(result => { - assert.strictEqual(result.length, 0); - }); - done(); - }) - .catch(err => done(err)); + }; + return statusTest("POST", json, 200) + .then(() => checkLockCategories(videoID)) + .then(result => assert.strictEqual(result.length, 0)); }); }); describe("DELETE lockCategories 403/400 tests", () => { - it(" Should return 400 for no data", (done) => { - client.delete(endpoint, {}) - .then(res => { - assert.strictEqual(res.status, 400); - done(); - }) - .catch(err => done(err)); - }); + it("Should return 400 for no data", () => statusTest("DELETE", {}, 400)); + it("Should return 400 for no data", () => statusTest("POST", {}, 400)); - it("Should return 400 for no categories", (done) => { + it("Should return 400 for no categories", () => { const json: any = { videoID: "test", userID: "test", categories: [], }; - client.delete(endpoint, json) - .then(res => { - assert.strictEqual(res.status, 400); - done(); - }) - .catch(err => done(err)); + return statusTest("DELETE", json, 400); }); - it("Should return 400 for no userID", (done) => { + it("Should return 400 for no userID", () => { const json: any = { videoID: "test", userID: null, categories: ["sponsor"], }; - - client.post(endpoint, json) - .then(res => { - assert.strictEqual(res.status, 400); - done(); - }) - .catch(err => done(err)); + return statusTest("POST", json, 400); }); - it("Should return 400 for no videoID", (done) => { + it("Should return 400 for no videoID", () => { const json: any = { videoID: null, userID: "test", categories: ["sponsor"], }; - - client.post(endpoint, json) - .then(res => { - assert.strictEqual(res.status, 400); - done(); - }) - .catch(err => done(err)); + return statusTest("POST", json, 400); }); - it("Should return 400 for invalid category array", (done) => { + it("Should return 400 for invalid category array", () => { const json = { videoID: "test", userID: "test", categories: {}, }; - - client.post(endpoint, json) - .then(res => { - assert.strictEqual(res.status, 400); - done(); - }) - .catch(err => done(err)); - }); - - it("Should return 400 for bad format categories", (done) => { - const json = { - videoID: "test", - userID: "test", - categories: "sponsor", - }; - - client.post(endpoint, json) - .then(res => { - assert.strictEqual(res.status, 400); - done(); - }) - .catch(err => done(err)); - }); - - it("Should return 403 if user is not VIP", (done) => { - const json = { - videoID: "test", - userID: "test", - categories: [ - "sponsor", - ], - }; - - client.post(endpoint, json) - .then(res => { - assert.strictEqual(res.status, 403); - done(); - }) - .catch(err => done(err)); + return statusTest("POST", json, 400); }); }); describe("manual DELETE/POST lockCategories 400 tests", () => { - it("DELETE Should return 400 for no data", (done) => { - client.delete(endpoint, { data: {} }) - .then(res => { - assert.strictEqual(res.status, 400); - done(); - }) - .catch(err => done(err)); - }); - it("POST Should return 400 for no data", (done) => { - client.post(endpoint, {}) - .then(res => { - assert.strictEqual(res.status, 400); - done(); - }) - .catch(err => done(err)); - }); - it("DELETE Should return 400 for bad format categories", (done) => { - const data = goodResponse(); - data.categories = "sponsor"; - client.delete(endpoint, { data }) - .then(res => { - assert.strictEqual(res.status, 400); - done(); - }) - .catch(err => done(err)); - }); - it("POST Should return 400 for bad format categories", (done) => { - const data = goodResponse(); - data.categories = "sponsor"; - client.post(endpoint, data) - .then(res => { - assert.strictEqual(res.status, 400); - done(); - }) - .catch(err => done(err)); - }); - it("DELETE Should return 403 if user is not VIP", (done) => { - const data = goodResponse(); - client.delete(endpoint, { data }) - .then(res => { - assert.strictEqual(res.status, 403); - done(); - }) - .catch(err => done(err)); - }); - it("POST Should return 403 if user is not VIP", (done) => { - const data = goodResponse(); - client.post(endpoint, data) - .then(res => { - assert.strictEqual(res.status, 403); - done(); - }) - .catch(err => done(err)); - }); + it("DELETE Should return 400 for no data", () => statusTest("DELETE", {}, 400)); + it("POST Should return 400 for no data", () => statusTest("POST", {}, 400)); + + it("DELETE Should return 400 for bad format categories", () => errTest("DELETE", { categories: "sponsor" })); + it("POST Should return 400 for bad format categories", () => errTest("POST", { categories: "sponsor" })); + + it("DELETE Should return 403 if user is not VIP", () => statusTest("DELETE", goodResponse(), 403)); + it("POST Should return 403 if user is not VIP", () => statusTest("POST", goodResponse(), 403)); }); describe("array of DELETE/POST lockCategories 400 tests", () => { for (const key of [ "videoID", "userID", "categories" ]) { for (const method of ["DELETE", "POST"]) { - it(`${method} - Should return 400 for invalid ${key}`, (done) => { - const data = goodResponse(); - data[key] = null; - client(endpoint, { data, method }) - .then(res => { - assert.strictEqual(res.status, 400); - done(); - }) - .catch(err => done(err)); - }); + it(`${method} - Should return 400 for invalid ${key}`, () => + errTest(method, { [key]: null }) + ); } } }); \ No newline at end of file diff --git a/test/cases/postClearCache.ts b/test/cases/postClearCache.ts index 671a9e45..309533f4 100644 --- a/test/cases/postClearCache.ts +++ b/test/cases/postClearCache.ts @@ -1,62 +1,46 @@ import { db } from "../../src/databases/databases"; -import { getHash } from "../../src/utils/getHash"; import assert from "assert"; import { client } from "../utils/httpClient"; +import { genUsers, User } from "../utils/genUser"; +import { insertSegment, insertVip } from "../utils/queryGen"; -const VIPUser = "clearCacheVIP"; -const regularUser = "regular-user"; const endpoint = "/api/clearCache"; -const postClearCache = (userID: string, videoID: string) => client({ method: "post", url: endpoint, params: { userID, videoID } }); +const postClearCache = (user: User, videoID: string) => client({ method: "post", url: endpoint, params: { userID: user.privID, videoID } }); + +const cases = [ + "vip", + "normal", +]; +const users = genUsers("postClearCache", cases); describe("postClearCache", () => { before(async () => { - await db.prepare("run", `INSERT INTO "vipUsers" ("userID") VALUES ('${getHash(VIPUser)}')`); - const startOfQuery = 'INSERT INTO "sponsorTimes" ("videoID", "startTime", "endTime", "votes", "UUID", "userID", "timeSubmitted", "views", "category", "shadowHidden") VALUES'; - await db.prepare("run", `${startOfQuery}('clear-test', 0, 1, 2, 'clear-uuid', 'testman', 0, 50, 'sponsor', 0)`); + await insertVip(db, users["vip"].pubID); + await insertSegment(db, { videoID: "clear-test" }); }); - it("Should be able to clear cache for existing video", (done) => { - postClearCache(VIPUser, "clear-test") - .then(res => { - assert.strictEqual(res.status, 200); - done(); - }) - .catch(err => done(err)); - }); + it("Should be able to clear cache for existing video", () => + postClearCache(users["vip"], "clear-test") + .then(res => assert.strictEqual(res.status, 200)) + ); - it("Should be able to clear cache for nonexistent video", (done) => { - postClearCache(VIPUser, "dne-video") - .then(res => { - assert.strictEqual(res.status, 200); - done(); - }) - .catch(err => done(err)); - }); + it("Should be able to clear cache for nonexistent video", () => + postClearCache(users["vip"], "dne-video") + .then(res => assert.strictEqual(res.status, 200)) + ); - it("Should get 403 as non-vip", (done) => { - postClearCache(regularUser, "clear-test") - .then(res => { - assert.strictEqual(res.status, 403); - done(); - }) - .catch(err => done(err)); - }); + it("Should get 403 as non-vip", () => + postClearCache(users["normal"], "clear-test") + .then(res => assert.strictEqual(res.status, 403)) + ); - it("Should give 400 with missing videoID", (done) => { - client.post(endpoint, { params: { userID: VIPUser } }) - .then(res => { - assert.strictEqual(res.status, 400); - done(); - }) - .catch(err => done(err)); - }); + it("Should give 400 with missing videoID", () => + client.post(endpoint, { params: { userID: users["vip"].privID } }) + .then(res => assert.strictEqual(res.status, 400)) + ); - it("Should give 400 with missing userID", (done) => { + it("Should give 400 with missing userID", () => client.post(endpoint, { params: { videoID: "clear-test" } }) - .then(res => { - assert.strictEqual(res.status, 400); - done(); - }) - .catch(err => done(err)); - }); + .then(res => assert.strictEqual(res.status, 400)) + ); }); diff --git a/test/cases/redisTest.ts b/test/cases/redisTest.ts index ba1dd0ca..5288c738 100644 --- a/test/cases/redisTest.ts +++ b/test/cases/redisTest.ts @@ -9,17 +9,20 @@ const randKey2 = genRandom(16); const randKey3 = genRandom(); const randValue3 = genRandom(); +const redisGetCheck = (key: string, expected: string | null, done: Mocha.Done): Promise => + redis.get(key) + .then(res => { + assert.strictEqual(res, expected); + done(); + }).catch(err => done(err)); + describe("redis test", function() { before(async function() { if (!config.redis?.enabled) this.skip(); await redis.set(randKey1, randValue1); }); it("Should get stored value", (done) => { - redis.get(randKey1) - .then(res => { - assert.strictEqual(res, randValue1); - done(); - }).catch(err => done(err)); + redisGetCheck(randKey1, randValue1, done); }); it("Should not be able to get not stored value", (done) => { redis.get(randKey2) @@ -30,23 +33,13 @@ describe("redis test", function() { }); it("Should be able to delete stored value", (done) => { redis.del(randKey1) - .then(() => { - redis.get(randKey1) - .then(res => { - assert.strictEqual(res, null); - done(); - }).catch(err => done(err)); - }).catch(err => done(err)); + .catch(err => done(err)) + .then(() => redisGetCheck(randKey1, null, done)); }); it("Should be able to set expiring value", (done) => { redis.setEx(randKey3, 8400, randValue3) - .then(() => { - redis.get(randKey3) - .then(res => { - assert.strictEqual(res, randValue3); - done(); - }).catch(err => done(err)); - }).catch(err => done(err)); + .catch(err => done(err)) + .then(() => redisGetCheck(randKey3, randValue3, done)); }); it("Should continue when undefined value is fetched", (done) => { const undefkey = `undefined.${genRandom()}`; diff --git a/test/cases/reputation.ts b/test/cases/reputation.ts index a345fc39..653484da 100644 --- a/test/cases/reputation.ts +++ b/test/cases/reputation.ts @@ -1,31 +1,24 @@ import assert from "assert"; import { db } from "../../src/databases/databases"; -import { UserID } from "../../src/types/user.model"; -import { getHash } from "../../src/utils/getHash"; import { getReputation, calculateReputationFromMetrics } from "../../src/utils/reputation"; +import { genUsers } from "../utils/genUser"; describe("reputation", () => { - // constants - const userIDLowSubmissions = "reputation-lowsubmissions" as UserID; - const userHashLowSubmissions = getHash(userIDLowSubmissions); - const userIDHighDownvotes = "reputation-highdownvotes" as UserID; - const userHashHighDownvotes = getHash(userIDHighDownvotes); - const userIDLowNonSelfDownvotes = "reputation-lownonselfdownvotes" as UserID; - const userHashLowNonSelfDownvotes = getHash(userIDLowNonSelfDownvotes); - const userIDHighNonSelfDownvotes = "reputation-highnonselfdownvotes" as UserID; - const userHashHighNonSelfDownvotes = getHash(userIDHighNonSelfDownvotes); - const userIDNewSubmissions = "reputation-newsubmissions" as UserID; - const userHashNewSubmissions = getHash(userIDNewSubmissions); - const userIDLowSum = "reputation-lowsum" as UserID; - const userHashLowSum = getHash(userIDLowSum); - const userIDHighRepBeforeManualVote = "reputation-oldhighrep" as UserID; - const userHashHighRepBeforeManualVote = getHash(userIDHighRepBeforeManualVote); - const userIDHighRep = "reputation-highrep" as UserID; - const userHashHighRep = getHash(userIDHighRep); - const userIDHighRepAndLocked = "reputation-highlockedrep" as UserID; - const userHashHighAndLocked = getHash(userIDHighRepAndLocked); - const userIDHaveMostUpvotedInLockedVideo = "reputation-mostupvotedaslocked" as UserID; - const userHashHaveMostUpvotedInLockedVideo = getHash(userIDHaveMostUpvotedInLockedVideo); + // user definitions + const cases = [ + "locking-vip", + "low-submissions", + "high-downvotes", + "low-non-self-downvotes", + "high-non-self-downvotes", + "new-submissions", + "low-sum", + "high-rep-before-manual-vote", + "high-rep", + "high-rep-locked", + "have-most-upvoted-in-locked-video" + ]; + const users = genUsers("reputation", cases); before(async function() { this.timeout(5000); // this preparation takes longer then usual @@ -33,113 +26,113 @@ describe("reputation", () => { const videoID2 = "reputation-videoID-2"; const sponsorTimesInsertQuery = 'INSERT INTO "sponsorTimes" ("videoID", "startTime", "endTime", "votes", "locked", "UUID", "userID", "timeSubmitted", "views", "category", "hidden", "shadowHidden") VALUES(?,?,?,?,?,?,?,?,?,?,?,?)'; - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-0-uuid-0", userHashLowSubmissions, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-0-uuid-1", userHashLowSubmissions, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 100, 0, "reputation-0-uuid-2", userHashLowSubmissions, 1606240000000, 50, "sponsor", 0, 0]); - - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-1-uuid-0", userHashHighDownvotes, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, -2, 0, "reputation-1-uuid-1", userHashHighDownvotes, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, -2, 0, "reputation-1-uuid-2", userHashHighDownvotes, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, -2, 0, "reputation-1-uuid-3", userHashHighDownvotes, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, -2, 0, "reputation-1-uuid-4", userHashHighDownvotes, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, -1, 0, "reputation-1-uuid-5", userHashHighDownvotes, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-1-uuid-6", userHashHighDownvotes, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-1-uuid-7", userHashHighDownvotes, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-0-uuid-0", users["low-submissions"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-0-uuid-1", users["low-submissions"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 100, 0, "reputation-0-uuid-2", users["low-submissions"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-1-uuid-0", users["high-downvotes"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, -2, 0, "reputation-1-uuid-1", users["high-downvotes"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, -2, 0, "reputation-1-uuid-2", users["high-downvotes"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, -2, 0, "reputation-1-uuid-3", users["high-downvotes"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, -2, 0, "reputation-1-uuid-4", users["high-downvotes"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, -1, 0, "reputation-1-uuid-5", users["high-downvotes"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-1-uuid-6", users["high-downvotes"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-1-uuid-7", users["high-downvotes"].pubID, 1606240000000, 50, "sponsor", 0, 0]); // First video is considered a normal downvote, second is considered a self-downvote (ie. they didn't resubmit to fix their downvote) - await db.prepare("run", sponsorTimesInsertQuery, [`${videoID}A`, 1, 11, 2, 0, "reputation-1-1-uuid-0", userHashLowNonSelfDownvotes, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [`${videoID}A`, 1, 11, 2, 0, "reputation-1-1-uuid-0", users["low-non-self-downvotes"].pubID, 1606240000000, 50, "sponsor", 0, 0]); // Different category, same video - await db.prepare("run", sponsorTimesInsertQuery, [`${videoID}A`, 1, 11, -2, 0, "reputation-1-1-uuid-1", userHashLowNonSelfDownvotes, 1606240000000, 50, "intro", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-1-1-uuid-2", userHashLowNonSelfDownvotes, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-1-1-uuid-3", userHashLowNonSelfDownvotes, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-1-1-uuid-4", userHashLowNonSelfDownvotes, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, -1, 0, "reputation-1-1-uuid-5", userHashLowNonSelfDownvotes, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-1-1-uuid-6", userHashLowNonSelfDownvotes, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-1-1-uuid-7", userHashLowNonSelfDownvotes, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [`${videoID}A`, 1, 11, -2, 0, "reputation-1-1-uuid-1", users["low-non-self-downvotes"].pubID, 1606240000000, 50, "intro", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-1-1-uuid-2", users["low-non-self-downvotes"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-1-1-uuid-3", users["low-non-self-downvotes"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-1-1-uuid-4", users["low-non-self-downvotes"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, -1, 0, "reputation-1-1-uuid-5", users["low-non-self-downvotes"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-1-1-uuid-6", users["low-non-self-downvotes"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-1-1-uuid-7", users["low-non-self-downvotes"].pubID, 1606240000000, 50, "sponsor", 0, 0]); // First videos is considered a normal downvote, last is considered a self-downvote (ie. they didn't resubmit to fix their downvote) - await db.prepare("run", sponsorTimesInsertQuery, [`${videoID}A`, 1, 11, 2, 0, "reputation-1-1-1-uuid-0", userHashHighNonSelfDownvotes, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [`${videoID}A`, 1, 11, 2, 0, "reputation-1-1-1-uuid-0", users["high-non-self-downvotes"].pubID, 1606240000000, 50, "sponsor", 0, 0]); // Different category, same video - await db.prepare("run", sponsorTimesInsertQuery, [`${videoID}A`, 1, 11, -2, 0, "reputation-1-1-1-uuid-1", userHashHighNonSelfDownvotes, 1606240000000, 50, "intro", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [`${videoID}B`, 1, 11, -2, 0, "reputation-1-1-1-uuid-1-b", userHashHighNonSelfDownvotes, 1606240000000, 50, "intro", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [`${videoID}C`, 1, 11, -2, 0, "reputation-1-1-1-uuid-1-c", userHashHighNonSelfDownvotes, 1606240000000, 50, "intro", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-1-1-1-uuid-2", userHashHighNonSelfDownvotes, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-1-1-1-uuid-3", userHashHighNonSelfDownvotes, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-1-1-1-uuid-4", userHashHighNonSelfDownvotes, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, -1, 0, "reputation-1-1-1-uuid-5", userHashHighNonSelfDownvotes, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-1-1-1-uuid-6", userHashHighNonSelfDownvotes, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-1-1-1-uuid-7", userHashHighNonSelfDownvotes, 1606240000000, 50, "sponsor", 0, 0]); - - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-2-uuid-0", userHashNewSubmissions, Date.now(), 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-2-uuid-1", userHashNewSubmissions, Date.now(), 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-2-uuid-2", userHashNewSubmissions, Date.now(), 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-2-uuid-3", userHashNewSubmissions, Date.now(), 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-2-uuid-4", userHashNewSubmissions, Date.now(), 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, -1, 0, "reputation-2-uuid-5", userHashNewSubmissions, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-2-uuid-6", userHashNewSubmissions, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-2-uuid-7", userHashNewSubmissions, 1606240000000, 50, "sponsor", 0, 0]); - - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-3-uuid-0", userHashLowSum, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 1, 0, "reputation-3-uuid-1", userHashLowSum, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-3-uuid-2", userHashLowSum, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-3-uuid-3", userHashLowSum, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 1, 0, "reputation-3-uuid-4", userHashLowSum, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, -1, 0, "reputation-3-uuid-5", userHashLowSum, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-3-uuid-6", userHashLowSum, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-3-uuid-7", userHashLowSum, 1606240000000, 50, "sponsor", 0, 0]); - - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-4-uuid-0", userHashHighRepBeforeManualVote, 0, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-4-uuid-1", userHashHighRepBeforeManualVote, 0, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-4-uuid-2", userHashHighRepBeforeManualVote, 0, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-4-uuid-3", userHashHighRepBeforeManualVote, 0, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-4-uuid-4", userHashHighRepBeforeManualVote, 0, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, -1, 0, "reputation-4-uuid-5", userHashHighRepBeforeManualVote, 0, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-4-uuid-6", userHashHighRepBeforeManualVote, 0, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-4-uuid-7", userHashHighRepBeforeManualVote, 0, 50, "sponsor", 0, 0]); - - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-5-uuid-0", userHashHighRep, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-5-uuid-1", userHashHighRep, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-5-uuid-2", userHashHighRep, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-5-uuid-3", userHashHighRep, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-5-uuid-4", userHashHighRep, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, -1, 0, "reputation-5-uuid-5", userHashHighRep, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-5-uuid-6", userHashHighRep, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-5-uuid-7", userHashHighRep, 1606240000000, 50, "sponsor", 0, 0]); - - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 1, "reputation-6-uuid-0", userHashHighAndLocked, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 1, "reputation-6-uuid-1", userHashHighAndLocked, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 1, "reputation-6-uuid-2", userHashHighAndLocked, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 1, "reputation-6-uuid-3", userHashHighAndLocked, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-6-uuid-4", userHashHighAndLocked, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, -1, 0, "reputation-6-uuid-5", userHashHighAndLocked, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-6-uuid-6", userHashHighAndLocked, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-6-uuid-7", userHashHighAndLocked, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [`${videoID}A`, 1, 11, -2, 0, "reputation-1-1-1-uuid-1", users["high-non-self-downvotes"].pubID, 1606240000000, 50, "intro", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [`${videoID}B`, 1, 11, -2, 0, "reputation-1-1-1-uuid-1-b", users["high-non-self-downvotes"].pubID, 1606240000000, 50, "intro", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [`${videoID}C`, 1, 11, -2, 0, "reputation-1-1-1-uuid-1-c", users["high-non-self-downvotes"].pubID, 1606240000000, 50, "intro", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-1-1-1-uuid-2", users["high-non-self-downvotes"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-1-1-1-uuid-3", users["high-non-self-downvotes"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-1-1-1-uuid-4", users["high-non-self-downvotes"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, -1, 0, "reputation-1-1-1-uuid-5", users["high-non-self-downvotes"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-1-1-1-uuid-6", users["high-non-self-downvotes"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-1-1-1-uuid-7", users["high-non-self-downvotes"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-2-uuid-0", users["new-submissions"].pubID, Date.now(), 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-2-uuid-1", users["new-submissions"].pubID, Date.now(), 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-2-uuid-2", users["new-submissions"].pubID, Date.now(), 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-2-uuid-3", users["new-submissions"].pubID, Date.now(), 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-2-uuid-4", users["new-submissions"].pubID, Date.now(), 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, -1, 0, "reputation-2-uuid-5", users["new-submissions"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-2-uuid-6", users["new-submissions"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-2-uuid-7", users["new-submissions"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-3-uuid-0", users["low-sum"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 1, 0, "reputation-3-uuid-1", users["low-sum"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-3-uuid-2", users["low-sum"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-3-uuid-3", users["low-sum"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 1, 0, "reputation-3-uuid-4", users["low-sum"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, -1, 0, "reputation-3-uuid-5", users["low-sum"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-3-uuid-6", users["low-sum"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-3-uuid-7", users["low-sum"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-4-uuid-0", users["high-rep-before-manual-vote"].pubID, 0, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-4-uuid-1", users["high-rep-before-manual-vote"].pubID, 0, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-4-uuid-2", users["high-rep-before-manual-vote"].pubID, 0, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-4-uuid-3", users["high-rep-before-manual-vote"].pubID, 0, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-4-uuid-4", users["high-rep-before-manual-vote"].pubID, 0, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, -1, 0, "reputation-4-uuid-5", users["high-rep-before-manual-vote"].pubID, 0, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-4-uuid-6", users["high-rep-before-manual-vote"].pubID, 0, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-4-uuid-7", users["high-rep-before-manual-vote"].pubID, 0, 50, "sponsor", 0, 0]); + + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-5-uuid-0", users["high-rep"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-5-uuid-1", users["high-rep"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-5-uuid-2", users["high-rep"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-5-uuid-3", users["high-rep"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-5-uuid-4", users["high-rep"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, -1, 0, "reputation-5-uuid-5", users["high-rep"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-5-uuid-6", users["high-rep"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-5-uuid-7", users["high-rep"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 1, "reputation-6-uuid-0", users["high-rep-locked"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 1, "reputation-6-uuid-1", users["high-rep-locked"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 1, "reputation-6-uuid-2", users["high-rep-locked"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 1, "reputation-6-uuid-3", users["high-rep-locked"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-6-uuid-4", users["high-rep-locked"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, -1, 0, "reputation-6-uuid-5", users["high-rep-locked"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-6-uuid-6", users["high-rep-locked"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-6-uuid-7", users["high-rep-locked"].pubID, 1606240000000, 50, "sponsor", 0, 0]); //Record has most upvoted - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 5, 0, "reputation-7-uuid-0", userHashHaveMostUpvotedInLockedVideo, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 101, 0, "reputation-7-uuid-1", userHashHaveMostUpvotedInLockedVideo, 1606240000000, 50, "intro", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID2, 1, 11, 5, 0, "reputation-7-uuid-8", userHashHaveMostUpvotedInLockedVideo, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID2, 1, 11, 0, 0, "reputation-7-uuid-9", userHashHaveMostUpvotedInLockedVideo, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 5, 0, "reputation-7-uuid-0", users["have-most-upvoted-in-locked-video"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 101, 0, "reputation-7-uuid-1", users["have-most-upvoted-in-locked-video"].pubID, 1606240000000, 50, "intro", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID2, 1, 11, 5, 0, "reputation-7-uuid-8", users["have-most-upvoted-in-locked-video"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID2, 1, 11, 0, 0, "reputation-7-uuid-9", users["have-most-upvoted-in-locked-video"].pubID, 1606240000000, 50, "sponsor", 0, 0]); // other segments - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-7-uuid-2", userHashHaveMostUpvotedInLockedVideo, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-7-uuid-3", userHashHaveMostUpvotedInLockedVideo, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-7-uuid-4", userHashHaveMostUpvotedInLockedVideo, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, -1, 0, "reputation-7-uuid-5", userHashHaveMostUpvotedInLockedVideo, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-7-uuid-6", userHashHaveMostUpvotedInLockedVideo, 1606240000000, 50, "sponsor", 0, 0]); - await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-7-uuid-7", userHashHaveMostUpvotedInLockedVideo, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-7-uuid-2", users["have-most-upvoted-in-locked-video"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-7-uuid-3", users["have-most-upvoted-in-locked-video"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 2, 0, "reputation-7-uuid-4", users["have-most-upvoted-in-locked-video"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, -1, 0, "reputation-7-uuid-5", users["have-most-upvoted-in-locked-video"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-7-uuid-6", users["have-most-upvoted-in-locked-video"].pubID, 1606240000000, 50, "sponsor", 0, 0]); + await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-7-uuid-7", users["have-most-upvoted-in-locked-video"].pubID, 1606240000000, 50, "sponsor", 0, 0]); // lock video const insertVipUserQuery = 'INSERT INTO "vipUsers" ("userID") VALUES (?)'; - await db.prepare("run", insertVipUserQuery, [getHash("VIPUser-getLockCategories")]); + await db.prepare("run", insertVipUserQuery, [users["locking-vip"].pubID]); const insertLockCategoryQuery = 'INSERT INTO "lockCategories" ("userID", "videoID", "category") VALUES (?, ?, ?)'; - await db.prepare("run", insertLockCategoryQuery, [getHash("VIPUser-getLockCategories"), videoID, "sponsor"]); - await db.prepare("run", insertLockCategoryQuery, [getHash("VIPUser-getLockCategories"), videoID, "intro"]); - await db.prepare("run", insertLockCategoryQuery, [getHash("VIPUser-getLockCategories"), videoID2, "sponsor"]); + await db.prepare("run", insertLockCategoryQuery, [users["locking-vip"].pubID, videoID, "sponsor"]); + await db.prepare("run", insertLockCategoryQuery, [users["locking-vip"].pubID, videoID, "intro"]); + await db.prepare("run", insertLockCategoryQuery, [users["locking-vip"].pubID, videoID2, "sponsor"]); }); it("user in grace period", async () => { - const data = await getReputation(getHash(userIDLowSubmissions)); + const data = await getReputation(users["low-submissions"].privID); assert.strictEqual(data, 0); }); @@ -154,7 +147,7 @@ describe("reputation", () => { oldUpvotedSubmissions: 1, mostUpvotedInLockedVideoSum: 0 }; - const data = await getReputation(getHash(userIDHighDownvotes)); + const data = await getReputation(users["high-downvotes"].pubID); assert.strictEqual(data, calculateReputationFromMetrics(metrics)); assert.strictEqual(data, -1.7500000000000002); }); @@ -170,26 +163,26 @@ describe("reputation", () => { oldUpvotedSubmissions: 1, mostUpvotedInLockedVideoSum: 0 }; - const data = await getReputation(userHashLowNonSelfDownvotes); + const data = await getReputation(users["low-non-self-downvotes"].pubID); assert.strictEqual(data, calculateReputationFromMetrics(metrics)); assert.strictEqual(data, 0); }); it("user with high non self downvote ratio", async () => { - const data = await getReputation(userHashHighNonSelfDownvotes); + const data = await getReputation(users["high-non-self-downvotes"].pubID); assert.strictEqual(data, -2.5); }); it("user with mostly new submissions", async () => { - assert.strictEqual(await getReputation(userHashNewSubmissions), 0); + assert.strictEqual(await getReputation(users["new-submissions"].pubID), 0); }); it("user with not enough vote sum", async () => { - assert.strictEqual(await getReputation(userHashLowSum), 0); + assert.strictEqual(await getReputation(users["low-sum"].pubID), 0); }); it("user with lots of old votes (before autovote was disabled) ", async () => { - assert.strictEqual(await getReputation(userHashHighRepBeforeManualVote), 0); + assert.strictEqual(await getReputation(users["high-rep-before-manual-vote"].pubID), 0); }); it("user with high reputation", async () => { @@ -203,7 +196,7 @@ describe("reputation", () => { oldUpvotedSubmissions: 5, mostUpvotedInLockedVideoSum: 0 }; - const data = await getReputation(userHashHighRep); + const data = await getReputation(users["high-rep"].pubID); assert.strictEqual(data, calculateReputationFromMetrics(metrics)); assert.strictEqual(data, 0.19310344827586207); }); @@ -219,7 +212,7 @@ describe("reputation", () => { oldUpvotedSubmissions: 5, mostUpvotedInLockedVideoSum: 4 }; - const data = await getReputation(userHashHighAndLocked); + const data = await getReputation(users["high-rep-locked"].pubID); assert.strictEqual(data, calculateReputationFromMetrics(metrics)); assert.strictEqual(data, 3.393103448275862); }); @@ -235,7 +228,7 @@ describe("reputation", () => { oldUpvotedSubmissions: 6, mostUpvotedInLockedVideoSum: 2 }; - const data = await getReputation(userHashHaveMostUpvotedInLockedVideo); + const data = await getReputation(users["have-most-upvoted-in-locked-video"].pubID); assert.strictEqual(data, calculateReputationFromMetrics(metrics)); assert.strictEqual(data, 6.158620689655172); }); diff --git a/test/cases/userCounter.ts b/test/cases/userCounter.ts index 1730d26e..7b456d5b 100644 --- a/test/cases/userCounter.ts +++ b/test/cases/userCounter.ts @@ -5,29 +5,23 @@ import { getHash } from "../../src/utils/getHash"; import { client } from "../utils/httpClient"; describe("userCounter", () => { - it("Should return 200", function (done) { + it("Should return 200", function () { if (!config.userCounterURL) this.skip(); // skip if no userCounterURL is set - axios.request({ + return axios.request({ method: "POST", baseURL: config.userCounterURL, url: "/api/v1/addIP", params: { hashedIP: getHash("127.0.0.1",1) } - }) - .then(res => { - assert.strictEqual(res.status, 200); - done(); - }) - .catch(err => done(err)); + }).then(res => assert.strictEqual(res.status, 200)); }); - it("Should not incremeent counter on OPTIONS", function (done) { + it("Should not incremeent counter on OPTIONS", function () { /* cannot spy test */ if (!config.userCounterURL) this.skip(); // skip if no userCounterURL is set //const spy = sinon.spy(UserCounter); - client({ method: "OPTIONS", url: "/api/status" }) + return client({ method: "OPTIONS", url: "/api/status" }) .then(() => client({ method: "GET", url: "/api/status" })); //assert.strictEqual(spy.callCount, 1); - done(); }); }); \ No newline at end of file diff --git a/test/cases/validateVideoIDs.ts b/test/cases/validateVideoIDs.ts index dc1c62dd..c5cf2756 100644 --- a/test/cases/validateVideoIDs.ts +++ b/test/cases/validateVideoIDs.ts @@ -106,20 +106,16 @@ describe("VideoID Validation - postSkipSegments", () => { done(); }); - it(`Should return 400 for invalid videoID`, (done) => { + it(`Should return 400 for invalid videoID`, () => postSkipSegments("123456").then(res => { assert.strictEqual(res.status, 400); assert.strictEqual(res.data, expectedError); - done(); }) - .catch(err => done(err)); - }); + ); - it(`Should return 200 for valid videoID`, (done) => { - postSkipSegments("dQw4w9WgXcQ").then(res => { - assert.strictEqual(res.status, 200); - done(); - }) - .catch(err => done(err)); - }); + it(`Should return 200 for valid videoID`, () => + postSkipSegments("dQw4w9WgXcQ").then(res => + assert.strictEqual(res.status, 200) + ) + ); }); \ No newline at end of file diff --git a/test/utils/genUser.ts b/test/utils/genUser.ts new file mode 100644 index 00000000..a4e34043 --- /dev/null +++ b/test/utils/genUser.ts @@ -0,0 +1,43 @@ +import { genRandom } from "./getRandom"; +import { UserID, HashedUserID } from "../../src/types/user.model"; +import { getHash } from "../../src/utils/getHash"; + +type info = Record + +export interface User { + privID: UserID, + pubID: HashedUserID + info: info +} +export type userArray = Record + +export interface UsernameUser extends User { + username: string +} +export type usernameUserArray = Record + +export const genUser = (fnname: string, testcase: string, info: info = {}): User => { + const privID = `${fnname}-${testcase}-${genRandom(2)}` as UserID; + const pubID = getHash(privID); + return { privID, pubID, info }; +}; + +export const genAnonUser = (info: info = {}): User => { + const privID = `user-${genRandom()}` as UserID; + const pubID = getHash(privID); + return { privID, pubID, info }; +}; + +export const genUsers = (fnname: string, testcase: string[]): userArray => { + const users: userArray = {}; + for (const tc of testcase) + users[tc] = genUser(fnname, tc); + return users; +}; + +export const genUsersUsername = (fnname: string, case_usernames: Map): usernameUserArray => { + const cases = Array.from(case_usernames.keys()); + const users = genUsers(fnname, cases); + case_usernames.forEach((username, tc) => (users[tc] as UsernameUser).username = username); + return users as usernameUserArray; +}; \ No newline at end of file diff --git a/test/utils/getRandom.ts b/test/utils/getRandom.ts index 6ac64373..b08a7f8a 100644 --- a/test/utils/getRandom.ts +++ b/test/utils/getRandom.ts @@ -1,3 +1,10 @@ import crypto from "crypto"; -export const genRandom = (bytes=8) => crypto.pseudoRandomBytes(bytes).toString("hex"); +export const genRandom = (bytes=8): string => crypto.pseudoRandomBytes(bytes).toString("hex"); + +export const genRandomValue = (prefix: string, identifier: string, bytes=8): string => `${prefix}-${identifier}-${genRandom(bytes)}`; +export const multiGenRandomValue = (prefix: string, identifier: string, count: number, bytes=8): string[] => { + const arr: string[] = []; + for (let i = 0; i < count; i++) arr.push(genRandomValue(prefix, identifier, bytes)); + return arr; +}; \ No newline at end of file diff --git a/test/utils/queryGen.ts b/test/utils/queryGen.ts new file mode 100644 index 00000000..a820c2be --- /dev/null +++ b/test/utils/queryGen.ts @@ -0,0 +1,94 @@ +import { IDatabase } from "../../src/databases/IDatabase"; +import { HashedUserID } from "../../src/types/user.model"; +import { User, userArray, usernameUserArray } from "./genUser"; +import { Feature } from "../../src/types/user.model"; +import { ActionType, Category, Service, VideoIDHash } from "../../src/types/segments.model"; +import { genRandomValue } from "./getRandom"; +import { getHash } from "../../src/utils/getHash"; + +// segments +export { insertSegment } from "./segmentQueryGen"; + +// vip +export const insertVip = async (db: IDatabase, userID: HashedUserID) => { + const query = 'INSERT INTO "vipUsers" ("userID") VALUES (?)'; + await db.prepare("run", query, [userID]); +}; +export const insertVipUser = async (db: IDatabase, user: User) => { + await insertVip(db, user.pubID); +}; +export const insertVipBulk = async (db: IDatabase, users: userArray) => { + for (const user of Object.values(users)) + await insertVip(db, user.pubID); +}; + +// userFeatures +export const grantFeature = async (db: IDatabase, target: HashedUserID, feature: Feature, issuer = "default-issuer", time = 0) => { + const query = 'INSERT INTO "userFeatures" ("userID", "feature", "issuerUserID", "timeSubmitted") VALUES(?, ?, ?, ?)'; + await db.prepare("run", query, [target, feature, issuer, time]); +}; +export const bulkGrantFeature = async (db: IDatabase, users: userArray, feature: Feature, issuer: User, time = 0) => { + for (const user of Object.values(users)) + await grantFeature(db, user.pubID, feature, issuer.pubID, time); +}; + +// usernames +export const insertUsername = async (db: IDatabase, userID: HashedUserID, userName: string, locked = false) => { + const query = 'INSERT INTO "userNames" ("userID", "userName", "locked") VALUES(?, ?, ?)'; + const lockedValue = Number(locked); + await db.prepare("run", query, [userID, userName, lockedValue]); +}; +export const insertUsernameBulk = async (db: IDatabase, users: usernameUserArray) => { + for (const user of Object.values(users)) + await insertUsername(db, user.pubID, user.username, false); +}; + +// videoInfo +export const insertVideoInfo = async (db: IDatabase, videoID: string, channelID: string, title = "", published = 0) => { + const query = 'INSERT INTO "videoInfo" ("videoID", "channelID", "title", "published") VALUES(?, ?, ?, ?)'; + await db.prepare("run", query, [videoID, channelID, title, published]); +}; + +interface lockParams { + videoID?: string, + userID?: HashedUserID | "", + actionType?: ActionType | string, + category?: Category | string, + hashedVideoID?: VideoIDHash | "", + reason?: string, + service?: Service | string +} + +export const insertLock = async(db: IDatabase, overrides: lockParams = {}) => { + const query = 'INSERT INTO "lockCategories" ("videoID", "userID", "actionType", "category", "hashedVideoID", "reason", "service") VALUES (?, ?, ?, ?, ?, ?, ?)'; + const identifier = "lock"; + const defaults = { + videoID: genRandomValue("video", identifier), userID: genRandomValue("user", identifier), + actionType: "skip", category: "sponsor", hashedVideoID: "", reason: "", service: Service.YouTube + }; + const params = { ...defaults, ...overrides }; + params.hashedVideoID = getHash(params.videoID); + await db.prepare("run", query, Object.values(params)); +}; + +// warning +type warningParams = { + userID?: HashedUserID, + issueTime?: number, + issuerUserID?: HashedUserID, + enabled?: boolean | number, + reason?: string, + type?: number +} +export const insertWarning = async (db: IDatabase, userID: HashedUserID, overrides: warningParams = {}) => { + const defaults = { userID, issueTime: 0, issuerUserID: "vip-user", enabled: true, reason: "default-warn-reason", type: 0 }; + const params = { ...defaults, ...overrides }; + params.enabled = Number(params.enabled); + const query = 'INSERT INTO "warnings" ("userID", "issueTime", "issuerUserID", "enabled", "reason", "type") VALUES(?, ?, ?, ?, ?, ?)'; + await db.prepare("run", query, Object.values(params)); +}; +// ban +export const insertBan = async (db: IDatabase, userID: HashedUserID) => { + const query = 'INSERT INTO "shadowBannedUsers" ("userID") VALUES (?)'; + await db.prepare("run", query, [userID]); +}; diff --git a/test/utils/segmentQueryGen.ts b/test/utils/segmentQueryGen.ts new file mode 100644 index 00000000..ce6fb385 --- /dev/null +++ b/test/utils/segmentQueryGen.ts @@ -0,0 +1,132 @@ +import { IDatabase } from "../../src/databases/IDatabase"; +import { Service, VideoIDHash } from "../../src/types/segments.model"; +import { HashedUserID } from "../../src/types/user.model"; +import { genRandom, genRandomValue } from "./getRandom"; +import { getHash } from "../../src/utils/getHash"; + +interface baseParams { + videoID?: string + hashedVideoID?: VideoIDHash | "" + userID?: HashedUserID | "" + service?: Service + timeSubmitted?: number + UUID?: string +} + +// sponsorTimes +interface insertSegmentParams extends baseParams { + startTime?: number, + endTime?: number, + votes?: number, + locked?: boolean | number, + views?: number, + category?: string, + actionType?: string, + videoDuration?: number, + hidden?: boolean | number, + shadowHidden?: boolean | number, + description?: string +} +const defaultSegmentParams: insertSegmentParams = { + videoID: "", + startTime: 0, + endTime: 0, + votes: 0, + locked: false, + UUID: "", + userID: "", + timeSubmitted: 0, + views: 0, + category: "sponsor", + actionType: "skip", + service: Service.YouTube, + videoDuration: 0, + hidden: false, + shadowHidden: false, + hashedVideoID: "", + description: "" +}; + +const generateDefaults = (identifier: string) => ({ + videoID: `vid-${identifier}`, + hashedVideoID: getHash(`vid-${identifier}`), + userID: `user-${identifier}`, + UUID: genRandomValue("uuid", identifier, 2), +}); + +export const insertSegment = async(db: IDatabase, overrides: insertSegmentParams = {}, identifier?: string) => { + const query = 'INSERT INTO "sponsorTimes" ("videoID", "startTime", "endTime", "votes", "locked", "UUID", "userID", "timeSubmitted", "views", "category", "actionType", "service", "videoDuration", "hidden", "shadowHidden", "hashedVideoID", "description") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'; + // generate defaults + identifier = identifier ?? genRandom(); + const defaults = generateDefaults(identifier); + const params = { ...defaultSegmentParams, ...defaults, ...overrides }; + // convert bool to 0 | 1 + params.locked = Number(params.locked); + params.hidden = Number(params.hidden); + params.shadowHidden = Number(params.shadowHidden); + await db.prepare("run", query, Object.values(params)); +}; +export const insertChapter = async(db: IDatabase, description: string, params: insertSegmentParams = {}) => { + const overrides = { category: "chapter", actionType: "chapter", description, ...params }; + await insertSegment(db, overrides); +}; + +// titles +interface insertTitleParams extends baseParams { + title?: string, + original?: boolean | number, +} +const defaultTitleParams: insertTitleParams = { + videoID: "", + title: "", + original: false, + userID: "", + service: Service.YouTube, + hashedVideoID: "", + timeSubmitted: 0, + UUID: "", +}; +export const insertTitle = async (db: IDatabase, overrides: insertTitleParams = {}, identifier?: string) => { + const query = 'INSERT INTO "titles" ("videoID", "title", "original", "userID", "service", "hashedVideoID", "timeSubmitted", "UUID") VALUES (?, ?, ?, ?, ?, ?, ?, ?)'; + // generate defaults + identifier = identifier ?? genRandom(); + const defaults = generateDefaults(identifier); + const params = { ...defaultTitleParams, ...defaults, ...overrides }; + params.title = genRandomValue("title", identifier); + // convert bool to 0 | 1 + params.original = Number(params.original); + await db.prepare("run", query, Object.values(params)); +}; +export const insertTitleVote = async (db: IDatabase, UUID: string, votes: number, locked = false, shadowHidden = false, verification = false) => { + const query = 'INSERT INTO "titleVotes" ("UUID", "votes", "locked", "shadowHidden", "verification") VALUES (?, ?, ?, ?, ?)'; + const params = [UUID, votes, Number(locked), Number(shadowHidden), Number(verification)]; + await db.prepare("run", query, params); +}; + +interface insertThumbnailParams extends baseParams { + original?: number, +} +const defaultThumbParams = { + videoID: "", + original: 0, + userID: "", + service: Service.YouTube, + hashedVideoID: "", + timeSubmitted: 0, + UUID: "", +}; +export const insertThumbnail = async (db: IDatabase, overrides: insertThumbnailParams = {}, identifier?: string) => { + const query = 'INSERT INTO "thumbnails" ("videoID", "original", "userID", "service", "hashedVideoID", "timeSubmitted", "UUID") VALUES (?, ?, ?, ?, ?, ?, ?)'; + // generate defaults + identifier = identifier ?? genRandom(); + const defaults = generateDefaults(identifier); + const params = { ...defaultThumbParams, ...defaults, ...overrides }; + // convert bool to 0 | 1 + await db.prepare("run", query, Object.values(params)); +}; + +export const insertThumbnailVote = async (db: IDatabase, UUID: string, votes: number, locked = false, shadowHidden = false) => { + const query = 'INSERT INTO "thumbnailVotes" ("UUID", "votes", "locked", "shadowHidden") VALUES (?, ?, ?, ?)'; + const params = [UUID, votes, Number(locked), Number(shadowHidden)]; + await db.prepare("run", query, params); +}; \ No newline at end of file