Merge branch 'master' into clickbait

This commit is contained in:
Ajay Ramachandran
2023-01-28 02:13:42 -05:00
committed by GitHub
39 changed files with 1207 additions and 228 deletions

12
test/cases/environment.ts Normal file
View File

@@ -0,0 +1,12 @@
import assert from "assert";
import { config } from "../../src/config";
describe("environment", () => {
it("minUserIDLength should be < 10", () => {
assert(config.minUserIDLength < 10);
});
it("nodeJS major version should be >= 16", () => {
const [major] = process.versions.node.split(".").map(i => parseInt(i));
assert(major >= 16);
});
});

View File

@@ -46,7 +46,6 @@ describe("getSkipSegments", () => {
assert.strictEqual(data[0].votes, 1);
assert.strictEqual(data[0].locked, 0);
assert.strictEqual(data[0].videoDuration, 100);
assert.strictEqual(data[0].userID, "testman");
done();
})
.catch(err => done(err));

View File

@@ -6,7 +6,7 @@ import { UserID } from "../../src/types/user.model";
describe("getSubmissionUUID", () => {
it("Should return the hashed value", () => {
assert.strictEqual(
getSubmissionUUID("video001" as VideoID, "sponsor" as Category, "skip" as ActionType, "testuser001" as UserID, 13.33337, 42.000001, Service.YouTube),
"2a473bca993dd84d8c2f6a4785989b20948dfe0c12c00f6f143bbda9ed561dca6");
getSubmissionUUID("video001" as VideoID, "sponsor" as Category, "skip" as ActionType, "", "testuser001" as UserID, 13.33337, 42.000001, Service.YouTube),
"2a473bca993dd84d8c2f6a4785989b20948dfe0c12c00f6f143bbda9ed561dca7");
});
});

View File

@@ -22,12 +22,22 @@ const user07PrivateUserID = "setUsername_07";
const username07 = "Username 07";
const user08PrivateUserID = "setUsername_08";
// private = public cases
// user09 - username === privateID
const user09PrivateUserID = "setUsername_09";
// user 10/11 - user 11 username === user 10 privateID
const user10PrivateUserID = "setUsername_10_collision";
const username10 = "setUsername_10";
const user11PrivateUserID = "setUsername_11";
const user12PrivateUserID = "setUsername_12";
const username12 = "Username 12";
async function addUsername(userID: string, userName: string, locked = 0) {
await db.prepare("run", 'INSERT INTO "userNames" ("userID", "userName", "locked") VALUES(?, ?, ?)', [userID, userName, locked]);
await addLogUserNameChange(userID, userName);
}
async function getUsernameInfo(userID: string): Promise<{ userName: string, locked: string }> {
async function getUsernameInfo(userID: string): Promise<{ userName: string, locked: string}> {
const row = await db.prepare("get", 'SELECT "userName", "locked" FROM "userNames" WHERE "userID" = ?', [userID]);
if (!row) {
return null;
@@ -88,6 +98,9 @@ describe("setUsername", () => {
await addUsername(getHash(user05PrivateUserID), username05, 0);
await addUsername(getHash(user06PrivateUserID), username06, 0);
await addUsername(getHash(user07PrivateUserID), username07, 1);
await addUsername(getHash(user10PrivateUserID), username10, 0);
// user11 skipped
await addUsername(getHash(user12PrivateUserID), username12, 0);
});
it("Should be able to set username that has never been set", (done) => {
@@ -240,6 +253,44 @@ describe("setUsername", () => {
const usernameInfo = await getUsernameInfo(getHash(user08PrivateUserID));
assert.strictEqual(usernameInfo, null);
done();
});
})
.catch((err) => done(err));
});
it("Should return error if trying to set username to privateID", (done) => {
const privateID = user09PrivateUserID;
postSetUserName(privateID, privateID)
.then(async (res) => {
assert.strictEqual(res.status, 400);
const usernameInfo = await getUsernameInfo(getHash(privateID));
assert.strictEqual(usernameInfo, null);
done();
})
.catch((err) => done(err));
});
it("Should return error if trying to set username to someone else's privateID", (done) => {
const privateID = user11PrivateUserID;
postSetUserName(privateID, user10PrivateUserID)
.then(async (res) => {
assert.strictEqual(res.status, 400);
const usernameInfo = await getUsernameInfo(getHash(privateID)); // user 10's privateID
assert.strictEqual(usernameInfo, null);
done();
})
.catch((err) => done(err));
});
it("Should not return error if trying to set username to someone else's publicID", (done) => {
const privateID = user12PrivateUserID;
const user10PublicID = getHash(user10PrivateUserID);
postSetUserName(privateID, user10PublicID)
.then(async (res) => {
assert.strictEqual(res.status, 200);
const usernameInfo = await getUsernameInfo(getHash(privateID)); // user 10's publicID
assert.strictEqual(usernameInfo.userName, user10PublicID);
done();
})
.catch((err) => done(err));
});
});

View File

