mirror of
https://github.com/ajayyy/SponsorBlockServer.git
synced 2024-11-10 01:02:30 +01:00
show stats to shadowhidden users
This commit is contained in:
parent
e9e1fd5228
commit
4600b8a599
4 changed files with 107 additions and 21 deletions
|
@ -12,10 +12,12 @@ const maxRewardTime = config.maxRewardTimePerSegmentInSeconds;
|
|||
|
||||
async function dbGetSubmittedSegmentSummary(userID: HashedUserID): Promise<{ minutesSaved: number, segmentCount: number }> {
|
||||
try {
|
||||
const userBanCount = (await db.prepare("get", `SELECT count(*) as "userCount" FROM "shadowBannedUsers" WHERE "userID" = ? LIMIT 1`, [userID]))?.userCount;
|
||||
const countShadowHidden = userBanCount > 0 ? 2 : 1; // if shadowbanned, count shadowhidden as well
|
||||
const row = await db.prepare("get",
|
||||
`SELECT SUM(CASE WHEN "actionType" = 'chapter' THEN 0 ELSE ((CASE WHEN "endTime" - "startTime" > ? THEN ? ELSE "endTime" - "startTime" END) / 60) * "views" END) as "minutesSaved",
|
||||
count(*) as "segmentCount" FROM "sponsorTimes"
|
||||
WHERE "userID" = ? AND "votes" > -2 AND "shadowHidden" != 1`, [maxRewardTime, maxRewardTime, userID], { useReplica: true });
|
||||
WHERE "userID" = ? AND "votes" > -2 AND "shadowHidden" != ?`, [maxRewardTime, maxRewardTime, userID, countShadowHidden], { useReplica: true });
|
||||
if (row.minutesSaved != null) {
|
||||
return {
|
||||
minutesSaved: row.minutesSaved,
|
||||
|
|
|
@ -34,13 +34,15 @@ async function dbGetUserSummary(userID: HashedUserID, fetchCategoryStats: boolea
|
|||
`;
|
||||
}
|
||||
try {
|
||||
const userBanCount = (await db.prepare("get", `SELECT count(*) as "userCount" FROM "shadowBannedUsers" WHERE "userID" = ? LIMIT 1`, [userID]))?.userCount;
|
||||
const countShadowHidden = userBanCount > 0 ? 2 : 1; // if shadowbanned, count shadowhidden as well
|
||||
const row = await db.prepare("get", `
|
||||
SELECT SUM(CASE WHEN "actionType" = 'chapter' THEN 0 ELSE ((CASE WHEN "endTime" - "startTime" > ? THEN ? ELSE "endTime" - "startTime" END) / 60) * "views" END) as "minutesSaved",
|
||||
${additionalQuery}
|
||||
count(*) as "segmentCount"
|
||||
FROM "sponsorTimes"
|
||||
WHERE "userID" = ? AND "votes" > -2 AND "shadowHidden" != 1`,
|
||||
[maxRewardTimePerSegmentInSeconds, maxRewardTimePerSegmentInSeconds, userID]);
|
||||
WHERE "userID" = ? AND "votes" > -2 AND "shadowHidden" != ?`,
|
||||
[maxRewardTimePerSegmentInSeconds, maxRewardTimePerSegmentInSeconds, userID, countShadowHidden]);
|
||||
const source = (row.minutesSaved != null) ? row : {};
|
||||
const handler = { get: (target: Record<string, any>, name: string) => target?.[name] || 0 };
|
||||
const proxy = new Proxy(source, handler);
|
||||
|
|
|
@ -22,6 +22,8 @@ describe("getUserInfo", () => {
|
|||
await db.prepare("run", sponsorTimesQuery, ["getUserInfo3", 1, 11, 2, "uuid000006", getHash("getuserinfo_user_02"), 6, 10, "sponsor", "skip", 0]);
|
||||
await db.prepare("run", sponsorTimesQuery, ["getUserInfo4", 1, 11, 2, "uuid000010", getHash("getuserinfo_user_04"), 9, 10, "chapter", "chapter", 0]);
|
||||
await db.prepare("run", sponsorTimesQuery, ["getUserInfo5", 1, 11, 2, "uuid000011", getHash("getuserinfo_user_05"), 9, 10, "sponsor", "skip", 0]);
|
||||
await db.prepare("run", sponsorTimesQuery, ["getUserInfo6", 1, 11, 2, "uuid000012", getHash("getuserinfo_user_06"), 9, 10, "sponsor", "skip", 1]);
|
||||
await db.prepare("run", sponsorTimesQuery, ["getUserInfo7", 1, 11, 2, "uuid000013", getHash("getuserinfo_ban_02"), 9, 10, "sponsor", "skip", 1]);
|
||||
|
||||
const titlesQuery = 'INSERT INTO "titles" ("videoID", "title", "original", "userID", "service", "hashedVideoID", "timeSubmitted", "UUID") VALUES (?, ?, ?, ?, ?, ?, ?, ?)';
|
||||
const titleVotesQuery = 'INSERT INTO "titleVotes" ("UUID", "votes", "locked", "shadowHidden") VALUES (?, ?, ?, 0);';
|
||||
|
@ -44,6 +46,7 @@ describe("getUserInfo", () => {
|
|||
|
||||
const insertBanQuery = 'INSERT INTO "shadowBannedUsers" ("userID") VALUES (?)';
|
||||
await db.prepare("run", insertBanQuery, [getHash("getuserinfo_ban_01")]);
|
||||
await db.prepare("run", insertBanQuery, [getHash("getuserinfo_ban_02")]);
|
||||
});
|
||||
|
||||
it("Should be able to get a 200", (done) => {
|
||||
|
@ -390,4 +393,30 @@ describe("getUserInfo", () => {
|
|||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("Should return all segments of banned user", (done) => {
|
||||
client.get(endpoint, { params: { userID: "getuserinfo_ban_02", value: ["segmentCount"] } })
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const expected = {
|
||||
segmentCount: 1
|
||||
};
|
||||
assert.ok(partialDeepEquals(res.data, expected));
|
||||
done(); // pass
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("Should not return shadowhidden segments of not-banned user", (done) => {
|
||||
client.get(endpoint, { params: { userID: "getuserinfo_user_06", value: ["segmentCount"] } })
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const expected = {
|
||||
segmentCount: 0
|
||||
};
|
||||
assert.ok(partialDeepEquals(res.data, expected));
|
||||
done(); // pass
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -4,25 +4,44 @@ import { getHash } from "../../src/utils/getHash";
|
|||
import assert from "assert";
|
||||
import { client } from "../utils/httpClient";
|
||||
|
||||
const userOnePrivateID = "getuserstats_user_01";
|
||||
const userOnePublicID = getHash(userOnePrivateID);
|
||||
const userTwoPrivateID = "getuserstats_user_02";
|
||||
const userTwoPublicID = getHash(userTwoPrivateID);
|
||||
const userThreePrivateID = "getuserstats_user_03";
|
||||
const userThreePublicID = getHash(userThreePrivateID);
|
||||
const userFourPrivateID = "getuserstats_user_04";
|
||||
const userFourPublicID = getHash(userFourPrivateID);
|
||||
|
||||
describe("getUserStats", () => {
|
||||
const endpoint = "/api/userStats";
|
||||
before(async () => {
|
||||
const insertBanQuery = 'INSERT INTO "shadowBannedUsers" ("userID") VALUES (?)';
|
||||
await db.prepare("run", insertBanQuery, [userThreePublicID]);
|
||||
|
||||
const insertUserNameQuery = 'INSERT INTO "userNames" ("userID", "userName") VALUES(?, ?)';
|
||||
await db.prepare("run", insertUserNameQuery, [getHash("getuserstats_user_01"), "Username user 01"]);
|
||||
await db.prepare("run", insertUserNameQuery, [userOnePublicID, "Username user 01"]);
|
||||
|
||||
const sponsorTimesQuery = 'INSERT INTO "sponsorTimes" ("videoID", "startTime", "endTime", "votes", "actionType", "UUID", "userID", "timeSubmitted", views, category, "shadowHidden") VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)';
|
||||
await db.prepare("run", sponsorTimesQuery, ["getuserstats1", 0, 60, 0, "skip", "getuserstatsuuid1", getHash("getuserstats_user_01"), 1, 1, "sponsor", 0]);
|
||||
await db.prepare("run", sponsorTimesQuery, ["getuserstats1", 0, 60, 0, "skip", "getuserstatsuuid2", getHash("getuserstats_user_01"), 2, 2, "selfpromo", 0]);
|
||||
await db.prepare("run", sponsorTimesQuery, ["getuserstats1", 0, 60, 0, "skip", "getuserstatsuuid3", getHash("getuserstats_user_01"), 3, 3, "interaction", 0]);
|
||||
await db.prepare("run", sponsorTimesQuery, ["getuserstats1", 0, 60, 0, "skip", "getuserstatsuuid4", getHash("getuserstats_user_01"), 4, 4, "intro", 0]);
|
||||
await db.prepare("run", sponsorTimesQuery, ["getuserstats1", 0, 60, 0, "skip", "getuserstatsuuid5", getHash("getuserstats_user_01"), 5, 5, "outro", 0]);
|
||||
await db.prepare("run", sponsorTimesQuery, ["getuserstats1", 0, 60, 0, "skip", "getuserstatsuuid6", getHash("getuserstats_user_01"), 6, 6, "preview", 0]);
|
||||
await db.prepare("run", sponsorTimesQuery, ["getuserstats1", 0, 60, 0, "skip", "getuserstatsuuid7", getHash("getuserstats_user_01"), 7, 7, "music_offtopic", 0]);
|
||||
await db.prepare("run", sponsorTimesQuery, ["getuserstats1", 11, 11, 0, "poi", "getuserstatsuuid8", getHash("getuserstats_user_01"), 8, 8, "poi_highlight", 0]);
|
||||
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]);
|
||||
await db.prepare("run", sponsorTimesQuery, [userOnePrivateID, 0, 60, 0, "skip", "getuserstatsuuid1", userOnePublicID, 1, 1, "sponsor", 0]);
|
||||
await db.prepare("run", sponsorTimesQuery, [userOnePrivateID, 0, 60, 0, "skip", "getuserstatsuuid2", userOnePublicID, 2, 2, "selfpromo", 0]);
|
||||
await db.prepare("run", sponsorTimesQuery, [userOnePrivateID, 0, 60, 0, "skip", "getuserstatsuuid3", userOnePublicID, 3, 3, "interaction", 0]);
|
||||
await db.prepare("run", sponsorTimesQuery, [userOnePrivateID, 0, 60, 0, "skip", "getuserstatsuuid4", userOnePublicID, 4, 4, "intro", 0]);
|
||||
await db.prepare("run", sponsorTimesQuery, [userOnePrivateID, 0, 60, 0, "skip", "getuserstatsuuid5", userOnePublicID, 5, 5, "outro", 0]);
|
||||
await db.prepare("run", sponsorTimesQuery, [userOnePrivateID, 0, 60, 0, "skip", "getuserstatsuuid6", userOnePublicID, 6, 6, "preview", 0]);
|
||||
await db.prepare("run", sponsorTimesQuery, [userOnePrivateID, 0, 60, 0, "skip", "getuserstatsuuid7", userOnePublicID, 7, 7, "music_offtopic", 0]);
|
||||
await db.prepare("run", sponsorTimesQuery, [userOnePrivateID, 11, 11, 0, "poi", "getuserstatsuuid8", userOnePublicID, 8, 8, "poi_highlight", 0]);
|
||||
await db.prepare("run", sponsorTimesQuery, [userTwoPrivateID, 0, 60, -2, "skip", "getuserstatsuuid9", userTwoPublicID, 8, 2, "sponsor", 0]);
|
||||
await db.prepare("run", sponsorTimesQuery, [userOnePrivateID, 0, 60, 0, "skip", "getuserstatsuuid10", userOnePublicID, 8, 2, "filler", 0]);
|
||||
await db.prepare("run", sponsorTimesQuery, [userOnePrivateID, 0, 0, 0, "full", "getuserstatsuuid11", userOnePublicID, 8, 2, "exclusive_access", 0]);
|
||||
await db.prepare("run", sponsorTimesQuery, [userOnePrivateID, 0, 60, 0, "chapter", "getuserstatsuuid12", userOnePublicID, 9, 2, "chapter", 0]);
|
||||
|
||||
// fully banned user
|
||||
await db.prepare("run", sponsorTimesQuery, [userThreePrivateID, 0, 60, 0, "skip", "getuserstatsuuid13", userThreePublicID, 1, 1, "sponsor", 1]);
|
||||
await db.prepare("run", sponsorTimesQuery, [userThreePrivateID, 0, 60, 0, "skip", "getuserstatsuuid14", userThreePublicID, 1, 1, "sponsor", 1]);
|
||||
// user with banned segments
|
||||
await db.prepare("run", sponsorTimesQuery, [userFourPrivateID, 0, 60, 0, "skip", "getuserstatsuuid15", userFourPublicID, 1, 1, "sponsor", 0]);
|
||||
await db.prepare("run", sponsorTimesQuery, [userFourPrivateID, 0, 60, 0, "skip", "getuserstatsuuid16", userFourPublicID, 1, 1, "sponsor", 1]);
|
||||
});
|
||||
|
||||
it("Should be able to get a 400 (No userID parameter)", (done) => {
|
||||
|
@ -35,12 +54,12 @@ describe("getUserStats", () => {
|
|||
});
|
||||
|
||||
it("Should be able to get all user info", (done) => {
|
||||
client.get(endpoint, { params: { userID: "getuserstats_user_01", fetchCategoryStats: true, fetchActionTypeStats: true } })
|
||||
client.get(endpoint, { params: { userID: userOnePrivateID, fetchCategoryStats: true, fetchActionTypeStats: true } })
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const expected = {
|
||||
userName: "Username user 01",
|
||||
userID: getHash("getuserstats_user_01"),
|
||||
userID: userOnePublicID,
|
||||
categoryCount: {
|
||||
sponsor: 1,
|
||||
selfpromo: 1,
|
||||
|
@ -88,7 +107,7 @@ describe("getUserStats", () => {
|
|||
});
|
||||
|
||||
it("Should be able to get all zeroes for only ignored segments", (done) => {
|
||||
client.get(endpoint, { params: { userID: "getuserstats_user_02" } })
|
||||
client.get(endpoint, { params: { userID: userTwoPrivateID } })
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const data = res.data;
|
||||
|
@ -103,7 +122,7 @@ describe("getUserStats", () => {
|
|||
});
|
||||
|
||||
it("Should not get extra stats if not requested", (done) => {
|
||||
client.get(endpoint, { params: { userID: "getuserstats_user_01" } })
|
||||
client.get(endpoint, { params: { userID: userOnePrivateID } })
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const data = res.data;
|
||||
|
@ -117,7 +136,7 @@ describe("getUserStats", () => {
|
|||
});
|
||||
|
||||
it("Should get parts of extra stats if not requested", (done) => {
|
||||
client.get(endpoint, { params: { userID: "getuserstats_user_01", fetchActionTypeStats: true } })
|
||||
client.get(endpoint, { params: { userID: userOnePrivateID, fetchActionTypeStats: true } })
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const data = res.data;
|
||||
|
@ -129,4 +148,38 @@ describe("getUserStats", () => {
|
|||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("Should return stats for banned segments if user is banned", (done) => {
|
||||
client.get(endpoint, { params: { userID: userThreePrivateID } })
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const expected = {
|
||||
userID: userThreePublicID,
|
||||
overallStats: {
|
||||
minutesSaved: 2,
|
||||
segmentCount: 2
|
||||
}
|
||||
};
|
||||
assert.ok(partialDeepEquals(res.data, expected));
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
|
||||
it("Should not return stats for banned segments", (done) => {
|
||||
client.get(endpoint, { params: { userID: userFourPrivateID } })
|
||||
.then(res => {
|
||||
assert.strictEqual(res.status, 200);
|
||||
const expected = {
|
||||
userID: userFourPublicID,
|
||||
overallStats: {
|
||||
minutesSaved: 1,
|
||||
segmentCount: 1
|
||||
}
|
||||
};
|
||||
assert.ok(partialDeepEquals(res.data, expected));
|
||||
done();
|
||||
})
|
||||
.catch(err => done(err));
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue