mirror of
https://github.com/ajayyy/SponsorBlockServer.git
synced 2026-01-02 14:49:17 +03:00
Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into fullVideoLabels
This commit is contained in:
68
test/cases/addFeatures.ts
Normal file
68
test/cases/addFeatures.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import assert from "assert";
|
||||
import { db } from "../../src/databases/databases";
|
||||
import { Feature, HashedUserID } from "../../src/types/user.model";
|
||||
import { hasFeature } from "../../src/utils/features";
|
||||
import { getHash } from "../../src/utils/getHash";
|
||||
import { client } from "../utils/httpClient";
|
||||
|
||||
const endpoint = "/api/feature";
|
||||
|
||||
const postAddFeatures = (userID: string, adminUserID: string, feature: Feature, enabled: string) => client({
|
||||
method: "POST",
|
||||
url: endpoint,
|
||||
data: {
|
||||
userID,
|
||||
feature,
|
||||
enabled,
|
||||
adminUserID
|
||||
}
|
||||
});
|
||||
|
||||
const privateVipUserID = "VIPUser-addFeatures";
|
||||
const vipUserID = getHash(privateVipUserID);
|
||||
|
||||
const hashedUserID1 = "user1-addFeatures" as HashedUserID;
|
||||
const hashedUserID2 = "user2-addFeatures" as HashedUserID;
|
||||
const hashedUserID3 = "user3-addFeatures" as HashedUserID;
|
||||
|
||||
const validFeatures = [Feature.ChapterSubmitter];
|
||||
|
||||
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])
|
||||
]);
|
||||
});
|
||||
|
||||
it("can add features", async () => {
|
||||
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);
|
||||
}
|
||||
});
|
||||
|
||||
it("can remove features", async () => {
|
||||
const feature = Feature.ChapterSubmitter;
|
||||
|
||||
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);
|
||||
});
|
||||
});
|
||||
@@ -19,9 +19,9 @@ if (db instanceof Postgres) {
|
||||
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", "genreUrl")
|
||||
SELECT ?, ?, ?, ?, ?`, [
|
||||
chapterNamesVid1, chapterChannelID, "", 0, ""
|
||||
await db.prepare("run", `INSERT INTO "videoInfo" ("videoID", "channelID", "title", "published")
|
||||
SELECT ?, ?, ?, ?`, [
|
||||
chapterNamesVid1, chapterChannelID, "", 0
|
||||
]);
|
||||
});
|
||||
|
||||
|
||||
31
test/cases/getHashCache.ts
Normal file
31
test/cases/getHashCache.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { config } from "../../src/config";
|
||||
import { getHashCache } from "../../src/utils/getHashCache";
|
||||
import { shaHashKey } from "../../src/utils/redisKeys";
|
||||
import { getHash } from "../../src/utils/getHash";
|
||||
import redis from "../../src/utils/redis";
|
||||
import crypto from "crypto";
|
||||
import assert from "assert";
|
||||
import { setTimeout } from "timers/promises";
|
||||
|
||||
const genRandom = (bytes=8) => crypto.pseudoRandomBytes(bytes).toString("hex");
|
||||
|
||||
const rand1Hash = genRandom(24);
|
||||
const rand1Hash_Key = getHash(rand1Hash, 1);
|
||||
const rand1Hash_Result = getHash(rand1Hash);
|
||||
|
||||
describe("getHashCache test", function() {
|
||||
before(function() {
|
||||
if (!config.redis?.enabled) this.skip();
|
||||
});
|
||||
it("Should set hashKey and be able to retreive", (done) => {
|
||||
const redisKey = shaHashKey(rand1Hash_Key);
|
||||
getHashCache(rand1Hash)
|
||||
.then(() => setTimeout(50)) // add timeout for redis to complete async
|
||||
.then(() => redis.get(redisKey))
|
||||
.then(result => {
|
||||
assert.strictEqual(result, rand1Hash_Result);
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err === undefined ? "no set value" : err));
|
||||
}).timeout(5000);
|
||||
});
|
||||
@@ -31,7 +31,7 @@ describe("getLockReason", () => {
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
const deleteUserNameQuery = 'DELETE FROM "userNames" WHERE "userID" = ? AND "userName" = ? LIMIT 1';
|
||||
const deleteUserNameQuery = 'DELETE FROM "userNames" WHERE "userID" = ? AND "userName" = ?';
|
||||
await db.prepare("run", deleteUserNameQuery, [vipUserID1, vipUserName1]);
|
||||
await db.prepare("run", deleteUserNameQuery, [vipUserID2, vipUserName2]);
|
||||
});
|
||||
|
||||
@@ -23,6 +23,8 @@ describe("getSkipSegments", () => {
|
||||
await db.prepare("run", query, ["requiredSegmentVid", 60, 70, -2, 0, "requiredSegmentVid2", "testman", 0, 50, "sponsor", "skip", "YouTube", 0, 0, 0, ""]);
|
||||
await db.prepare("run", query, ["requiredSegmentVid", 80, 90, -2, 0, "requiredSegmentVid3", "testman", 0, 50, "sponsor", "skip", "YouTube", 0, 0, 0, ""]);
|
||||
await db.prepare("run", query, ["requiredSegmentVid", 80, 90, 2, 0, "requiredSegmentVid4", "testman", 0, 50, "sponsor", "skip", "YouTube", 0, 0, 0, ""]);
|
||||
await db.prepare("run", query, ["requiredSegmentVid", 60, 70, 0, 0, "requiredSegmentVid-hidden", "testman", 0, 50, "sponsor", "skip", "YouTube", 0, 1, 0, ""]);
|
||||
await db.prepare("run", query, ["requiredSegmentVid", 80, 90, 0, 0, "requiredSegmentVid-shadowhidden", "testman", 0, 50, "sponsor", "skip", "YouTube", 0, 0, 1, ""]);
|
||||
await db.prepare("run", query, ["chapterVid", 60, 80, 2, 0, "chapterVid-1", "testman", 0, 50, "chapter", "chapter", "YouTube", 0, 0, 0, "Chapter 1"]);
|
||||
await db.prepare("run", query, ["chapterVid", 70, 75, 2, 0, "chapterVid-2", "testman", 0, 50, "chapter", "chapter", "YouTube", 0, 0, 0, "Chapter 2"]);
|
||||
await db.prepare("run", query, ["chapterVid", 71, 75, 2, 0, "chapterVid-3", "testman", 0, 50, "chapter", "chapter", "YouTube", 0, 0, 0, "Chapter 3"]);
|
||||
@@ -447,4 +449,42 @@ describe("getSkipSegments", () => {
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("Should be able to get hidden segments with requiredSegments", (done) => {
|
||||
const required3 = "requiredSegmentVid3";
|
||||
const requiredHidden = "requiredSegmentVid-hidden";
|
||||
client.get(endpoint, { params: { videoID: "requiredSegmentVid", requiredSegments: `["${requiredHidden}","${required3}"]` } })
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const data = res.data;
|
||||
assert.strictEqual(data.length, 2);
|
||||
const expected = [{
|
||||
UUID: requiredHidden,
|
||||
}, {
|
||||
UUID: required3,
|
||||
}];
|
||||
assert.ok(partialDeepEquals(data, expected));
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("Should be able to get shadowhidden segments with requiredSegments", (done) => {
|
||||
const required2 = "requiredSegmentVid2";
|
||||
const requiredShadowHidden = "requiredSegmentVid-shadowhidden";
|
||||
client.get(endpoint, { params: { videoID: "requiredSegmentVid", requiredSegments: `["${required2}","${requiredShadowHidden}"]` } })
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const data = res.data;
|
||||
assert.strictEqual(data.length, 2);
|
||||
const expected = [{
|
||||
UUID: required2,
|
||||
}, {
|
||||
UUID: requiredShadowHidden,
|
||||
}];
|
||||
assert.ok(partialDeepEquals(data, expected));
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -150,7 +150,7 @@ describe("getSkipSegmentsByHash", () => {
|
||||
client.get(`${endpoint}/fdaf`, { params: { categories: `["sponsor","intro"]` } })
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const data = res.data;
|
||||
const data = (res.data as Array<any>).sort((a, b) => a.videoID.localeCompare(b.videoID));
|
||||
assert.strictEqual(data.length, 2);
|
||||
assert.strictEqual(data[0].segments.length, 2);
|
||||
assert.strictEqual(data[1].segments.length, 1);
|
||||
@@ -163,15 +163,15 @@ describe("getSkipSegmentsByHash", () => {
|
||||
client.get(`${endpoint}/fdaf`)
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const data = res.data;
|
||||
const data = (res.data as Array<any>).sort((a, b) => a.videoID.localeCompare(b.videoID));
|
||||
const expected = [{
|
||||
segments: [{
|
||||
category: "sponsor",
|
||||
UUID: "getSegmentsByHash-01",
|
||||
UUID: "getSegmentsByHash-01"
|
||||
}]
|
||||
}, {
|
||||
segments: [{
|
||||
category: "sponsor",
|
||||
category: "sponsor"
|
||||
}]
|
||||
}];
|
||||
assert.strictEqual(data.length, 2);
|
||||
@@ -187,7 +187,7 @@ describe("getSkipSegmentsByHash", () => {
|
||||
client.get(`${endpoint}/fdaf`, { params: { actionType: "skip" } })
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const data = res.data;
|
||||
const data = (res.data as Array<any>).sort((a, b) => a.videoID.localeCompare(b.videoID));
|
||||
assert.strictEqual(data.length, 2);
|
||||
assert.strictEqual(data[0].segments.length, 1);
|
||||
assert.strictEqual(data[1].segments.length, 1);
|
||||
@@ -211,7 +211,7 @@ describe("getSkipSegmentsByHash", () => {
|
||||
client.get(`${endpoint}/fdaf?actionType=skip&actionType=mute`)
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const data = res.data;
|
||||
const data = (res.data as Array<any>).sort((a, b) => a.videoID.localeCompare(b.videoID));
|
||||
assert.strictEqual(data.length, 2);
|
||||
assert.strictEqual(data[0].segments.length, 2);
|
||||
assert.strictEqual(data[1].segments.length, 1);
|
||||
@@ -237,7 +237,7 @@ describe("getSkipSegmentsByHash", () => {
|
||||
client.get(`${endpoint}/fdaf?actionTypes=["skip","mute"]`)
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const data = res.data;
|
||||
const data = (res.data as Array<any>).sort((a, b) => a.videoID.localeCompare(b.videoID));
|
||||
assert.strictEqual(data.length, 2);
|
||||
const expected = [{
|
||||
segments: [{
|
||||
@@ -261,7 +261,7 @@ describe("getSkipSegmentsByHash", () => {
|
||||
client.get(`${endpoint}/fdaf`, { params: { service: "PeerTube" } })
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const data = res.data;
|
||||
const data = (res.data as Array<any>).sort((a, b) => a.videoID.localeCompare(b.videoID));
|
||||
assert.strictEqual(data.length, 1);
|
||||
const expected = [{
|
||||
segments: [{
|
||||
@@ -279,7 +279,7 @@ describe("getSkipSegmentsByHash", () => {
|
||||
client.get(`${endpoint}/c962`, { params: { category: "poi_highlight", actionType: "poi" } })
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const data = res.data;
|
||||
const data = (res.data as Array<any>).sort((a, b) => a.videoID.localeCompare(b.videoID));
|
||||
assert.strictEqual(data.length, 1);
|
||||
assert.strictEqual(data[0].segments.length, 1);
|
||||
assert.strictEqual(data[0].segments[0].category, "poi_highlight");
|
||||
@@ -293,7 +293,7 @@ describe("getSkipSegmentsByHash", () => {
|
||||
client.get(`${endpoint}/c962`, { params: { category: "poi_highlight" } })
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const data = res.data;
|
||||
const data = (res.data as Array<any>).sort((a, b) => a.videoID.localeCompare(b.videoID));
|
||||
assert.strictEqual(data.length, 1);
|
||||
assert.strictEqual(data[0].segments.length, 1);
|
||||
assert.strictEqual(data[0].segments[0].category, "poi_highlight");
|
||||
@@ -317,7 +317,7 @@ describe("getSkipSegmentsByHash", () => {
|
||||
client.get(`${endpoint}/${getHash(testID, 1).substring(0, 3)}`)
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const data = res.data;
|
||||
const data = (res.data as Array<any>).sort((a, b) => a.videoID.localeCompare(b.videoID));
|
||||
assert.strictEqual(data.length, 1);
|
||||
const expected = [{
|
||||
segments: [{
|
||||
@@ -337,7 +337,7 @@ describe("getSkipSegmentsByHash", () => {
|
||||
client.get(`${endpoint}/fdaff4?&category=sponsor&category=intro`)
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const data = res.data;
|
||||
const data = (res.data as Array<any>).sort((a, b) => a.videoID.localeCompare(b.videoID));
|
||||
assert.strictEqual(data.length, 1);
|
||||
const expected = [{
|
||||
segments: [{
|
||||
@@ -360,7 +360,7 @@ describe("getSkipSegmentsByHash", () => {
|
||||
client.get(`${endpoint}/d518?requiredSegments=["requiredSegmentVid-2","requiredSegmentVid-3"]`)
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const data = res.data;
|
||||
const data = (res.data as Array<any>).sort((a, b) => a.videoID.localeCompare(b.videoID));
|
||||
assert.strictEqual(data.length, 1);
|
||||
const expected = [{
|
||||
segments: [{
|
||||
@@ -380,7 +380,7 @@ describe("getSkipSegmentsByHash", () => {
|
||||
client.get(`${endpoint}/d518?requiredSegment=requiredSegmentVid-2&requiredSegment=requiredSegmentVid-3`)
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const data = res.data;
|
||||
const data = (res.data as Array<any>).sort((a, b) => a.videoID.localeCompare(b.videoID));
|
||||
assert.strictEqual(data.length, 1);
|
||||
assert.strictEqual(data[0].segments.length, 2);
|
||||
const expected = [{
|
||||
@@ -400,7 +400,7 @@ describe("getSkipSegmentsByHash", () => {
|
||||
client.get(`${endpoint}/7258?category=chapter&actionType=chapter`)
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const data = res.data;
|
||||
const data = (res.data as Array<any>).sort((a, b) => a.videoID.localeCompare(b.videoID));
|
||||
assert.strictEqual(data.length, 1);
|
||||
const expected = [{
|
||||
segments: [{
|
||||
@@ -432,7 +432,7 @@ describe("getSkipSegmentsByHash", () => {
|
||||
client.get(`${endpoint}/6613?actionType=skip&actionType=mute`)
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const data = res.data;
|
||||
const data = (res.data as Array<any>).sort((a, b) => a.videoID.localeCompare(b.videoID));
|
||||
assert.strictEqual(data.length, 1);
|
||||
const expected = [{
|
||||
segments: [{
|
||||
@@ -490,7 +490,7 @@ describe("getSkipSegmentsByHash", () => {
|
||||
client.get(`${endpoint}/3061?categories=["sponsor","music_offtopic"]`)
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const data = res.data;
|
||||
const data = (res.data as Array<any>).sort((a, b) => a.videoID.localeCompare(b.videoID));
|
||||
assert.strictEqual(data.length, 1);
|
||||
const expected = [{
|
||||
segments: [{
|
||||
@@ -510,7 +510,7 @@ describe("getSkipSegmentsByHash", () => {
|
||||
client.get(`${endpoint}/ab0c?actionType=skip&actionType=mute`)
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const data = res.data;
|
||||
const data = (res.data as Array<any>).sort((a, b) => a.videoID.localeCompare(b.videoID));
|
||||
assert.strictEqual(data.length, 1);
|
||||
const expected = [{
|
||||
segments: [{
|
||||
@@ -551,7 +551,7 @@ describe("getSkipSegmentsByHash", () => {
|
||||
client.get(`${endpoint}/278f`, { params: { category: ["sponsor", "selfpromo"], actionType: "full" } })
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const data = res.data;
|
||||
const data = (res.data as Array<any>).sort((a, b) => a.videoID.localeCompare(b.videoID));
|
||||
assert.strictEqual(data.length, 1);
|
||||
assert.strictEqual(data[0].segments.length, 1);
|
||||
assert.strictEqual(data[0].segments[0].category, "selfpromo");
|
||||
@@ -566,7 +566,7 @@ describe("getSkipSegmentsByHash", () => {
|
||||
client.get(`${endpoint}/17bf?requiredSegments=["${requiredSegment1.slice(0,8)}","${requiredSegment2.slice(0,8)}"]`)
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const data = res.data;
|
||||
const data = (res.data as Array<any>).sort((a, b) => a.videoID.localeCompare(b.videoID));
|
||||
assert.strictEqual(data.length, 1);
|
||||
const expected = [{
|
||||
segments: [{
|
||||
|
||||
@@ -110,4 +110,16 @@ describe("getStatus", () => {
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("Should be able to get redis latency", function (done) {
|
||||
if (!config.redis?.enabled) this.skip();
|
||||
client.get(endpoint)
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const data = res.data;
|
||||
assert.ok(data.redisProcessTime >= 0);
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -10,16 +10,17 @@ describe("getUserInfo", () => {
|
||||
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, "shadowHidden") VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
|
||||
await db.prepare("run", sponsorTimesQuery, ["getUserInfo0", 1, 11, 2, "uuid000001", getHash("getuserinfo_user_01"), 1, 10, "sponsor", 0]);
|
||||
await db.prepare("run", sponsorTimesQuery, ["getUserInfo0", 1, 11, 2, "uuid000002", getHash("getuserinfo_user_01"), 2, 10, "sponsor", 0]);
|
||||
await db.prepare("run", sponsorTimesQuery, ["getUserInfo1", 1, 11, -1, "uuid000003", getHash("getuserinfo_user_01"), 3, 10, "sponsor", 0]);
|
||||
await db.prepare("run", sponsorTimesQuery, ["getUserInfo1", 1, 11, -2, "uuid000004", getHash("getuserinfo_user_01"), 4, 10, "sponsor", 1]);
|
||||
await db.prepare("run", sponsorTimesQuery, ["getUserInfo2", 1, 11, -5, "uuid000005", getHash("getuserinfo_user_01"), 5, 10, "sponsor", 1]);
|
||||
await db.prepare("run", sponsorTimesQuery, ["getUserInfo0", 1, 11, 2, "uuid000007", getHash("getuserinfo_user_02"), 7, 10, "sponsor", 1]);
|
||||
await db.prepare("run", sponsorTimesQuery, ["getUserInfo0", 1, 11, 2, "uuid000008", getHash("getuserinfo_user_02"), 8, 10, "sponsor", 1]);
|
||||
await db.prepare("run", sponsorTimesQuery, ["getUserInfo0", 0, 36000, 2,"uuid000009", getHash("getuserinfo_user_03"), 8, 10, "sponsor", 0]);
|
||||
await db.prepare("run", sponsorTimesQuery, ["getUserInfo3", 1, 11, 2, "uuid000006", getHash("getuserinfo_user_02"), 6, 10, "sponsor", 0]);
|
||||
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]);
|
||||
|
||||
|
||||
const insertWarningQuery = 'INSERT INTO warnings ("userID", "issueTime", "issuerUserID", "enabled", "reason") VALUES (?, ?, ?, ?, ?)';
|
||||
@@ -64,7 +65,7 @@ describe("getUserInfo", () => {
|
||||
ignoredViewCount: 20,
|
||||
segmentCount: 3,
|
||||
ignoredSegmentCount: 2,
|
||||
reputation: -2,
|
||||
reputation: -1.5,
|
||||
lastSegmentID: "uuid000005",
|
||||
vip: false,
|
||||
warnings: 0,
|
||||
@@ -307,4 +308,28 @@ describe("getUserInfo", () => {
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
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));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -22,8 +22,7 @@ describe("getUserStats", () => {
|
||||
await db.prepare("run", sponsorTimesQuery, ["getuserstats1", 0, 60, -2, "skip", "getuserstatsuuid9", getHash("getuserstats_user_02"), 8, 2, "sponsor", 0]);
|
||||
await db.prepare("run", sponsorTimesQuery, ["getuserstats1", 0, 60, 0, "skip", "getuserstatsuuid10", getHash("getuserstats_user_01"), 8, 2, "filler", 0]);
|
||||
await db.prepare("run", sponsorTimesQuery, ["getuserstats1", 0, 0, 0, "full", "getuserstatsuuid11", getHash("getuserstats_user_01"), 8, 2, "exclusive_access", 0]);
|
||||
|
||||
|
||||
await db.prepare("run", sponsorTimesQuery, ["getuserstats1", 0, 60, 0, "chapter", "getuserstatsuuid12", getHash("getuserstats_user_01"), 9, 2, "chapter", 0]);
|
||||
});
|
||||
|
||||
it("Should be able to get a 400 (No userID parameter)", (done) => {
|
||||
@@ -52,17 +51,19 @@ describe("getUserStats", () => {
|
||||
music_offtopic: 1,
|
||||
poi_highlight: 1,
|
||||
filler: 1,
|
||||
exclusive_access: 1
|
||||
exclusive_access: 1,
|
||||
chapter: 1,
|
||||
},
|
||||
actionTypeCount: {
|
||||
mute: 0,
|
||||
skip: 8,
|
||||
full: 1,
|
||||
poi: 1
|
||||
poi: 1,
|
||||
chapter: 1,
|
||||
},
|
||||
overallStats: {
|
||||
minutesSaved: 30,
|
||||
segmentCount: 10
|
||||
segmentCount: 11
|
||||
}
|
||||
};
|
||||
assert.ok(partialDeepEquals(res.data, expected));
|
||||
|
||||
49
test/cases/innerTubeApi.ts
Normal file
49
test/cases/innerTubeApi.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { config } from "../../src/config";
|
||||
import assert from "assert";
|
||||
import { YouTubeAPI } from "../../src/utils/youtubeApi";
|
||||
import * as innerTube from "../../src/utils/innerTubeAPI";
|
||||
import { partialDeepEquals } from "../utils/partialDeepEquals";
|
||||
import { getVideoDetails } from "../../src/utils/getVideoDetails";
|
||||
|
||||
const videoID = "BaW_jenozKc";
|
||||
const expectedInnerTube = { // partial type of innerTubeVideoDetails
|
||||
videoId: videoID,
|
||||
title: "youtube-dl test video \"'/\\ä↭𝕐",
|
||||
lengthSeconds: "10",
|
||||
channelId: "UCLqxVugv74EIW3VWh2NOa3Q",
|
||||
isOwnerViewing: false,
|
||||
isCrawlable: true,
|
||||
allowRatings: true,
|
||||
author: "Philipp Hagemeister",
|
||||
isPrivate: false,
|
||||
isUnpluggedCorpus: false,
|
||||
isLiveContent: false
|
||||
};
|
||||
const currentViews = 49816;
|
||||
|
||||
describe("innertube API test", function() {
|
||||
it("should be able to get innerTube details", async () => {
|
||||
const result = await innerTube.getPlayerData(videoID, true);
|
||||
assert.ok(partialDeepEquals(result, expectedInnerTube));
|
||||
});
|
||||
it("Should have more views than current", async () => {
|
||||
const result = await innerTube.getPlayerData(videoID, true);
|
||||
assert.ok(Number(result.viewCount) >= currentViews);
|
||||
});
|
||||
it("Should have equivalent response from NewLeaf", async function () {
|
||||
if (!config.newLeafURLs || config.newLeafURLs.length <= 0 || config.newLeafURLs[0] == "placeholder") this.skip();
|
||||
const itResponse = await innerTube.getPlayerData(videoID, true);
|
||||
const newLeafResponse = await YouTubeAPI.listVideos(videoID, true);
|
||||
// validate videoID
|
||||
assert.strictEqual(itResponse.videoId, videoID);
|
||||
assert.strictEqual(newLeafResponse.data?.videoId, videoID);
|
||||
// validate description
|
||||
assert.strictEqual(itResponse.shortDescription, newLeafResponse.data?.description);
|
||||
// validate authorId
|
||||
assert.strictEqual(itResponse.channelId, newLeafResponse.data?.authorId);
|
||||
});
|
||||
it("Should return data from generic endpoint", async function () {
|
||||
const videoDetail = await getVideoDetails(videoID);
|
||||
assert.ok(videoDetail);
|
||||
});
|
||||
});
|
||||
@@ -54,6 +54,7 @@ describe("lockCategoriesRecords", () => {
|
||||
await db.prepare("run", insertLockCategoryQuery, [lockVIPUserHash, "delete-record-1", "mute", "sponsor", "reason-5", "YouTube"]);
|
||||
await db.prepare("run", insertLockCategoryQuery, [lockVIPUserHash, "delete-record-1", "skip", "intro", "reason-5", "YouTube"]);
|
||||
await db.prepare("run", insertLockCategoryQuery, [lockVIPUserHash, "delete-record-1", "mute", "intro", "reason-5", "YouTube"]);
|
||||
await db.prepare("run", insertLockCategoryQuery, [lockVIPUserHash, "delete-record-poi", "poi", "poi_highlight", "reason-6", "YouTube"]);
|
||||
});
|
||||
|
||||
it("Should update the database version when starting the application", async () => {
|
||||
@@ -519,4 +520,44 @@ describe("lockCategoriesRecords", () => {
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("should be able to delete poi type category by type poi", (done) => {
|
||||
const videoID = "delete-record-poi";
|
||||
const json = {
|
||||
videoID,
|
||||
userID: lockVIPUser,
|
||||
categories: [
|
||||
"poi_highlight",
|
||||
],
|
||||
actionTypes: ["poi"]
|
||||
};
|
||||
client.delete(endpoint, { data: json })
|
||||
.then(async res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const result = await checkLockCategories(videoID);
|
||||
assert.strictEqual(result.length, 0);
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("should be able to delete poi type category by type poi", (done) => {
|
||||
const videoID = "delete-record-poi";
|
||||
const json = {
|
||||
videoID,
|
||||
userID: lockVIPUser,
|
||||
categories: [
|
||||
"poi_highlight",
|
||||
],
|
||||
actionTypes: ["poi"]
|
||||
};
|
||||
client.delete(endpoint, { data: json })
|
||||
.then(async res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const result = await checkLockCategories(videoID);
|
||||
assert.strictEqual(result.length, 0);
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -44,8 +44,17 @@ describe("postVideoSponsorTime (Old submission method)", () => {
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("Should return 400 for missing params", (done) => {
|
||||
client.post(endpoint, { params: { startTime: 1, endTime: 10, userID } })
|
||||
it("Should return 400 for missing video", (done) => {
|
||||
client.get(endpoint, { params: { startTime: 1, endTime: 10, userID } })
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 400);
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("Should return 400 for missing userID", (done) => {
|
||||
client.get(endpoint, { params: { videoID: videoID1, startTime: 1, endTime: 10 } })
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 400);
|
||||
done();
|
||||
|
||||
@@ -7,6 +7,7 @@ import * as YouTubeAPIModule from "../../src/utils/youtubeApi";
|
||||
import { YouTubeApiMock } from "../youtubeMock";
|
||||
import assert from "assert";
|
||||
import { client } from "../utils/httpClient";
|
||||
import { Feature } from "../../src/types/user.model";
|
||||
|
||||
const mockManager = ImportMock.mockStaticClass(YouTubeAPIModule, "YouTubeAPI");
|
||||
const sinonStub = mockManager.mock("listVideos");
|
||||
@@ -15,6 +16,7 @@ sinonStub.callsFake(YouTubeApiMock.listVideos);
|
||||
describe("postSkipSegments", () => {
|
||||
// Constant and helpers
|
||||
const submitUserOne = `PostSkipUser1${".".repeat(18)}`;
|
||||
const submitUserOneHash = getHash(submitUserOne);
|
||||
const submitUserTwo = `PostSkipUser2${".".repeat(18)}`;
|
||||
const submitUserTwoHash = getHash(submitUserTwo);
|
||||
const submitUserThree = `PostSkipUser3${".".repeat(18)}`;
|
||||
@@ -30,7 +32,6 @@ describe("postSkipSegments", () => {
|
||||
const banUser01 = "ban-user01-loremipsumdolorsitametconsectetur";
|
||||
const banUser01Hash = getHash(banUser01);
|
||||
|
||||
const submitUserOneHash = getHash(submitUserOne);
|
||||
const submitVIPuser = `VIPPostSkipUser${".".repeat(16)}`;
|
||||
const warnVideoID = "postSkip2";
|
||||
const badInputVideoID = "dQw4w9WgXcQ";
|
||||
@@ -66,6 +67,15 @@ describe("postSkipSegments", () => {
|
||||
db.prepare("run", insertSponsorTimeQuery, ["full_video_duration_segment", 0, 0, 0, "full-video-duration-uuid-0", submitUserTwoHash, 0, 0, "sponsor", "full", 123, 0, "full_video_duration_segment"]);
|
||||
db.prepare("run", insertSponsorTimeQuery, ["full_video_duration_segment", 25, 30, 0, "full-video-duration-uuid-1", submitUserTwoHash, 0, 0, "sponsor", "skip", 123, 0, "full_video_duration_segment"]);
|
||||
|
||||
const reputationVideoID = "post_reputation_video";
|
||||
db.prepare("run", insertSponsorTimeQuery, [reputationVideoID, 1, 11, 2,"post_reputation-5-uuid-0", submitUserOneHash, 1606240000000, 50, "sponsor", "skip", 0, 0, reputationVideoID]);
|
||||
db.prepare("run", insertSponsorTimeQuery, [reputationVideoID, 1, 11, 2,"post_reputation-5-uuid-1", submitUserOneHash, 1606240000000, 50, "sponsor", "skip", 0, 0, reputationVideoID]);
|
||||
db.prepare("run", insertSponsorTimeQuery, [reputationVideoID, 1, 11, 2,"post_reputation-5-uuid-2", submitUserOneHash, 1606240000000, 50, "sponsor", "skip", 0, 0, reputationVideoID]);
|
||||
db.prepare("run", insertSponsorTimeQuery, [reputationVideoID, 1, 11, 2,"post_reputation-5-uuid-3", submitUserOneHash, 1606240000000, 50, "sponsor", "skip", 0, 0, reputationVideoID]);
|
||||
db.prepare("run", insertSponsorTimeQuery, [reputationVideoID, 1, 11, 2,"post_reputation-5-uuid-4", submitUserOneHash, 1606240000000, 50, "sponsor", "skip", 0, 0, reputationVideoID]);
|
||||
db.prepare("run", insertSponsorTimeQuery, [reputationVideoID, 1, 11, 0,"post_reputation-5-uuid-6", submitUserOneHash, 1606240000000, 50, "sponsor", "skip", 0, 0, reputationVideoID]);
|
||||
db.prepare("run", insertSponsorTimeQuery, [reputationVideoID, 1, 11, 0,"post_reputation-5-uuid-7", submitUserOneHash, 1606240000000, 50, "sponsor", "skip", 0, 0, reputationVideoID]);
|
||||
|
||||
const now = Date.now();
|
||||
const warnVip01Hash = getHash("warn-vip01-qwertyuiopasdfghjklzxcvbnm");
|
||||
const reason01 = "Reason01";
|
||||
@@ -83,7 +93,6 @@ describe("postSkipSegments", () => {
|
||||
db.prepare("run", insertWarningQuery, [warnUser01Hash, warnVip01Hash, 1, reason01, (now - 3601000)]);
|
||||
// User 2
|
||||
db.prepare("run", insertWarningQuery, [warnUser02Hash, warnVip01Hash, 1, reason02, now]);
|
||||
db.prepare("run", insertWarningQuery, [warnUser02Hash, warnVip01Hash, 1, reason02, now]);
|
||||
db.prepare("run", insertWarningQuery, [warnUser02Hash, warnVip01Hash, 1, reason02, (now - (warningExpireTime + 1000))]);
|
||||
db.prepare("run", insertWarningQuery, [warnUser02Hash, warnVip01Hash, 1, reason02, (now - (warningExpireTime + 2000))]);
|
||||
// User 3
|
||||
@@ -102,6 +111,9 @@ describe("postSkipSegments", () => {
|
||||
|
||||
// ban user
|
||||
db.prepare("run", `INSERT INTO "shadowBannedUsers" ("userID") VALUES(?)`, [banUser01Hash]);
|
||||
|
||||
// user feature
|
||||
db.prepare("run", `INSERT INTO "userFeatures" ("userID", "feature", "issuerUserID", "timeSubmitted") VALUES(?, ?, ?, ?)`, [submitUserTwoHash, Feature.ChapterSubmitter, "some-user", 0]);
|
||||
});
|
||||
|
||||
it("Should be able to submit a single time (Params method)", (done) => {
|
||||
@@ -129,7 +141,6 @@ describe("postSkipSegments", () => {
|
||||
title: "Example Title",
|
||||
channelID: "ExampleChannel",
|
||||
published: 123,
|
||||
genreUrl: ""
|
||||
};
|
||||
assert.ok(partialDeepEquals(videoInfo, expectedVideoInfo));
|
||||
|
||||
@@ -189,7 +200,7 @@ describe("postSkipSegments", () => {
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("Should be able to submit a single chapter (JSON method)", (done) => {
|
||||
it("Should be able to submit a single chapter due to reputation (JSON method)", (done) => {
|
||||
const videoID = "postSkipChapter1";
|
||||
postSkipSegmentJSON({
|
||||
userID: submitUserOne,
|
||||
@@ -217,6 +228,34 @@ describe("postSkipSegments", () => {
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("Should be able to submit a single chapter due to user feature (JSON method)", (done) => {
|
||||
const videoID = "postSkipChapter2";
|
||||
postSkipSegmentJSON({
|
||||
userID: submitUserTwo,
|
||||
videoID,
|
||||
segments: [{
|
||||
segment: [0, 10],
|
||||
category: "chapter",
|
||||
actionType: "chapter",
|
||||
description: "This is a chapter"
|
||||
}],
|
||||
})
|
||||
.then(async res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const row = await queryDatabaseChapter(videoID);
|
||||
const expected = {
|
||||
startTime: 0,
|
||||
endTime: 10,
|
||||
category: "chapter",
|
||||
actionType: "chapter",
|
||||
description: "This is a chapter"
|
||||
};
|
||||
assert.ok(partialDeepEquals(row, expected));
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("Should not be able to submit an music_offtopic with mute action type (JSON method)", (done) => {
|
||||
const videoID = "postSkip4";
|
||||
postSkipSegmentJSON({
|
||||
@@ -237,8 +276,27 @@ describe("postSkipSegments", () => {
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("Should not be able to submit a chapter without permission (JSON method)", (done) => {
|
||||
const videoID = "postSkipChapter3";
|
||||
postSkipSegmentJSON({
|
||||
userID: submitUserThree,
|
||||
videoID,
|
||||
segments: [{
|
||||
segment: [0, 10],
|
||||
category: "chapter",
|
||||
actionType: "chapter",
|
||||
description: "This is a chapter"
|
||||
}],
|
||||
})
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 400);
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("Should not be able to submit a chapter with skip action type (JSON method)", (done) => {
|
||||
const videoID = "postSkipChapter2";
|
||||
const videoID = "postSkipChapter4";
|
||||
postSkipSegmentJSON({
|
||||
userID: submitUserOne,
|
||||
videoID,
|
||||
@@ -258,7 +316,7 @@ describe("postSkipSegments", () => {
|
||||
});
|
||||
|
||||
it("Should not be able to submit a sponsor with a description (JSON method)", (done) => {
|
||||
const videoID = "postSkipChapter3";
|
||||
const videoID = "postSkipChapter5";
|
||||
postSkipSegmentJSON({
|
||||
userID: submitUserOne,
|
||||
videoID,
|
||||
@@ -1220,7 +1278,7 @@ describe("postSkipSegments", () => {
|
||||
});
|
||||
|
||||
it("Should return 400 if videoID is empty", (done) => {
|
||||
const videoID = null as string;
|
||||
const videoID = null as unknown as string;
|
||||
postSkipSegmentParam({
|
||||
videoID,
|
||||
startTime: 1,
|
||||
|
||||
@@ -9,6 +9,8 @@ describe("postWarning", () => {
|
||||
const endpoint = "/api/warnUser";
|
||||
const getWarning = (userID: string) => db.prepare("get", `SELECT "userID", "issueTime", "issuerUserID", enabled, "reason" FROM warnings WHERE "userID" = ?`, [userID]);
|
||||
|
||||
const warnedUser = getHash("warning-0");
|
||||
|
||||
before(async () => {
|
||||
await db.prepare("run", `INSERT INTO "vipUsers" ("userID") VALUES (?)`, [getHash("warning-vip")]);
|
||||
});
|
||||
@@ -16,7 +18,7 @@ describe("postWarning", () => {
|
||||
it("Should be able to create warning if vip (exp 200)", (done) => {
|
||||
const json = {
|
||||
issuerUserID: "warning-vip",
|
||||
userID: "warning-0",
|
||||
userID: warnedUser,
|
||||
reason: "warning-reason-0"
|
||||
};
|
||||
client.post(endpoint, json)
|
||||
@@ -37,7 +39,7 @@ describe("postWarning", () => {
|
||||
it("Should be not be able to create a duplicate warning if vip", (done) => {
|
||||
const json = {
|
||||
issuerUserID: "warning-vip",
|
||||
userID: "warning-0",
|
||||
userID: warnedUser,
|
||||
};
|
||||
|
||||
client.post(endpoint, json)
|
||||
@@ -57,7 +59,7 @@ describe("postWarning", () => {
|
||||
it("Should be able to remove warning if vip", (done) => {
|
||||
const json = {
|
||||
issuerUserID: "warning-vip",
|
||||
userID: "warning-0",
|
||||
userID: warnedUser,
|
||||
enabled: false
|
||||
};
|
||||
|
||||
@@ -100,7 +102,7 @@ describe("postWarning", () => {
|
||||
it("Should re-enable disabled warning", (done) => {
|
||||
const json = {
|
||||
issuerUserID: "warning-vip",
|
||||
userID: "warning-0",
|
||||
userID: warnedUser,
|
||||
enabled: true
|
||||
};
|
||||
|
||||
@@ -116,4 +118,41 @@ describe("postWarning", () => {
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("Should be able to remove your own warning", (done) => {
|
||||
const json = {
|
||||
userID: "warning-0",
|
||||
enabled: false
|
||||
};
|
||||
|
||||
client.post(endpoint, json)
|
||||
.then(async res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const data = await getWarning(warnedUser);
|
||||
const expected = {
|
||||
enabled: 0
|
||||
};
|
||||
assert.ok(partialDeepEquals(data, expected));
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("Should be able to add your own warning", (done) => {
|
||||
const json = {
|
||||
userID: "warning-0"
|
||||
};
|
||||
|
||||
client.post(endpoint, json)
|
||||
.then(async res => {
|
||||
assert.strictEqual(res.status, 403);
|
||||
const data = await getWarning(warnedUser);
|
||||
const expected = {
|
||||
enabled: 0
|
||||
};
|
||||
assert.ok(partialDeepEquals(data, expected));
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
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 { partialDeepEquals, arrayPartialDeepEquals } from "../../utils/partialDeepEquals";
|
||||
|
||||
const endpoint = "/api/ratings/rate";
|
||||
const getRating = (hash: string, params?: unknown): Promise<AxiosResponse> => client.get(`${endpoint}/${hash}`, { params });
|
||||
const getBulkRating = (hashes: string[], params?: any): Promise<AxiosResponse> => client.get(endpoint, { params: { ...params, prefix: hashes } });
|
||||
|
||||
const videoOneID = "some-likes-and-dislikes";
|
||||
const videoOneIDHash = getHash(videoOneID, 1);
|
||||
const videoOnePartialHash = videoOneIDHash.substr(0, 4);
|
||||
const videoTwoID = "some-likes-and-dislikes-2";
|
||||
const videoTwoIDHash = getHash(videoTwoID, 1);
|
||||
const videoTwoPartialHash = videoTwoIDHash.substr(0, 4);
|
||||
|
||||
describe("getRating", () => {
|
||||
before(async () => {
|
||||
const insertUserNameQuery = 'INSERT INTO "ratings" ("videoID", "service", "type", "count", "hashedVideoID") VALUES (?, ?, ?, ?, ?)';
|
||||
await db.prepare("run", insertUserNameQuery, [videoOneID, "YouTube", 0, 5, videoOneIDHash]);
|
||||
await db.prepare("run", insertUserNameQuery, [videoOneID, "YouTube", 1, 10, videoOneIDHash]);
|
||||
|
||||
await db.prepare("run", insertUserNameQuery, [videoTwoID, "YouTube", 0, 20, videoTwoIDHash]);
|
||||
await db.prepare("run", insertUserNameQuery, [videoTwoID, "YouTube", 1, 30, videoTwoIDHash]);
|
||||
});
|
||||
|
||||
it("Should be able to get dislikes and likes by default", (done) => {
|
||||
getRating(videoOnePartialHash)
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const expected = [{
|
||||
type: 0,
|
||||
count: 5,
|
||||
}, {
|
||||
type: 1,
|
||||
count: 10,
|
||||
}];
|
||||
assert.ok(partialDeepEquals(res.data, expected));
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("Should be able to filter for only dislikes", (done) => {
|
||||
getRating(videoOnePartialHash, { type: 0 })
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const expected = [{
|
||||
type: 0,
|
||||
count: 5,
|
||||
}];
|
||||
assert.ok(partialDeepEquals(res.data, expected));
|
||||
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
/*
|
||||
This test will fail if tests are already ran with redis.
|
||||
*/
|
||||
it("Should be able to bulk fetch", (done) => {
|
||||
getBulkRating([videoOnePartialHash, videoTwoPartialHash])
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const expected = [{
|
||||
type: 0,
|
||||
count: 20,
|
||||
hash: videoTwoIDHash,
|
||||
},
|
||||
{
|
||||
type: 1,
|
||||
count: 30,
|
||||
hash: videoTwoIDHash,
|
||||
}, {
|
||||
type: 0,
|
||||
count: 5,
|
||||
hash: videoOneIDHash,
|
||||
}, {
|
||||
type: 1,
|
||||
count: 10,
|
||||
hash: videoOneIDHash,
|
||||
}];
|
||||
assert.ok(arrayPartialDeepEquals(res.data, expected));
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("Should return 400 for invalid hash", (done) => {
|
||||
getRating("a")
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 400);
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("Should return 404 for nonexitent type", (done) => {
|
||||
getRating(videoOnePartialHash, { type: 100 })
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 404);
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("Should return 404 for nonexistent videoID", (done) => {
|
||||
getRating("aaaa")
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 404);
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
});
|
||||
@@ -1,51 +0,0 @@
|
||||
import { db } from "../../../src/databases/databases";
|
||||
import { getHash } from "../../../src/utils/getHash";
|
||||
import assert from "assert";
|
||||
import { client } from "../../utils/httpClient";
|
||||
|
||||
const VIPUser = "clearCacheVIP";
|
||||
const regularUser = "regular-user";
|
||||
const endpoint = "/api/ratings/clearCache";
|
||||
const postClearCache = (userID: string, videoID: string) => client({ method: "post", url: endpoint, params: { userID, videoID } });
|
||||
|
||||
describe("ratings postClearCache", () => {
|
||||
before(async () => {
|
||||
await db.prepare("run", `INSERT INTO "vipUsers" ("userID") VALUES ('${getHash(VIPUser)}')`);
|
||||
});
|
||||
|
||||
it("Should be able to clear cache amy video", (done) => {
|
||||
postClearCache(VIPUser, "dne-video")
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
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 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 userID", (done) => {
|
||||
client.post(endpoint, { params: { videoID: "clear-test" } })
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 400);
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
});
|
||||
@@ -1,118 +0,0 @@
|
||||
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 { partialDeepEquals } from "../../utils/partialDeepEquals";
|
||||
|
||||
const endpoint = "/api/ratings/rate/";
|
||||
const postRating = (body: unknown): Promise<AxiosResponse> => client.post(endpoint, body);
|
||||
const queryDatabase = (videoID: string) => db.prepare("all", `SELECT * FROM "ratings" WHERE "videoID" = ?`, [videoID]);
|
||||
|
||||
const videoIDOne = "normal-video";
|
||||
const videoIDTwo = "multiple-rates";
|
||||
const ratingUserID = "rating-testman";
|
||||
|
||||
describe("postRating", () => {
|
||||
before(async () => {
|
||||
const insertUserNameQuery = 'INSERT INTO "ratings" ("videoID", "service", "type", "count", "hashedVideoID") VALUES (?, ?, ?, ?, ?)';
|
||||
await db.prepare("run", insertUserNameQuery, [videoIDTwo, "YouTube", 0, 3, getHash(videoIDTwo, 1)]);
|
||||
});
|
||||
|
||||
it("Should be able to vote on a video", (done) => {
|
||||
const videoID = videoIDOne;
|
||||
postRating({
|
||||
userID: ratingUserID,
|
||||
videoID,
|
||||
type: 0
|
||||
})
|
||||
.then(async res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const expected = [{
|
||||
hashedVideoID: getHash(videoID, 1),
|
||||
videoID,
|
||||
type: 0,
|
||||
count: 1,
|
||||
service: "YouTube"
|
||||
}];
|
||||
assert.ok(partialDeepEquals(await queryDatabase(videoID), expected));
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("Should be able to undo a vote on a video", (done) => {
|
||||
const videoID = videoIDOne;
|
||||
postRating({
|
||||
userID: ratingUserID,
|
||||
videoID,
|
||||
type: 0,
|
||||
enabled: false
|
||||
})
|
||||
.then(async res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const expected = [{
|
||||
type: 0,
|
||||
count: 0
|
||||
}];
|
||||
assert.ok(partialDeepEquals(await queryDatabase(videoID), expected));
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("Should be able to vote after someone else on a video", (done) => {
|
||||
const videoID = videoIDTwo;
|
||||
postRating({
|
||||
userID: ratingUserID,
|
||||
videoID,
|
||||
type: 0
|
||||
})
|
||||
.then(async res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const expected = [{
|
||||
type: 0,
|
||||
count: 4
|
||||
}];
|
||||
assert.ok(partialDeepEquals(await queryDatabase(videoID), expected));
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("Should be able to vote a different type than existing votes on a video", (done) => {
|
||||
const videoID = videoIDTwo;
|
||||
postRating({
|
||||
userID: ratingUserID,
|
||||
videoID,
|
||||
type: 1
|
||||
})
|
||||
.then(async res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const expected = [{
|
||||
type: 0,
|
||||
count: 4
|
||||
}, {
|
||||
type: 1,
|
||||
count: 1
|
||||
}];
|
||||
assert.ok(partialDeepEquals(await queryDatabase(videoID), expected));
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("Should not be able to vote with nonexistent type", (done) => {
|
||||
const videoID = videoIDOne;
|
||||
postRating({
|
||||
userID: ratingUserID,
|
||||
videoID,
|
||||
type: 100
|
||||
})
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 400);
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
});
|
||||
@@ -8,6 +8,8 @@ const genRandom = (bytes=8) => crypto.pseudoRandomBytes(bytes).toString("hex");
|
||||
const randKey1 = genRandom();
|
||||
const randValue1 = genRandom();
|
||||
const randKey2 = genRandom(16);
|
||||
const randKey3 = genRandom();
|
||||
const randValue3 = genRandom();
|
||||
|
||||
describe("redis test", function() {
|
||||
before(async function() {
|
||||
@@ -19,13 +21,41 @@ describe("redis test", function() {
|
||||
.then(res => {
|
||||
assert.strictEqual(res, randValue1);
|
||||
done();
|
||||
}).catch(err => assert.fail(err));
|
||||
}).catch(err => done(err));
|
||||
});
|
||||
it("Should not be able to get not stored value", (done) => {
|
||||
redis.get(randKey2)
|
||||
.then(res => {
|
||||
if (res) assert.fail("Value should not be found");
|
||||
if (res) done("Value should not be found");
|
||||
done();
|
||||
}).catch(err => assert.fail(err));
|
||||
}).catch(err => done(err));
|
||||
});
|
||||
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));
|
||||
});
|
||||
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));
|
||||
});
|
||||
it("Should continue when undefined value is fetched", (done) => {
|
||||
const undefkey = `undefined.${genRandom()}`;
|
||||
redis.get(undefkey)
|
||||
.then(result => {
|
||||
assert.ok(!result); // result should be falsy
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -10,6 +10,8 @@ describe("reputation", () => {
|
||||
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;
|
||||
@@ -45,15 +47,28 @@ describe("reputation", () => {
|
||||
await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-1-uuid-7", userHashHighDownvotes, 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", userHashHighNonSelfDownvotes, 1606240000000, 50, "sponsor", 0, 0]);
|
||||
await db.prepare("run", sponsorTimesInsertQuery, [`${videoID}A`, 1, 11, 2, 0, "reputation-1-1-uuid-0", userHashLowNonSelfDownvotes, 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", userHashHighNonSelfDownvotes, 1606240000000, 50, "intro", 0, 0]);
|
||||
await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-1-1-uuid-2", userHashHighNonSelfDownvotes, 1606240000000, 50, "sponsor", 0, 0]);
|
||||
await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-1-1-uuid-3", userHashHighNonSelfDownvotes, 1606240000000, 50, "sponsor", 0, 0]);
|
||||
await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-1-1-uuid-4", userHashHighNonSelfDownvotes, 1606240000000, 50, "sponsor", 0, 0]);
|
||||
await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, -1, 0, "reputation-1-1-uuid-5", userHashHighNonSelfDownvotes, 1606240000000, 50, "sponsor", 0, 0]);
|
||||
await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-1-1-uuid-6", userHashHighNonSelfDownvotes, 1606240000000, 50, "sponsor", 0, 0]);
|
||||
await db.prepare("run", sponsorTimesInsertQuery, [videoID, 1, 11, 0, 0, "reputation-1-1-uuid-7", userHashHighNonSelfDownvotes, 1606240000000, 50, "sponsor", 0, 0]);
|
||||
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]);
|
||||
|
||||
// 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]);
|
||||
// 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]);
|
||||
@@ -141,10 +156,10 @@ describe("reputation", () => {
|
||||
};
|
||||
const data = await getReputation(getHash(userIDHighDownvotes));
|
||||
assert.strictEqual(data, calculateReputationFromMetrics(metrics));
|
||||
assert.strictEqual(data, -2.125);
|
||||
assert.strictEqual(data, -1.7500000000000002);
|
||||
});
|
||||
|
||||
it("user with high non self downvote ratio", async () => {
|
||||
it("user with low non self downvote ratio", async () => {
|
||||
const metrics = {
|
||||
totalSubmissions: 8,
|
||||
downvotedSubmissions: 2,
|
||||
@@ -155,9 +170,14 @@ describe("reputation", () => {
|
||||
oldUpvotedSubmissions: 1,
|
||||
mostUpvotedInLockedVideoSum: 0
|
||||
};
|
||||
const data = await getReputation(userHashHighNonSelfDownvotes);
|
||||
const data = await getReputation(userHashLowNonSelfDownvotes);
|
||||
assert.strictEqual(data, calculateReputationFromMetrics(metrics));
|
||||
assert.strictEqual(data, -1.6428571428571428);
|
||||
assert.strictEqual(data, 0);
|
||||
});
|
||||
|
||||
it("user with high non self downvote ratio", async () => {
|
||||
const data = await getReputation(userHashHighNonSelfDownvotes);
|
||||
assert.strictEqual(data, -2.5);
|
||||
});
|
||||
|
||||
it("user with mostly new submissions", async () => {
|
||||
|
||||
@@ -6,14 +6,13 @@ import { client } from "../utils/httpClient";
|
||||
import { db, privateDB } from "../../src/databases/databases";
|
||||
import redis from "../../src/utils/redis";
|
||||
import assert from "assert";
|
||||
import { Logger } from "../../src/utils/logger";
|
||||
|
||||
// helpers
|
||||
const getSegment = (UUID: string) => db.prepare("get", `SELECT "votes", "locked", "category" FROM "sponsorTimes" WHERE "UUID" = ?`, [UUID]);
|
||||
|
||||
const permVIP1 = "tempVipPermOne";
|
||||
const permVIP1 = "tempVip_permaVIPOne";
|
||||
const publicPermVIP1 = getHash(permVIP1) as HashedUserID;
|
||||
const permVIP2 = "tempVipPermOne";
|
||||
const permVIP2 = "tempVip_permaVIPTwo";
|
||||
const publicPermVIP2 = getHash(permVIP2) as HashedUserID;
|
||||
|
||||
const tempVIPOne = "tempVipTempOne";
|
||||
@@ -51,15 +50,8 @@ const postVoteCategory = (userID: string, UUID: string, category: string) => cli
|
||||
category
|
||||
}
|
||||
});
|
||||
const checkUserVIP = async (publicID: HashedUserID) => {
|
||||
try {
|
||||
const reply = await redis.get(tempVIPKey(publicID));
|
||||
return reply;
|
||||
} catch (e) {
|
||||
Logger.error(e as string);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
const checkUserVIP = async (publicID: HashedUserID): Promise<string> =>
|
||||
await redis.get(tempVIPKey(publicID));
|
||||
|
||||
describe("tempVIP test", function() {
|
||||
before(async function() {
|
||||
@@ -152,7 +144,7 @@ describe("tempVIP test", function() {
|
||||
.catch(err => done(err));
|
||||
});
|
||||
it("Should be able to remove tempVIP prematurely", (done) => {
|
||||
addTempVIP("false", permVIP1, publicTempVIPOne, null)
|
||||
addTempVIP("false", permVIP1, publicTempVIPOne)
|
||||
.then(async res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const vip = await checkUserVIP(publicTempVIPOne);
|
||||
|
||||
@@ -59,6 +59,8 @@ describe("voteOnSponsorTime", () => {
|
||||
await db.prepare("run", insertSponsorTimeQuery, ["category-change-test-1", 8, 12, 0, 1, "category-change-uuid-6", categoryChangeUserHash, 0, 50, "intro", "skip", 0, 0]);
|
||||
await db.prepare("run", insertSponsorTimeQuery, ["category-change-test-1", 9, 14, 0, 0, "category-change-uuid-7", categoryChangeUserHash, 0, 50, "intro", "skip", 0, 0]);
|
||||
await db.prepare("run", insertSponsorTimeQuery, ["category-change-test-1", 7, 12, 0, 1, "category-change-uuid-8", categoryChangeUserHash, 0, 50, "intro", "skip", 0, 0]);
|
||||
await db.prepare("run", insertSponsorTimeQuery, ["category-change-test-2", 7, 14, 0, 0, "category-warnvote-uuid-0", categoryChangeUserHash, 0, 50, "intro", "skip", 0, 0]);
|
||||
await db.prepare("run", insertSponsorTimeQuery, ["category-change-test-2", 8, 13, 0, 0, "category-banvote-uuid-0", categoryChangeUserHash, 0, 50, "intro", "skip", 0, 0]);
|
||||
await db.prepare("run", insertSponsorTimeQuery, ["duration-update", 1, 10, 0, 0, "duration-update-uuid-1", "testman", 0, 0, "intro", "skip", 0, 0]);
|
||||
await db.prepare("run", insertSponsorTimeQuery, ["full-video", 1, 10, 0, 0, "full-video-uuid-1", "testman", 0, 0, "sponsor", "full", 0, 0]);
|
||||
// videoDuration change
|
||||
@@ -67,6 +69,8 @@ describe("voteOnSponsorTime", () => {
|
||||
await db.prepare("run", insertSponsorTimeQuery, ["duration-changed", 1, 12, 0, 0, "duration-changed-uuid-3", "testman", 20, 0, "sponsor", "skip", 0, 0]);
|
||||
// add videoDuration to duration-changed-uuid-2
|
||||
await db.prepare("run", `UPDATE "sponsorTimes" SET "videoDuration" = 150 WHERE "UUID" = 'duration-changed-uuid-2'`);
|
||||
await db.prepare("run", insertSponsorTimeQuery, ["chapter-video", 1, 10, 0, 0, "chapter-uuid-1", "testman", 0, 0, "chapter", "chapter", 0, 0]);
|
||||
await db.prepare("run", insertSponsorTimeQuery, ["chapter-video", 1, 10, 0, 0, "non-chapter-uuid-2", "testman", 0, 0, "sponsor", "skip", 0, 0]);
|
||||
|
||||
const insertWarningQuery = 'INSERT INTO "warnings" ("userID", "issueTime", "issuerUserID", "enabled") VALUES(?, ?, ?, ?)';
|
||||
await db.prepare("run", insertWarningQuery, [warnUser01Hash, now, warnVip01Hash, 1]);
|
||||
@@ -74,7 +78,6 @@ describe("voteOnSponsorTime", () => {
|
||||
await db.prepare("run", insertWarningQuery, [warnUser01Hash, (now - 2000), warnVip01Hash, 1]);
|
||||
await db.prepare("run", insertWarningQuery, [warnUser01Hash, (now - 3601000), warnVip01Hash, 1]);
|
||||
await db.prepare("run", insertWarningQuery, [warnUser02Hash, now, warnVip01Hash, 1]);
|
||||
await db.prepare("run", insertWarningQuery, [warnUser02Hash, now, warnVip01Hash, 1]);
|
||||
await db.prepare("run", insertWarningQuery, [warnUser02Hash, (now - (warningExpireTime + 1000)), warnVip01Hash, 1]);
|
||||
await db.prepare("run", insertWarningQuery, [warnUser02Hash, (now - (warningExpireTime + 2000)), warnVip01Hash, 1]);
|
||||
|
||||
@@ -223,6 +226,30 @@ describe("voteOnSponsorTime", () => {
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("should be able to completely downvote chapter using malicious", (done) => {
|
||||
const UUID = "chapter-uuid-1";
|
||||
postVote(randomID2, UUID, 30)
|
||||
.then(async res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const row = await getSegmentVotes(UUID);
|
||||
assert.strictEqual(row.votes, -2);
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("should not be able to completely downvote non-chapter using malicious", (done) => {
|
||||
const UUID = "non-chapter-uuid-2";
|
||||
postVote(randomID2, UUID, 30)
|
||||
.then(async res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const row = await getSegmentVotes(UUID);
|
||||
assert.strictEqual(row.votes, 0);
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("Should be able to vote for a category and it should add your vote to the database", (done) => {
|
||||
const UUID = "vote-uuid-4";
|
||||
postVoteCategory(randomID2, UUID, "intro")
|
||||
@@ -265,6 +292,18 @@ describe("voteOnSponsorTime", () => {
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("Should not able to change to chapter category", (done) => {
|
||||
const UUID = "incorrect-category";
|
||||
postVoteCategory(randomID2, UUID, "chapter")
|
||||
.then(async res => {
|
||||
assert.strictEqual(res.status, 400);
|
||||
const row = await getSegmentCategory(UUID);
|
||||
assert.strictEqual(row.category, "sponsor");
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("Should be able to change your vote for a category and it should add your vote to the database(segment unlocked, nextCatgeory unlocked)", (done) => {
|
||||
const UUID = "vote-uuid-4";
|
||||
postVoteCategory(randomID2, UUID, "outro")
|
||||
@@ -419,6 +458,32 @@ describe("voteOnSponsorTime", () => {
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("Should not be able to vote for a category of a segment (Too many warning)", (done) => {
|
||||
const UUID = "category-warnvote-uuid-0";
|
||||
const category = "preview";
|
||||
postVoteCategory("warn-voteuser01", UUID, category)
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 403);
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("Should be able to vote for a category as a shadowbanned user, but it shouldn't add your vote to the database", (done) => {
|
||||
const UUID = "category-banvote-uuid-0";
|
||||
const category = "preview";
|
||||
postVoteCategory("randomID4", UUID, category)
|
||||
.then(async res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const row = await getSegmentCategory(UUID);
|
||||
const categoryRows = await db.prepare("all", `SELECT votes, category FROM "categoryVotes" WHERE "UUID" = ?`, [UUID]);
|
||||
assert.strictEqual(row.category, "intro");
|
||||
assert.strictEqual(categoryRows.length, 0);
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("Should not be able to category-vote on an invalid UUID submission", (done) => {
|
||||
const UUID = "invalid-uuid";
|
||||
postVoteCategory("randomID3", UUID, "intro")
|
||||
@@ -628,4 +693,18 @@ describe("voteOnSponsorTime", () => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("Should not be able to revive full video segment as non-vip", (done) => {
|
||||
const UUID = "full-video-uuid-1";
|
||||
postVote("VIPUser", UUID, 0).then(() => {
|
||||
postVote("randomID3", UUID, 1)
|
||||
.then(async res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const row = await getSegmentVotes(UUID);
|
||||
assert.strictEqual(row.votes, -2);
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user