@@ -0,0 +1,125 @@
import assert from "assert";
import { client } from "../utils/httpClient";
import { config } from "../../src/config";
import sinon from "sinon";
import { sanitize } from "../../src/utils/youtubeID";
// videoID array
const badVideoIDs = [
["null", "< 11"],
["dQw4w9WgXc?", "invalid characters"],
["https://www.youtube.com/clip/UgkxeLPGsmKnMdm46DGml_0aa0aaAAAAA00a", "clip URL"],
["https://youtube.com/channel/UCaAa00aaaAA0a0a0AaaAAAA", "channel ID (UC)"],
["https://www.youtube.com/@LinusTechTips", "channel @username"],
["https://www.youtube.com/@GamersNexus", "channel @username"],
["https://www.youtube.com/c/LinusTechTips", "custom channel /c/"],
["https://www.youtube.com/c/GamersNexus", "custom channel /c/"],
["https://www.youtube.com/", "home/ page URL"],
["03224876b002487796379942f199bc22ffac46157ad2488119bccc7b03c55430","UUID"],
["https://www.youtube.com/watch?v=dQw4w9WgXcQ&t=16s#requiredSegment=03224876b002487796379942f199bc22ffac46157ad2488119bccc7b03c55430", "full #requiredSegments uuid"],
["","empty videoID"]
];
const goodVideoIDs = [
["dQw4w9WgXcQ", "standalone videoID"],
["https://www.youtube.com/watch?v=dQw4w9WgXcQ", "?watch link"],
["http://www.youtube.com/watch?v=dQw4w9WgXcQ", "http link"],
["www.youtube.com/watch?v=dQw4w9WgXcQ", "no protocol link"],
["https://www.youtube.com/watch?v=dQw4w9WgXcQ?t=2", "trailing &t parameter"],
["https://youtu.be/dQw4w9WgXcQ","youtu.be"],
["youtu.be/dQw4w9WgXcQ","no protocol youtu.be"],
["https://www.youtube.com/watch?v=dQw4w9WgXcQ&t=16s#requiredSegment=00000000000","#requiredsegment link"],
["https://www.youtube.com/embed/dQw4w9WgXcQ?wmode=transparent&rel=0&autohide=1&showinfo=1&fs=1&enablejsapi=0&theme=light", "long embedded link"],
["http://m.youtube.com/watch?v=dQw4w9WgXcQ&app=m&persist_app=1", "force persist desktop"],
["http://m.youtube.com/watch?v=dQw4w9WgXcQ", "mobile"],
["https://www.youtube.com/watch?v=dQw4w9WgXcQ&list=PL8mG-AaA0aAa0AAa0A0A-aAaaA00aaAa0","/watch&list"],
["https://www.youtube.com/embed/dQw4w9WgXcQ?list=PL8mG-AaA0aAa0AAa0A0A-aAaaA00aaAa0","/embed/video"],
["dQw4w9WgXcQ\n", "escaped newline"],
["dQw4w9WgXcQ\t", "escaped tab"],
["%20dQw4w9WgXcQ%20%20%20", "urlencoded"],
["https://sb.ltn.fi/video/dQw4w9WgXcQ/","sbltnfi link"],
["https://www.youtube.com/watch?v=dQw4w9WgXcQ#t=0m10s", "anchor as t parameter"],
];
const edgeVideoIDs = [
["https://www.youtube.com/embed/videoseries?list=PL8mG-Aaa0aAa1AAa0A0A-a0aaA00aaAa0", "/videoseries"],
["https://www.youtube.com/embed/playlist?list=PL8mG-Aaa0aAa1AAa0A0A-a0aaA00aaAa0", "/playlist"],
["PL8mG-Aaa0aAa1AAa0A0A-a0aaA00aaAa0", "playlist ID"],
["UgkxeLPGsmKnMdm46DGml_0aa0aaAAAAA00a","clip ID"],
["https://www.youtube.com/GamersNexus", "channel custom URL"],
["https://www.youtube.com/LinusTechTips", "channel custom URL"],
];
const targetVideoID = "dQw4w9WgXcQ";
// tests
describe("YouTube VideoID validation - failing tests", () => {
for (const testCase of badVideoIDs) {
it(`Should error on invalid videoID - ${testCase[1]}`, () => {
assert.equal(sanitize(testCase[0]), null);
});
}
});
describe("YouTube VideoID validation - passing tests", () => {
for (const testCase of goodVideoIDs) {
it(`Should be able to sanitize good videoID - ${testCase[1]}`, () => {
assert.equal(sanitize(testCase[0]), targetVideoID);
});
}
});
describe("YouTube VideoID validation - edge cases tests", () => {
for (const testCase of edgeVideoIDs) {
it(`edge cases produce bad results - ${testCase[1]}`, () => {
assert.ok(sanitize(testCase[0]));
});
}
});
// stubs
const mode = "production";
let stub: sinon.SinonStub;
// constants
const endpoint = "/api/skipSegments";
const userID = "postVideoID_user1";
const expectedError = `No valid videoID. YouTube videoID could not be extracted`;
// helper functions
const postSkipSegments = (videoID: string) => client({
method: "POST",
url: endpoint,
params: {
videoID,
startTime: Math.random(),
endTime: 10,
userID,
service: "YouTube",
category: "sponsor"
}
});
describe("VideoID Validation - postSkipSegments", () => {
before(() => stub = sinon.stub(config, "mode").value(mode));
after(() => stub.restore());
it("Should return production mode if stub worked", (done) => {
assert.strictEqual(config.mode, mode);
done();
});
it(`Should return 400 for invalid videoID`, (done) => {
postSkipSegments("123456").then(res => {
assert.strictEqual(res.status, 400);
assert.strictEqual(res.data, expectedError);
done();
})
.catch(err => done(err));
});
it(`Should return 200 for valid videoID`, (done) => {
postSkipSegments("dQw4w9WgXcQ").then(res => {
assert.strictEqual(res.status, 200);
done();
})
.catch(err => done(err));
});
});