Merge branch 'master' of https://github.com/ajayyy/SponsorBlockServer into stricter-eslint

This commit is contained in:
Michael C
2021-07-13 15:55:03 -04:00
18 changed files with 145 additions and 48 deletions

View File

@@ -13,11 +13,15 @@ export async function getLockCategories(req: Request, res: Response): Promise<Re
try { try {
// Get existing lock categories markers // Get existing lock categories markers
const lockedCategories = await db.prepare("all", 'SELECT "category" from "lockCategories" where "videoID" = ?', [videoID]) as {category: Category}[]; const row = await db.prepare("all", 'SELECT "category", "reason" from "lockCategories" where "videoID" = ?', [videoID]) as {category: Category, reason: string}[];
if (lockedCategories.length === 0 || !lockedCategories[0]) return res.sendStatus(404); // map categories to array in JS becaues of SQL incompatibilities
// map to array in JS becaues of SQL incompatibilities const categories = row.map(item => item.category);
const categories = Object.values(lockedCategories).map((entry) => entry.category); if (categories.length === 0 || !categories[0]) return res.sendStatus(404);
// Get longest lock reason
const reason = row.map(item => item.reason)
.reduce((a,b) => (a.length > b.length) ? a : b);
return res.send({ return res.send({
reason,
categories categories
}); });
} catch (err) { } catch (err) {

View File

@@ -7,13 +7,15 @@ import { Category, VideoID, VideoIDHash } from "../types/segments.model";
interface LockResultByHash { interface LockResultByHash {
videoID: VideoID, videoID: VideoID,
hash: VideoIDHash, hash: VideoIDHash,
reason: string,
categories: Category[] categories: Category[]
} }
interface DBLock { interface DBLock {
videoID: VideoID, videoID: VideoID,
hash: VideoIDHash, hash: VideoIDHash,
category: Category category: Category,
reason: string,
} }
const mergeLocks = (source: DBLock[]) => { const mergeLocks = (source: DBLock[]) => {
@@ -22,12 +24,15 @@ const mergeLocks = (source: DBLock[]) => {
// videoID already exists // videoID already exists
const destMatch = dest.find(s => s.videoID === obj.videoID); const destMatch = dest.find(s => s.videoID === obj.videoID);
if (destMatch) { if (destMatch) {
// override longer reason
if (obj.reason.length > destMatch.reason.length) destMatch.reason = obj.reason;
// push to categories // push to categories
destMatch.categories.push(obj.category); destMatch.categories.push(obj.category);
} else { } else {
dest.push({ dest.push({
videoID: obj.videoID, videoID: obj.videoID,
hash: obj.hash, hash: obj.hash,
reason: obj.reason,
categories: [obj.category] categories: [obj.category]
}); });
} }

View File

@@ -275,6 +275,10 @@ async function chooseSegments(segments: DBSegment[], max: number): Promise<DBSeg
*/ */
async function handleGetSegments(req: Request, res: Response): Promise<Segment[] | false> { async function handleGetSegments(req: Request, res: Response): Promise<Segment[] | false> {
const videoID = req.query.videoID as VideoID; const videoID = req.query.videoID as VideoID;
if (!videoID) {
res.status(400).send("videoID not specified");
return false;
}
// Default to sponsor // Default to sponsor
// If using params instead of JSON, only one category can be pulled // If using params instead of JSON, only one category can be pulled
const categories: Category[] = req.query.categories const categories: Category[] = req.query.categories

View File

@@ -5,7 +5,7 @@ import { ActionType, Category, SegmentUUID, Service, VideoIDHash } from "../type
export async function getSkipSegmentsByHash(req: Request, res: Response): Promise<Response> { export async function getSkipSegmentsByHash(req: Request, res: Response): Promise<Response> {
let hashPrefix = req.params.prefix as VideoIDHash; let hashPrefix = req.params.prefix as VideoIDHash;
if (!hashPrefixTester(req.params.prefix)) { if (!req.params.prefix || !hashPrefixTester(req.params.prefix)) {
return res.status(400).send("Hash prefix does not match format requirements."); // Exit early on faulty prefix return res.status(400).send("Hash prefix does not match format requirements."); // Exit early on faulty prefix
} }
hashPrefix = hashPrefix.toLowerCase() as VideoIDHash; hashPrefix = hashPrefix.toLowerCase() as VideoIDHash;

View File

@@ -6,6 +6,8 @@ import {getHash} from "../utils/getHash";
import { HashedUserID, UserID } from "../types/user.model"; import { HashedUserID, UserID } from "../types/user.model";
export async function postWarning(req: Request, res: Response): Promise<Response> { export async function postWarning(req: Request, res: Response): Promise<Response> {
// exit early if no body passed in
if (!req.body.userID && !req.body.issuerUserID) return res.status(400).json({"message": "Missing parameters"});
// Collect user input data // Collect user input data
const issuerUserID: HashedUserID = getHash(<UserID> req.body.issuerUserID); const issuerUserID: HashedUserID = getHash(<UserID> req.body.issuerUserID);
const userID: UserID = req.body.userID; const userID: UserID = req.body.userID;

View File

@@ -10,9 +10,9 @@ export function skipSegmentsHashKey(hashedVideoIDPrefix: VideoIDHash, service: S
hashedVideoIDPrefix = hashedVideoIDPrefix.substring(0, 4) as VideoIDHash; hashedVideoIDPrefix = hashedVideoIDPrefix.substring(0, 4) as VideoIDHash;
if (hashedVideoIDPrefix.length !== 4) Logger.warn(`Redis skip segment hash-prefix key is not length 4! ${hashedVideoIDPrefix}`); if (hashedVideoIDPrefix.length !== 4) Logger.warn(`Redis skip segment hash-prefix key is not length 4! ${hashedVideoIDPrefix}`);
return `segments.v2.${ service }.${ hashedVideoIDPrefix}`; return `segments.v2.${service}.${hashedVideoIDPrefix}`;
} }
export function reputationKey(userID: UserID): string { export function reputationKey(userID: UserID): string {
return `reputation.user.${ userID}`; return `reputation.user.${userID}`;
} }

View File

@@ -7,12 +7,14 @@ interface ReputationDBResult {
totalSubmissions: number, totalSubmissions: number,
downvotedSubmissions: number, downvotedSubmissions: number,
nonSelfDownvotedSubmissions: number, nonSelfDownvotedSubmissions: number,
upvotedSum: number, votedSum: number,
lockedSum: number, lockedSum: number,
semiOldUpvotedSubmissions: number,
oldUpvotedSubmissions: number oldUpvotedSubmissions: number
} }
export async function getReputation(userID: UserID): Promise<number> { export async function getReputation(userID: UserID): Promise<number> {
const weekAgo = Date.now() - 1000 * 60 * 60 * 24 * 45; // 45 days ago
const pastDate = Date.now() - 1000 * 60 * 60 * 24 * 45; // 45 days ago const pastDate = Date.now() - 1000 * 60 * 60 * 24 * 45; // 45 days ago
// 1596240000000 is August 1st 2020, a little after auto upvote was disabled // 1596240000000 is August 1st 2020, a little after auto upvote was disabled
const fetchFromDB = () => db.prepare("get", const fetchFromDB = () => db.prepare("get",
@@ -23,10 +25,11 @@ export async function getReputation(userID: UserID): Promise<number> {
WHERE b."userID" = ? WHERE b."userID" = ?
AND b."votes" > 0 AND b."category" = "a"."category" AND b."videoID" = "a"."videoID" LIMIT 1) AND b."votes" > 0 AND b."category" = "a"."category" AND b."videoID" = "a"."videoID" LIMIT 1)
THEN 1 ELSE 0 END) AS "nonSelfDownvotedSubmissions", THEN 1 ELSE 0 END) AS "nonSelfDownvotedSubmissions",
SUM(CASE WHEN "votes" > 0 AND "timeSubmitted" > 1596240000000 THEN "votes" ELSE 0 END) AS "upvotedSum", SUM(CASE WHEN "timeSubmitted" > 1596240000000 THEN "votes" ELSE 0 END) AS "votedSum",
SUM(locked) AS "lockedSum", SUM(locked) AS "lockedSum",
SUM(CASE WHEN "timeSubmitted" < ? AND "timeSubmitted" > 1596240000000 AND "votes" > 0 THEN 1 ELSE 0 END) AS "semiOldUpvotedSubmissions",
SUM(CASE WHEN "timeSubmitted" < ? AND "timeSubmitted" > 1596240000000 AND "votes" > 0 THEN 1 ELSE 0 END) AS "oldUpvotedSubmissions" SUM(CASE WHEN "timeSubmitted" < ? AND "timeSubmitted" > 1596240000000 AND "votes" > 0 THEN 1 ELSE 0 END) AS "oldUpvotedSubmissions"
FROM "sponsorTimes" as "a" WHERE "userID" = ?`, [userID, pastDate, userID]) as Promise<ReputationDBResult>; FROM "sponsorTimes" as "a" WHERE "userID" = ?`, [userID, weekAgo, pastDate, userID]) as Promise<ReputationDBResult>;
const result = await QueryCacher.get(fetchFromDB, reputationKey(userID)); const result = await QueryCacher.get(fetchFromDB, reputationKey(userID));
@@ -45,11 +48,19 @@ export async function getReputation(userID: UserID): Promise<number> {
return convertRange(Math.min(nonSelfDownvoteRatio, 0.4), 0.05, 0.4, -0.5, -2.5); return convertRange(Math.min(nonSelfDownvoteRatio, 0.4), 0.05, 0.4, -0.5, -2.5);
} }
if (result.oldUpvotedSubmissions < 3 || result.upvotedSum < 5) { if (result.votedSum < 5) {
return 0; return 0;
} }
return convertRange(Math.min(result.upvotedSum, 150), 5, 150, 0, 7) + convertRange(Math.min(result.lockedSum ?? 0, 50), 0, 50, 0, 20); if (result.oldUpvotedSubmissions < 3) {
if (result.semiOldUpvotedSubmissions > 3) {
return convertRange(Math.min(result.votedSum, 150), 5, 150, 0, 2) + convertRange(Math.min(result.lockedSum ?? 0, 50), 0, 50, 0, 5);
} else {
return 0;
}
}
return convertRange(Math.min(result.votedSum, 150), 5, 150, 0, 7) + convertRange(Math.min(result.lockedSum ?? 0, 50), 0, 50, 0, 20);
} }
function convertRange(value: number, currentMin: number, currentMax: number, targetMin: number, targetMax: number): number { function convertRange(value: number, currentMin: number, currentMax: number, targetMin: number, targetMax: number): number {

View File

@@ -10,19 +10,19 @@ describe("getLockCategories", () => {
const insertVipUserQuery = 'INSERT INTO "vipUsers" ("userID") VALUES (?)'; const insertVipUserQuery = 'INSERT INTO "vipUsers" ("userID") VALUES (?)';
await db.prepare("run", insertVipUserQuery, [getHash("VIPUser-getLockCategories")]); await db.prepare("run", insertVipUserQuery, [getHash("VIPUser-getLockCategories")]);
const insertLockCategoryQuery = 'INSERT INTO "lockCategories" ("userID", "videoID", "category") VALUES (?, ?, ?)'; const insertLockCategoryQuery = 'INSERT INTO "lockCategories" ("userID", "videoID", "category", "reason") VALUES (?, ?, ?, ?)';
await db.prepare("run", insertLockCategoryQuery, [getHash("VIPUser-getLockCategories"), "getLock-1", "sponsor"]); await db.prepare("run", insertLockCategoryQuery, [getHash("VIPUser-getLockCategories"), "getLock-1", "sponsor", "1-short"]);
await db.prepare("run", insertLockCategoryQuery, [getHash("VIPUser-getLockCategories"), "getLock-1", "interaction"]); await db.prepare("run", insertLockCategoryQuery, [getHash("VIPUser-getLockCategories"), "getLock-1", "interaction", "1-longer-reason"]);
await db.prepare("run", insertLockCategoryQuery, [getHash("VIPUser-getLockCategories"), "getLock-2", "preview"]); await db.prepare("run", insertLockCategoryQuery, [getHash("VIPUser-getLockCategories"), "getLock-2", "preview", "2-reason"]);
await db.prepare("run", insertLockCategoryQuery, [getHash("VIPUser-getLockCategories"), "getLock-3", "nonmusic"]); await db.prepare("run", insertLockCategoryQuery, [getHash("VIPUser-getLockCategories"), "getLock-3", "nonmusic", "3-reason"]);
}); });
it("Should update the database version when starting the application", async () => { 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; const version = (await db.prepare("get", "SELECT key, value FROM config where key = ?", ["version"])).value;
if (version > 1) return; if (version > 20) return;
else return `Version isn't greater than 1. Version is ${version}`; else return `Version isn't greater than 20. Version is ${version}`;
}); });
it("Should be able to get multiple locks", (done: Done) => { it("Should be able to get multiple locks", (done: Done) => {
@@ -34,7 +34,8 @@ describe("getLockCategories", () => {
categories: [ categories: [
"sponsor", "sponsor",
"interaction" "interaction"
] ],
reason: "1-longer-reason"
}; };
assert.deepStrictEqual(data, expected); assert.deepStrictEqual(data, expected);
done(); done();
@@ -50,7 +51,8 @@ describe("getLockCategories", () => {
const expected = { const expected = {
categories: [ categories: [
"preview" "preview"
] ],
reason: "2-reason"
}; };
assert.deepStrictEqual(data, expected); assert.deepStrictEqual(data, expected);
done(); done();

View File

@@ -4,29 +4,28 @@ import {getHash} from "../../src/utils/getHash";
import {db} from "../../src/databases/databases"; import {db} from "../../src/databases/databases";
import assert from "assert"; import assert from "assert";
describe("getLockCategoriesByHash", () => { describe("getLockCategoriesByHash", () => {
before(async () => { before(async () => {
const insertVipUserQuery = 'INSERT INTO "vipUsers" ("userID") VALUES (?)'; const insertVipUserQuery = 'INSERT INTO "vipUsers" ("userID") VALUES (?)';
await db.prepare("run", insertVipUserQuery, [getHash("VIPUser-getLockCategories")]); await db.prepare("run", insertVipUserQuery, [getHash("VIPUser-getLockCategories")]);
const insertLockCategoryQuery = 'INSERT INTO "lockCategories" ("userID", "videoID", "category", "hashedVideoID") VALUES (?, ?, ?, ?)'; const insertLockCategoryQuery = 'INSERT INTO "lockCategories" ("userID", "videoID", "category", "reason", "hashedVideoID") VALUES (?, ?, ?, ?, ?)';
await db.prepare("run", insertLockCategoryQuery, [getHash("VIPUser-getLockCategories"), "getLockHash-1", "sponsor", "67a654898fda3a5541774aea345796c7709982bb6018cb08d22a18eeddccc1d0"]); await db.prepare("run", insertLockCategoryQuery, [getHash("VIPUser-getLockCategories"), "getLockHash-1", "sponsor", "1-reason-short", "67a654898fda3a5541774aea345796c7709982bb6018cb08d22a18eeddccc1d0"]);
await db.prepare("run", insertLockCategoryQuery, [getHash("VIPUser-getLockCategories"), "getLockHash-1", "interaction", "67a654898fda3a5541774aea345796c7709982bb6018cb08d22a18eeddccc1d0"]); await db.prepare("run", insertLockCategoryQuery, [getHash("VIPUser-getLockCategories"), "getLockHash-1", "interaction", "1-reason-longer", "67a654898fda3a5541774aea345796c7709982bb6018cb08d22a18eeddccc1d0"]);
await db.prepare("run", insertLockCategoryQuery, [getHash("VIPUser-getLockCategories"), "getLockHash-2", "preview", "dff09120437b4bd594dffae5f3cde3cfc5f6099fb01d0ef4051919b2908d9a50"]); await db.prepare("run", insertLockCategoryQuery, [getHash("VIPUser-getLockCategories"), "getLockHash-2", "preview", "2-reason", "dff09120437b4bd594dffae5f3cde3cfc5f6099fb01d0ef4051919b2908d9a50"]);
await db.prepare("run", insertLockCategoryQuery, [getHash("VIPUser-getLockCategories"), "getLockHash-3", "nonmusic", "bf1b122fd5630e0df8626d00c4a95c58954ad715e5595b0f75a19ac131e28928"]); await db.prepare("run", insertLockCategoryQuery, [getHash("VIPUser-getLockCategories"), "getLockHash-3", "nonmusic", "3-reason", "bf1b122fd5630e0df8626d00c4a95c58954ad715e5595b0f75a19ac131e28928"]);
await db.prepare("run", insertLockCategoryQuery, [getHash("VIPUser-getLockCategories"), "fakehash-1", "outro", "b05a20424f24a53dac1b059fb78d861ba9723645026be2174c93a94f9106bb35"]); await db.prepare("run", insertLockCategoryQuery, [getHash("VIPUser-getLockCategories"), "fakehash-1", "outro", "fake1-reason", "b05a20424f24a53dac1b059fb78d861ba9723645026be2174c93a94f9106bb35"]);
await db.prepare("run", insertLockCategoryQuery, [getHash("VIPUser-getLockCategories"), "fakehash-2", "intro", "b05acd1cd6ec7dffe5ffea64ada91ae7469d6db2ce21c7e30ad7fa62075d450"]); await db.prepare("run", insertLockCategoryQuery, [getHash("VIPUser-getLockCategories"), "fakehash-2", "intro", "fake2-longer-reason", "b05acd1cd6ec7dffe5ffea64ada91ae7469d6db2ce21c7e30ad7fa62075d450"]);
await db.prepare("run", insertLockCategoryQuery, [getHash("VIPUser-getLockCategories"), "fakehash-2", "preview", "b05acd1cd6ec7dffe5ffea64ada91ae7469d6db2ce21c7e30ad7fa62075d450"]); await db.prepare("run", insertLockCategoryQuery, [getHash("VIPUser-getLockCategories"), "fakehash-2", "preview", "fake2-short", "b05acd1cd6ec7dffe5ffea64ada91ae7469d6db2ce21c7e30ad7fa62075d450"]);
}); });
it("Database should be greater or equal to version 18", async () => { it("Database should be greater or equal to version 20", async () => {
const version = (await db.prepare("get", "SELECT key, value FROM config where key = ?", ["version"])).value; const version = (await db.prepare("get", "SELECT key, value FROM config where key = ?", ["version"])).value;
if (version >= 18) return; if (version >= 20) return;
else return `Version isn't greater than 18. Version is ${version}`; else return `Version isn't greater than 20. Version is ${version}`;
}); });
it("Should be able to get multiple locks in one object", (done: Done) => { it("Should be able to get multiple locks in one object", (done: Done) => {
@@ -40,7 +39,8 @@ describe("getLockCategoriesByHash", () => {
categories: [ categories: [
"sponsor", "sponsor",
"interaction" "interaction"
] ],
reason: "1-reason-longer"
}]; }];
assert.deepStrictEqual(data, expected); assert.deepStrictEqual(data, expected);
done(); done();
@@ -58,7 +58,8 @@ describe("getLockCategoriesByHash", () => {
hash: getHash("getLockHash-2", 1), hash: getHash("getLockHash-2", 1),
categories: [ categories: [
"preview" "preview"
] ],
reason: "2-reason"
}]; }];
assert.deepStrictEqual(data, expected); assert.deepStrictEqual(data, expected);
done(); done();
@@ -76,7 +77,8 @@ describe("getLockCategoriesByHash", () => {
hash: getHash("getLockHash-3", 1), hash: getHash("getLockHash-3", 1),
categories: [ categories: [
"nonmusic" "nonmusic"
] ],
reason: "3-reason"
}]; }];
assert.deepStrictEqual(data, expected); assert.deepStrictEqual(data, expected);
done(); done();
@@ -94,14 +96,16 @@ describe("getLockCategoriesByHash", () => {
hash: "b05a20424f24a53dac1b059fb78d861ba9723645026be2174c93a94f9106bb35", hash: "b05a20424f24a53dac1b059fb78d861ba9723645026be2174c93a94f9106bb35",
categories: [ categories: [
"outro" "outro"
] ],
reason: "fake1-reason"
}, { }, {
videoID: "fakehash-2", videoID: "fakehash-2",
hash: "b05acd1cd6ec7dffe5ffea64ada91ae7469d6db2ce21c7e30ad7fa62075d450", hash: "b05acd1cd6ec7dffe5ffea64ada91ae7469d6db2ce21c7e30ad7fa62075d450",
categories: [ categories: [
"intro", "intro",
"preview" "preview"
] ],
reason: "fake2-longer-reason"
}]; }];
assert.deepStrictEqual(data, expected); assert.deepStrictEqual(data, expected);
done(); done();
@@ -144,4 +148,22 @@ describe("getLockCategoriesByHash", () => {
}) })
.catch(err => done(err)); .catch(err => done(err));
}); });
it("should return 400 if hash too short", (done: Done) => {
fetch(`${getbaseURL()}/api/lockCategories/00`)
.then(res => {
assert.strictEqual(res.status, 400);
done();
})
.catch(err => done(err));
});
it("should return 400 if no hash specified", (done: Done) => {
fetch(`${getbaseURL()}/api/lockCategories/`)
.then(res => {
assert.strictEqual(res.status, 400);
done();
})
.catch(err => done(err));
});
}); });

View File

@@ -340,4 +340,13 @@ describe("getSkipSegments", () => {
}) })
.catch(err => done(err)); .catch(err => done(err));
}); });
it('Should get 400 if no videoID passed in', (done: Done) => {
fetch(getbaseURL() + '/api/skipSegments')
.then(async res => {
assert.strictEqual(res.status, 400);
done();
})
.catch(err => done(err));
});
}); });

View File

@@ -11,7 +11,7 @@ const mockManager = ImportMock.mockStaticClass(YouTubeAPIModule, "YouTubeAPI");
const sinonStub = mockManager.mock("listVideos"); const sinonStub = mockManager.mock("listVideos");
sinonStub.callsFake(YouTubeApiMock.listVideos); sinonStub.callsFake(YouTubeApiMock.listVideos);
describe("getSegmentsByHash", () => { describe("getSkipSegmentsByHash", () => {
before(async () => { before(async () => {
const query = 'INSERT INTO "sponsorTimes" ("videoID", "startTime", "endTime", "votes", "UUID", "userID", "timeSubmitted", views, category, "actionType", "service", "hidden", "shadowHidden", "hashedVideoID") VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'; const query = 'INSERT INTO "sponsorTimes" ("videoID", "startTime", "endTime", "votes", "UUID", "userID", "timeSubmitted", views, category, "actionType", "service", "hidden", "shadowHidden", "hashedVideoID") VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
await db.prepare("run", query, ["getSegmentsByHash-0", 1, 10, 2, "getSegmentsByHash-0-0", "testman", 0, 50, "sponsor", "skip", "YouTube", 0, 0, "fdaff4dee1043451faa7398324fb63d8618ebcd11bddfe0491c488db12c6c910"]); await db.prepare("run", query, ["getSegmentsByHash-0", 1, 10, 2, "getSegmentsByHash-0-0", "testman", 0, 50, "sponsor", "skip", "YouTube", 0, 0, "fdaff4dee1043451faa7398324fb63d8618ebcd11bddfe0491c488db12c6c910"]);
@@ -88,7 +88,7 @@ describe("getSegmentsByHash", () => {
it("Should return 400 prefix too long", (done: Done) => { it("Should return 400 prefix too long", (done: Done) => {
const prefix = "1".repeat(50); const prefix = "1".repeat(50);
assert.ok(prefix.length > 33, "failed to generate long enough string"); assert.ok(prefix.length > 33, "failed to generate long enough string");
fetch(`${getbaseURL()}/api/skipSegments/${ prefix }?categories=["shilling"]`) fetch(`${getbaseURL()}/api/skipSegments/${prefix}?categories=["shilling"]`)
.then(res => { .then(res => {
assert.strictEqual(res.status, 400); assert.strictEqual(res.status, 400);
done(); done();

View File

@@ -313,4 +313,13 @@ describe("getUserID", () => {
}) })
.catch(err => done(err)); .catch(err => done(err));
}); });
it('should return 400 if no username parameter specified', (done: Done) => {
fetch(getbaseURL() + '/api/userID')
.then(res => {
assert.strictEqual(res.status, 400);
done();
})
.catch(() => ("couldn't call endpoint"));
});
}); });

View File

@@ -79,7 +79,7 @@ describe("getUserInfo", () => {
}); });
it("Should get warning data with public ID", (done: Done) => { it("Should get warning data with public ID", (done: Done) => {
fetch(`${getbaseURL()}/api/userInfo?publicUserID=${ getHash("getuserinfo_warning_0")}`) fetch(`${getbaseURL()}/api/userInfo?publicUserID=${getHash("getuserinfo_warning_0")}`)
.then(async res => { .then(async res => {
assert.strictEqual(res.status, 200); assert.strictEqual(res.status, 200);
const data = await res.json(); const data = await res.json();

View File

@@ -81,4 +81,18 @@ describe("postPurgeAllSegments", function () {
}) })
.catch(err => done(err)); .catch(err => done(err));
}); });
it('Should return 400 if missing body', function (done: Done) {
fetch(`${baseURL}${route}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
}
})
.then(async res => {
assert.strictEqual(res.status, 400);
done();
})
.catch(err => done(err));
});
}); });

View File

@@ -610,7 +610,7 @@ describe("postSkipSegments", () => {
done(); // success done(); // success
} else { } else {
const body = await res.text(); const body = await res.text();
done(`Status code was ${ res.status } ${ body}`); done(`Status code was ${res.status} ${body}`);
} }
}) })
.catch(err => done(err)); .catch(err => done(err));
@@ -636,7 +636,7 @@ describe("postSkipSegments", () => {
done(); // success done(); // success
} else { } else {
const body = await res.text(); const body = await res.text();
done(`Status code was ${ res.status } ${ body}`); done(`Status code was ${res.status} ${body}`);
} }
}) })
.catch(err => done(err)); .catch(err => done(err));

View File

@@ -98,4 +98,19 @@ describe("postWarning", () => {
}) })
.catch(err => done(err)); .catch(err => done(err));
}); });
it('Should return 400 if missing body', (done: Done) => {
fetch(getbaseURL()
+ "/api/warnUser", {
method: 'POST',
headers: {
'Content-Type': 'application/json',
}
})
.then(async res => {
assert.strictEqual(res.status, 400);
done();
})
.catch(err => done(err));
});
}); });

View File

@@ -114,11 +114,11 @@ describe("reputation", () => {
}); });
it("user with high reputation", async () => { it("user with high reputation", async () => {
assert.strictEqual(await getReputation(getHash(userIDHighRep)), 0.24137931034482757); assert.strictEqual(await getReputation(getHash(userIDHighRep)), 0.19310344827586207);
}); });
it("user with high reputation and locked segments", async () => { it("user with high reputation and locked segments", async () => {
assert.strictEqual(await getReputation(getHash(userIDHighRepAndLocked)), 1.8413793103448277); assert.strictEqual(await getReputation(getHash(userIDHighRepAndLocked)), 1.793103448275862);
}); });
}); });

View File

@@ -235,7 +235,7 @@ describe("voteOnSponsorTime", () => {
assert.strictEqual(sponsorVotes, 1); assert.strictEqual(sponsorVotes, 1);
done(); done();
} else { } else {
done(`Status code was ${ res.status}`); done(`Status code was ${res.status}`);
} }
}) })
.catch(err => done(err)); .catch(err => done(err));
@@ -245,7 +245,7 @@ describe("voteOnSponsorTime", () => {
it("Should not be able to change your vote to an invalid category", (done: Done) => { it("Should not be able to change your vote to an invalid category", (done: Done) => {
const vote = (inputCat: string, assertCat: string, callback: Done) => { const vote = (inputCat: string, assertCat: string, callback: Done) => {
fetch(`${getbaseURL() fetch(`${getbaseURL()
}/api/voteOnSponsorTime?userID=randomID2&UUID=incorrect-category-change&category=${ inputCat}`) }/api/voteOnSponsorTime?userID=randomID2&UUID=incorrect-category-change&category=${inputCat}`)
.then(async () => { .then(async () => {
const row = await db.prepare("get", `SELECT "category" FROM "sponsorTimes" WHERE "UUID" = ?`, ["incorrect-category-change"]); const row = await db.prepare("get", `SELECT "category" FROM "sponsorTimes" WHERE "UUID" = ?`, ["incorrect-category-change"]);
assert.strictEqual(row.category, assertCat); assert.strictEqual(row.category, assertCat);