mirror of
https://github.com/ajayyy/SponsorBlockServer.git
synced 2024-11-13 02:14:32 +01:00
bargaining with postgres CI
- fix tests with lockCategories - new unique naming scheme for video - super janky somehow working method for comparing arrays out of order
This commit is contained in:
parent
2d10dd6c9c
commit
fd6ae8fc0e
4 changed files with 136 additions and 39 deletions
65
config.json.backup
Normal file
65
config.json.backup
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
{
|
||||||
|
"port": 8080,
|
||||||
|
"mockPort": 8081,
|
||||||
|
"globalSalt": "testSalt",
|
||||||
|
"adminUserID": "4bdfdc9cddf2c7d07a8a87b57bf6d25389fb75d1399674ee0e0938a6a60f4c3b",
|
||||||
|
"newLeafURLs": ["placeholder"],
|
||||||
|
"discordReportChannelWebhookURL": "http://127.0.0.1:8081/ReportChannelWebhook",
|
||||||
|
"discordFirstTimeSubmissionsWebhookURL": "http://127.0.0.1:8081/FirstTimeSubmissionsWebhook",
|
||||||
|
"discordCompletelyIncorrectReportWebhookURL": "http://127.0.0.1:8081/CompletelyIncorrectReportWebhook",
|
||||||
|
"discordNeuralBlockRejectWebhookURL": "http://127.0.0.1:8081/NeuralBlockRejectWebhook",
|
||||||
|
"neuralBlockURL": "http://127.0.0.1:8081/NeuralBlock",
|
||||||
|
"behindProxy": true,
|
||||||
|
"postgres": {
|
||||||
|
"user": "ci_db_user",
|
||||||
|
"password": "ci_db_pass",
|
||||||
|
"host": "bf.mchang.icu",
|
||||||
|
"port": 5432
|
||||||
|
},
|
||||||
|
"createDatabaseIfNotExist": true,
|
||||||
|
"schemaFolder": "./databases",
|
||||||
|
"dbSchema": "./databases/_sponsorTimes.db.sql",
|
||||||
|
"privateDBSchema": "./databases/_private.db.sql",
|
||||||
|
"mode": "test",
|
||||||
|
"readOnly": false,
|
||||||
|
"webhooks": [
|
||||||
|
{
|
||||||
|
"url": "http://127.0.0.1:8081/CustomWebhook",
|
||||||
|
"key": "superSecretKey",
|
||||||
|
"scopes": [
|
||||||
|
"vote.up",
|
||||||
|
"vote.down"
|
||||||
|
]
|
||||||
|
}, {
|
||||||
|
"url": "http://127.0.0.1:8081/FailedWebhook",
|
||||||
|
"key": "superSecretKey",
|
||||||
|
"scopes": [
|
||||||
|
"vote.up",
|
||||||
|
"vote.down"
|
||||||
|
]
|
||||||
|
}, {
|
||||||
|
"url": "http://127.0.0.1:8099/WrongPort",
|
||||||
|
"key": "superSecretKey",
|
||||||
|
"scopes": [
|
||||||
|
"vote.up",
|
||||||
|
"vote.down"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"categoryList": ["sponsor", "selfpromo", "interaction", "intro", "outro", "preview", "music_offtopic", "poi_highlight"],
|
||||||
|
"maxNumberOfActiveWarnings": 3,
|
||||||
|
"hoursAfterWarningExpires": 24,
|
||||||
|
"rateLimit": {
|
||||||
|
"vote": {
|
||||||
|
"windowMs": 900000,
|
||||||
|
"max": 20,
|
||||||
|
"message": "Too many votes, please try again later",
|
||||||
|
"statusCode": 429
|
||||||
|
},
|
||||||
|
"view": {
|
||||||
|
"windowMs": 900000,
|
||||||
|
"max": 20,
|
||||||
|
"statusCode": 200
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ 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";
|
||||||
import { client } from "../utils/httpClient";
|
import { client } from "../utils/httpClient";
|
||||||
|
import { mixedDeepEquals } from "../utils/partialDeepEquals";
|
||||||
const endpoint = "/api/lockCategories";
|
const endpoint = "/api/lockCategories";
|
||||||
const getLockCategories = (videoID: string) => client.get(endpoint, { params: { videoID } });
|
const getLockCategories = (videoID: string) => client.get(endpoint, { params: { videoID } });
|
||||||
const getLockCategoriesWithService = (videoID: string, service: string) => client.get(endpoint, { params: { videoID, service } });
|
const getLockCategoriesWithService = (videoID: string, service: string) => client.get(endpoint, { params: { videoID, service } });
|
||||||
|
@ -12,13 +13,13 @@ describe("getLockCategories", () => {
|
||||||
await db.prepare("run", insertVipUserQuery, [getHash("getLockCategoriesVIP")]);
|
await db.prepare("run", insertVipUserQuery, [getHash("getLockCategoriesVIP")]);
|
||||||
|
|
||||||
const insertLockCategoryQuery = 'INSERT INTO "lockCategories" ("userID", "videoID", "category", "reason", "service") VALUES (?, ?, ?, ?, ?)';
|
const insertLockCategoryQuery = 'INSERT INTO "lockCategories" ("userID", "videoID", "category", "reason", "service") VALUES (?, ?, ?, ?, ?)';
|
||||||
await db.prepare("run", insertLockCategoryQuery, [getHash("getLockCategoriesVIP"), "getLock1", "sponsor", "1-short", "YouTube"]);
|
await db.prepare("run", insertLockCategoryQuery, [getHash("getLockCategoriesVIP"), "getLockCategory1", "sponsor", "1-short", "YouTube"]);
|
||||||
await db.prepare("run", insertLockCategoryQuery, [getHash("getLockCategoriesVIP"), "getLock1", "interaction", "1-longer-reason", "YouTube"]);
|
await db.prepare("run", insertLockCategoryQuery, [getHash("getLockCategoriesVIP"), "getLockCategory1", "interaction", "1-longer-reason", "YouTube"]);
|
||||||
|
|
||||||
await db.prepare("run", insertLockCategoryQuery, [getHash("getLockCategoriesVIP"), "getLock2", "preview", "2-reason", "YouTube"]);
|
await db.prepare("run", insertLockCategoryQuery, [getHash("getLockCategoriesVIP"), "getLockCategory2", "preview", "2-reason", "YouTube"]);
|
||||||
|
|
||||||
await db.prepare("run", insertLockCategoryQuery, [getHash("getLockCategoriesVIP"), "getLock3", "nonmusic", "3-reason", "PeerTube"]);
|
await db.prepare("run", insertLockCategoryQuery, [getHash("getLockCategoriesVIP"), "getLockCategory3", "nonmusic", "3-reason", "PeerTube"]);
|
||||||
await db.prepare("run", insertLockCategoryQuery, [getHash("getLockCategoriesVIP"), "getLock3", "sponsor", "3-reason", "YouTube"]);
|
await db.prepare("run", insertLockCategoryQuery, [getHash("getLockCategoriesVIP"), "getLockCategory3", "sponsor", "3-reason", "YouTube"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should update the database version when starting the application", async () => {
|
it("Should update the database version when starting the application", async () => {
|
||||||
|
@ -27,7 +28,7 @@ describe("getLockCategories", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should be able to get multiple locks", (done) => {
|
it("Should be able to get multiple locks", (done) => {
|
||||||
getLockCategories("getLock1")
|
getLockCategories("getLockCategory1")
|
||||||
.then(res => {
|
.then(res => {
|
||||||
assert.strictEqual(res.status, 200);
|
assert.strictEqual(res.status, 200);
|
||||||
const expected = {
|
const expected = {
|
||||||
|
@ -37,14 +38,14 @@ describe("getLockCategories", () => {
|
||||||
],
|
],
|
||||||
reason: "1-longer-reason"
|
reason: "1-longer-reason"
|
||||||
};
|
};
|
||||||
assert.deepStrictEqual(res.data, expected);
|
assert.ok(mixedDeepEquals(res.data, expected));
|
||||||
done();
|
done();
|
||||||
})
|
})
|
||||||
.catch(err => done(err));
|
.catch(err => done(err));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should be able to get single locks", (done) => {
|
it("Should be able to get single locks", (done) => {
|
||||||
getLockCategories("getLock2")
|
getLockCategories("getLockCategory2")
|
||||||
.then(res => {
|
.then(res => {
|
||||||
assert.strictEqual(res.status, 200);
|
assert.strictEqual(res.status, 200);
|
||||||
const expected = {
|
const expected = {
|
||||||
|
@ -60,7 +61,7 @@ describe("getLockCategories", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return 404 if no lock exists", (done) => {
|
it("should return 404 if no lock exists", (done) => {
|
||||||
getLockCategories("getLockNull")
|
getLockCategories("getLockCategoryNull")
|
||||||
.then(res => {
|
.then(res => {
|
||||||
assert.strictEqual(res.status, 404);
|
assert.strictEqual(res.status, 404);
|
||||||
done();
|
done();
|
||||||
|
@ -78,7 +79,7 @@ describe("getLockCategories", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should be able to get multiple locks with service", (done) => {
|
it("Should be able to get multiple locks with service", (done) => {
|
||||||
getLockCategoriesWithService("getLock1", "YouTube")
|
getLockCategoriesWithService("getLockCategory1", "YouTube")
|
||||||
.then(res => {
|
.then(res => {
|
||||||
assert.strictEqual(res.status, 200);
|
assert.strictEqual(res.status, 200);
|
||||||
const expected = {
|
const expected = {
|
||||||
|
@ -88,14 +89,14 @@ describe("getLockCategories", () => {
|
||||||
],
|
],
|
||||||
reason: "1-longer-reason"
|
reason: "1-longer-reason"
|
||||||
};
|
};
|
||||||
assert.deepStrictEqual(res.data, expected);
|
assert.ok(mixedDeepEquals(res.data, expected));
|
||||||
done();
|
done();
|
||||||
})
|
})
|
||||||
.catch(err => done(err));
|
.catch(err => done(err));
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should be able to get single locks with service", (done) => {
|
it("Should be able to get single locks with service", (done) => {
|
||||||
getLockCategoriesWithService("getLock3", "PeerTube")
|
getLockCategoriesWithService("getLockCategory3", "PeerTube")
|
||||||
.then(res => {
|
.then(res => {
|
||||||
assert.strictEqual(res.status, 200);
|
assert.strictEqual(res.status, 200);
|
||||||
const expected = {
|
const expected = {
|
||||||
|
@ -111,7 +112,7 @@ describe("getLockCategories", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should be able to get single locks with service", (done) => {
|
it("Should be able to get single locks with service", (done) => {
|
||||||
getLockCategoriesWithService("getLock3", "Youtube")
|
getLockCategoriesWithService("getLockCategory3", "Youtube")
|
||||||
.then(res => {
|
.then(res => {
|
||||||
assert.strictEqual(res.status, 200);
|
assert.strictEqual(res.status, 200);
|
||||||
const expected = {
|
const expected = {
|
||||||
|
@ -127,7 +128,7 @@ describe("getLockCategories", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should return result from Youtube service if service not match", (done) => {
|
it("should return result from Youtube service if service not match", (done) => {
|
||||||
getLockCategoriesWithService("getLock3", "Dailymotion")
|
getLockCategoriesWithService("getLockCategory3", "Dailymotion")
|
||||||
.then(res => {
|
.then(res => {
|
||||||
assert.strictEqual(res.status, 200);
|
assert.strictEqual(res.status, 200);
|
||||||
const expected = {
|
const expected = {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { config } from "../../src/config";
|
import { config } from "../../src/config";
|
||||||
import { getHash } from "../../src/utils/getHash";
|
import { getHash } from "../../src/utils/getHash";
|
||||||
import { partialDeepEquals } from "../utils/partialDeepEquals";
|
import { partialDeepEquals, arrayDeepEquals } from "../utils/partialDeepEquals";
|
||||||
import { db } from "../../src/databases/databases";
|
import { db } from "../../src/databases/databases";
|
||||||
import { ImportMock } from "ts-mock-imports";
|
import { ImportMock } from "ts-mock-imports";
|
||||||
import * as YouTubeAPIModule from "../../src/utils/youtubeApi";
|
import * as YouTubeAPIModule from "../../src/utils/youtubeApi";
|
||||||
|
@ -29,7 +29,7 @@ describe("postSkipSegments", () => {
|
||||||
|
|
||||||
const submitUserOneHash = getHash(submitUserOne);
|
const submitUserOneHash = getHash(submitUserOne);
|
||||||
const submitVIPuser = `VIPPostSkipUser${".".repeat(16)}`;
|
const submitVIPuser = `VIPPostSkipUser${".".repeat(16)}`;
|
||||||
const warnVideoID = "dQw4w9WgXcF";
|
const warnVideoID = "postSkip2";
|
||||||
const badInputVideoID = "dQw4w9WgXcQ";
|
const badInputVideoID = "dQw4w9WgXcQ";
|
||||||
|
|
||||||
const queryDatabase = (videoID: string) => db.prepare("get", `SELECT "startTime", "endTime", "locked", "category" FROM "sponsorTimes" WHERE "videoID" = ?`, [videoID]);
|
const queryDatabase = (videoID: string) => db.prepare("get", `SELECT "startTime", "endTime", "locked", "category" FROM "sponsorTimes" WHERE "videoID" = ?`, [videoID]);
|
||||||
|
@ -91,7 +91,7 @@ describe("postSkipSegments", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should be able to submit a single time (Params method)", (done) => {
|
it("Should be able to submit a single time (Params method)", (done) => {
|
||||||
const videoID = "dQw4w9WgXcR";
|
const videoID = "postSkip1";
|
||||||
postSkipSegmentParam({
|
postSkipSegmentParam({
|
||||||
videoID,
|
videoID,
|
||||||
startTime: 2,
|
startTime: 2,
|
||||||
|
@ -125,7 +125,7 @@ describe("postSkipSegments", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should be able to submit a single time (JSON method)", (done) => {
|
it("Should be able to submit a single time (JSON method)", (done) => {
|
||||||
const videoID = "dQw4w9WgXcF";
|
const videoID = "postSkip2";
|
||||||
postSkipSegmentJSON({
|
postSkipSegmentJSON({
|
||||||
userID: submitUserOne,
|
userID: submitUserOne,
|
||||||
videoID,
|
videoID,
|
||||||
|
@ -150,7 +150,7 @@ describe("postSkipSegments", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should be able to submit a single time with an action type (JSON method)", (done) => {
|
it("Should be able to submit a single time with an action type (JSON method)", (done) => {
|
||||||
const videoID = "dQw4w9WgXcV";
|
const videoID = "postSkip3";
|
||||||
postSkipSegmentJSON({
|
postSkipSegmentJSON({
|
||||||
userID: submitUserOne,
|
userID: submitUserOne,
|
||||||
videoID,
|
videoID,
|
||||||
|
@ -176,7 +176,7 @@ describe("postSkipSegments", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should not be able to submit an intro with mute action type (JSON method)", (done) => {
|
it("Should not be able to submit an intro with mute action type (JSON method)", (done) => {
|
||||||
const videoID = "dQw4w9WgXpQ";
|
const videoID = "postSkip4";
|
||||||
postSkipSegmentJSON({
|
postSkipSegmentJSON({
|
||||||
userID: submitUserOne,
|
userID: submitUserOne,
|
||||||
videoID,
|
videoID,
|
||||||
|
@ -196,7 +196,7 @@ describe("postSkipSegments", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should be able to submit a single time with a duration from the YouTube API (JSON method)", (done) => {
|
it("Should be able to submit a single time with a duration from the YouTube API (JSON method)", (done) => {
|
||||||
const videoID = "dQw4w9WgXZX";
|
const videoID = "postSkip5";
|
||||||
postSkipSegmentJSON({
|
postSkipSegmentJSON({
|
||||||
userID: submitUserOne,
|
userID: submitUserOne,
|
||||||
videoID,
|
videoID,
|
||||||
|
@ -222,7 +222,7 @@ describe("postSkipSegments", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should be able to submit a single time with a precise duration close to the one from the YouTube API (JSON method)", (done) => {
|
it("Should be able to submit a single time with a precise duration close to the one from the YouTube API (JSON method)", (done) => {
|
||||||
const videoID = "dQw4w9WgXZH";
|
const videoID = "postSkip6";
|
||||||
postSkipSegmentJSON({
|
postSkipSegmentJSON({
|
||||||
userID: submitUserOne,
|
userID: submitUserOne,
|
||||||
videoID,
|
videoID,
|
||||||
|
@ -331,7 +331,7 @@ describe("postSkipSegments", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should be able to submit a single time under a different service (JSON method)", (done) => {
|
it("Should be able to submit a single time under a different service (JSON method)", (done) => {
|
||||||
const videoID = "dQw4w9WgXcG";
|
const videoID = "postSkip7";
|
||||||
postSkipSegmentJSON({
|
postSkipSegmentJSON({
|
||||||
userID: submitUserOne,
|
userID: submitUserOne,
|
||||||
videoID,
|
videoID,
|
||||||
|
@ -383,7 +383,7 @@ describe("postSkipSegments", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should be able to submit multiple times (JSON method)", (done) => {
|
it("Should be able to submit multiple times (JSON method)", (done) => {
|
||||||
const videoID = "dQw4w9WgXcT";
|
const videoID = "postSkip11";
|
||||||
postSkipSegmentJSON({
|
postSkipSegmentJSON({
|
||||||
userID: submitUserOne,
|
userID: submitUserOne,
|
||||||
videoID,
|
videoID,
|
||||||
|
@ -407,14 +407,14 @@ describe("postSkipSegments", () => {
|
||||||
endTime: 60,
|
endTime: 60,
|
||||||
category: "intro"
|
category: "intro"
|
||||||
}];
|
}];
|
||||||
assert.deepStrictEqual(rows, expected);
|
assert.ok(arrayDeepEquals(rows, expected));
|
||||||
done();
|
done();
|
||||||
})
|
})
|
||||||
.catch(err => done(err));
|
.catch(err => done(err));
|
||||||
}).timeout(5000);
|
}).timeout(5000);
|
||||||
|
|
||||||
it("Should allow multiple times if total is under 80% of video(JSON method)", (done) => {
|
it("Should allow multiple times if total is under 80% of video(JSON method)", (done) => {
|
||||||
const videoID = "L_jWHffIx5E";
|
const videoID = "postSkip9";
|
||||||
postSkipSegmentJSON({
|
postSkipSegmentJSON({
|
||||||
userID: submitUserOne,
|
userID: submitUserOne,
|
||||||
videoID,
|
videoID,
|
||||||
|
@ -452,7 +452,7 @@ describe("postSkipSegments", () => {
|
||||||
endTime: 170,
|
endTime: 170,
|
||||||
category: "sponsor"
|
category: "sponsor"
|
||||||
}];
|
}];
|
||||||
assert.deepStrictEqual(rows, expected);
|
assert.ok(arrayDeepEquals(rows, expected));
|
||||||
done();
|
done();
|
||||||
})
|
})
|
||||||
.catch(err => done(err));
|
.catch(err => done(err));
|
||||||
|
@ -505,20 +505,20 @@ describe("postSkipSegments", () => {
|
||||||
.then(async res => {
|
.then(async res => {
|
||||||
assert.strictEqual(res.status, 403);
|
assert.strictEqual(res.status, 403);
|
||||||
const expected = [{
|
const expected = [{
|
||||||
category: "sponsor",
|
category: "interaction",
|
||||||
startTime: 2000,
|
startTime: 0,
|
||||||
endTime: 4000
|
endTime: 1000
|
||||||
}, {
|
}, {
|
||||||
category: "sponsor",
|
category: "interaction",
|
||||||
startTime: 1500,
|
startTime: 1001,
|
||||||
endTime: 2750
|
endTime: 1005
|
||||||
}, {
|
}, {
|
||||||
category: "sponsor",
|
category: "interaction",
|
||||||
startTime: 4050,
|
startTime: 0,
|
||||||
endTime: 4750
|
endTime: 5000
|
||||||
}];
|
}];
|
||||||
const rows = await queryDatabase(videoID);
|
const rows = await db.prepare("all", `SELECT "category", "startTime", "endTime" FROM "sponsorTimes" WHERE "videoID" = ?`, [videoID]);
|
||||||
assert.notDeepStrictEqual(rows, expected);
|
assert.ok(arrayDeepEquals(rows, expected));
|
||||||
done();
|
done();
|
||||||
})
|
})
|
||||||
.catch(err => done(err));
|
.catch(err => done(err));
|
||||||
|
|
|
@ -21,4 +21,35 @@ export const partialDeepEquals = (actual: Record<string, any>, expected: Record<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const arrayDeepEquals = (actual: Record<string, any>, expected: Record<string, any>, print = true): boolean => {
|
||||||
|
if (actual.length !== expected.length) return false;
|
||||||
|
let flag = true;
|
||||||
|
const actualString = JSON.stringify(actual);
|
||||||
|
const expectedString = JSON.stringify(expected);
|
||||||
|
// check every value in arr1 for match in arr2
|
||||||
|
actual.every((value: any) => { if (flag && !expectedString.includes(JSON.stringify(value))) flag = false; });
|
||||||
|
// check arr2 for match in arr1
|
||||||
|
expected.every((value: any) => { if (flag && !actualString.includes(JSON.stringify(value))) flag = false; });
|
||||||
|
|
||||||
|
if (!flag && print) printActualExpected(actual, expected);
|
||||||
|
return flag;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const mixedDeepEquals = (actual: Record<string, any>, expected: Record<string, any>, print = true): boolean => {
|
||||||
|
for (const [ key, value ] of Object.entries(expected)) {
|
||||||
|
// if value is object or array, recurse
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
if (!arrayDeepEquals(actual?.[key], value, false)) {
|
||||||
|
if (print) printActualExpected(actual, expected);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (actual?.[key] !== value) {
|
||||||
|
if (print) printActualExpected(actual, expected);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in a new issue