mirror of
https://github.com/ajayyy/SponsorBlockServer.git
synced 2025-12-06 03:26:59 +03:00
Added testing
This commit is contained in:
89
index.js
89
index.js
@@ -1,84 +1,5 @@
|
||||
var express = require('express');
|
||||
var fs = require('fs');
|
||||
var http = require('http');
|
||||
// Create a service (the app object is just a callback).
|
||||
var app = express();
|
||||
|
||||
let config = JSON.parse(fs.readFileSync('config.json'));
|
||||
|
||||
// Routes
|
||||
var corsMiddleware = require('./src/middleware/cors.js');
|
||||
var loggerMiddleware = require('./src/middleware/logger.js');
|
||||
|
||||
// Routes
|
||||
var getVideoSponsorTimes = require('./src/routes/getVideoSponsorTimes.js');
|
||||
var submitSponsorTimes = require('./src/routes/submitSponsorTimes.js');
|
||||
var voteOnSponsorTime = require('./src/routes/voteOnSponsorTime.js');
|
||||
var viewedVideoSponsorTime = require('./src/routes/viewedVideoSponsorTime.js');
|
||||
var setUsername = require('./src/routes/setUsername.js');
|
||||
var getUsername = require('./src/routes/getUsername.js');
|
||||
var shadowBanUser = require('./src/routes/shadowBanUser.js');
|
||||
var addUserAsVIP = require('./src/routes/addUserAsVIP.js');
|
||||
var getSavedTimeForUser = require('./src/routes/getSavedTimeForUser.js');
|
||||
var getViewsForUser = require('./src/routes/getViewsForUser.js');
|
||||
var getTopUsers = require('./src/routes/getTopUsers.js');
|
||||
var getTotalStats = require('./src/routes/getTotalStats.js');
|
||||
var getDaysSavedFormatted = require('./src/routes/getDaysSavedFormatted.js');
|
||||
|
||||
|
||||
// Create an HTTP service.
|
||||
http.createServer(app).listen(config.port);
|
||||
|
||||
//setup CORS correctly
|
||||
app.use(corsMiddleware);
|
||||
app.use(loggerMiddleware);
|
||||
|
||||
//add the get function
|
||||
app.get('/api/getVideoSponsorTimes', getVideoSponsorTimes);
|
||||
|
||||
//add the post function
|
||||
app.get('/api/postVideoSponsorTimes', submitSponsorTimes);
|
||||
app.post('/api/postVideoSponsorTimes', submitSponsorTimes);
|
||||
|
||||
//voting endpoint
|
||||
app.get('/api/voteOnSponsorTime', voteOnSponsorTime);
|
||||
app.post('/api/voteOnSponsorTime', voteOnSponsorTime);
|
||||
|
||||
//Endpoint when a sponsorTime is used up
|
||||
app.get('/api/viewedVideoSponsorTime', viewedVideoSponsorTime);
|
||||
app.post('/api/viewedVideoSponsorTime', viewedVideoSponsorTime);
|
||||
|
||||
//To set your username for the stats view
|
||||
app.post('/api/setUsername', setUsername);
|
||||
|
||||
//get what username this user has
|
||||
app.get('/api/getUsername', getUsername);
|
||||
|
||||
//Endpoint used to hide a certain user's data
|
||||
app.post('/api/shadowBanUser', shadowBanUser);
|
||||
|
||||
//Endpoint used to make a user a VIP user with special privileges
|
||||
app.post('/api/addUserAsVIP', addUserAsVIP);
|
||||
|
||||
//Gets all the views added up for one userID
|
||||
//Useful to see how much one user has contributed
|
||||
app.get('/api/getViewsForUser', getViewsForUser);
|
||||
|
||||
//Gets all the saved time added up (views * sponsor length) for one userID
|
||||
//Useful to see how much one user has contributed
|
||||
//In minutes
|
||||
app.get('/api/getSavedTimeForUser', getSavedTimeForUser);
|
||||
|
||||
app.get('/api/getTopUsers', getTopUsers);
|
||||
|
||||
//send out totals
|
||||
//send the total submissions, total views and total minutes saved
|
||||
app.get('/api/getTotalStats', getTotalStats);
|
||||
|
||||
//send out a formatted time saved total
|
||||
app.get('/api/getdayssavedformatted', getDaysSavedFormatted);
|
||||
|
||||
app.get('/database.db', function (req, res) {
|
||||
res.sendfile("./databases/sponsortimes.db", { root: __dirname });
|
||||
});
|
||||
|
||||
var config = require('./src/config.js');
|
||||
var createServer = require('./src/app.js');
|
||||
var server = createServer(() => {
|
||||
console.log("Server started.");
|
||||
});
|
||||
1540
package-lock.json
generated
1540
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@
|
||||
"description": "Server that holds the SponsorBlock database",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"test": "node test.js",
|
||||
"start": "node index.js"
|
||||
},
|
||||
"author": "Ajay Ramachandran",
|
||||
@@ -15,5 +15,8 @@
|
||||
"http": "0.0.0",
|
||||
"uuid": "^3.3.2",
|
||||
"youtube-api": "^2.0.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha": "^7.1.1"
|
||||
}
|
||||
}
|
||||
|
||||
82
src/app.js
Normal file
82
src/app.js
Normal file
@@ -0,0 +1,82 @@
|
||||
var express = require('express');
|
||||
// Create a service (the app object is just a callback).
|
||||
var app = express();
|
||||
var config = require('./config.js');
|
||||
|
||||
// Middleware
|
||||
var corsMiddleware = require('./middleware/cors.js');
|
||||
var loggerMiddleware = require('./middleware/logger.js');
|
||||
|
||||
// Routes
|
||||
var getVideoSponsorTimes = require('./routes/getVideoSponsorTimes.js');
|
||||
var submitSponsorTimes = require('./routes/submitSponsorTimes.js');
|
||||
var voteOnSponsorTime = require('./routes/voteOnSponsorTime.js');
|
||||
var viewedVideoSponsorTime = require('./routes/viewedVideoSponsorTime.js');
|
||||
var setUsername = require('./routes/setUsername.js');
|
||||
var getUsername = require('./routes/getUsername.js');
|
||||
var shadowBanUser = require('./routes/shadowBanUser.js');
|
||||
var addUserAsVIP = require('./routes/addUserAsVIP.js');
|
||||
var getSavedTimeForUser = require('./routes/getSavedTimeForUser.js');
|
||||
var getViewsForUser = require('./routes/getViewsForUser.js');
|
||||
var getTopUsers = require('./routes/getTopUsers.js');
|
||||
var getTotalStats = require('./routes/getTotalStats.js');
|
||||
var getDaysSavedFormatted = require('./routes/getDaysSavedFormatted.js');
|
||||
|
||||
|
||||
//setup CORS correctly
|
||||
app.use(corsMiddleware);
|
||||
app.use(loggerMiddleware);
|
||||
|
||||
//add the get function
|
||||
app.get('/api/getVideoSponsorTimes', getVideoSponsorTimes);
|
||||
|
||||
//add the post function
|
||||
app.get('/api/postVideoSponsorTimes', submitSponsorTimes);
|
||||
app.post('/api/postVideoSponsorTimes', submitSponsorTimes);
|
||||
|
||||
//voting endpoint
|
||||
app.get('/api/voteOnSponsorTime', voteOnSponsorTime);
|
||||
app.post('/api/voteOnSponsorTime', voteOnSponsorTime);
|
||||
|
||||
//Endpoint when a sponsorTime is used up
|
||||
app.get('/api/viewedVideoSponsorTime', viewedVideoSponsorTime);
|
||||
app.post('/api/viewedVideoSponsorTime', viewedVideoSponsorTime);
|
||||
|
||||
//To set your username for the stats view
|
||||
app.post('/api/setUsername', setUsername);
|
||||
|
||||
//get what username this user has
|
||||
app.get('/api/getUsername', getUsername);
|
||||
|
||||
//Endpoint used to hide a certain user's data
|
||||
app.post('/api/shadowBanUser', shadowBanUser);
|
||||
|
||||
//Endpoint used to make a user a VIP user with special privileges
|
||||
app.post('/api/addUserAsVIP', addUserAsVIP);
|
||||
|
||||
//Gets all the views added up for one userID
|
||||
//Useful to see how much one user has contributed
|
||||
app.get('/api/getViewsForUser', getViewsForUser);
|
||||
|
||||
//Gets all the saved time added up (views * sponsor length) for one userID
|
||||
//Useful to see how much one user has contributed
|
||||
//In minutes
|
||||
app.get('/api/getSavedTimeForUser', getSavedTimeForUser);
|
||||
|
||||
app.get('/api/getTopUsers', getTopUsers);
|
||||
|
||||
//send out totals
|
||||
//send the total submissions, total views and total minutes saved
|
||||
app.get('/api/getTotalStats', getTotalStats);
|
||||
|
||||
//send out a formatted time saved total
|
||||
app.get('/api/getdayssavedformatted', getDaysSavedFormatted);
|
||||
|
||||
app.get('/database.db', function (req, res) {
|
||||
res.sendfile("./databases/sponsortimes.db", { root: __dirname });
|
||||
});
|
||||
|
||||
// Create an HTTP service.
|
||||
module.exports = function createServer (callback) {
|
||||
return app.listen(config.port, callback);
|
||||
}
|
||||
12
src/config.js
Normal file
12
src/config.js
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
var fs = require('fs');
|
||||
var config = undefined;
|
||||
|
||||
// Check to see if launched in test mode
|
||||
if (process.env.npm_lifecycle_script === 'node test.js') {
|
||||
config = JSON.parse(fs.readFileSync('test.json'));
|
||||
} else {
|
||||
config = JSON.parse(fs.readFileSync('config.json'));
|
||||
}
|
||||
|
||||
module.exports = config;
|
||||
@@ -1,6 +1,6 @@
|
||||
var fs = require('fs');
|
||||
var config = JSON.parse(fs.readFileSync('config.json'));
|
||||
var config = require('../config.js');
|
||||
var Sqlite3 = require('better-sqlite3');
|
||||
var fs = require('fs');
|
||||
|
||||
let options = {
|
||||
readonly: config.readOnly
|
||||
@@ -9,6 +9,11 @@ let options = {
|
||||
var db = new Sqlite3(config.db, options);
|
||||
var privateDB = new Sqlite3(config.privateDB, options);
|
||||
|
||||
if (config.createDatabaseIfNotExist && !config.readOnly) {
|
||||
if (fs.existsSync(config.dbSchema)) db.exec(fs.readFileSync(config.dbSchema).toString());
|
||||
if (fs.existsSync(config.privateDBSchema)) privateDB.exec(fs.readFileSync(config.privateDBSchema).toString());
|
||||
}
|
||||
|
||||
// Enable WAL mode checkpoint number
|
||||
if (!config.readOnly && config.mode === "production") {
|
||||
db.exec("PRAGMA journal_mode=WAL;");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var fs = require('fs');
|
||||
var config = JSON.parse(fs.readFileSync('config.json'));
|
||||
var config = require('../config.js');
|
||||
|
||||
module.exports = function logger (req, res, next) {
|
||||
(config.mode === "development") && console.log('Request recieved: ' + req.url);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var fs = require('fs');
|
||||
var config = JSON.parse(fs.readFileSync('config.json'));
|
||||
var config = require('../config.js');
|
||||
|
||||
var db = require('../databases/databases.js').db;
|
||||
var getHash = require('../utils/getHash.js');
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var fs = require('fs');
|
||||
var config = JSON.parse(fs.readFileSync('config.json'));
|
||||
var config = require('../config.js');
|
||||
|
||||
var databases = require('../databases/databases.js');
|
||||
var db = databases.db;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
|
||||
var fs = require('fs');
|
||||
var config = JSON.parse(fs.readFileSync('config.json'));
|
||||
var config = require('../config.js');
|
||||
|
||||
var db = require('../databases/databases.js').db;
|
||||
var getHash = require('../utils/getHash.js');
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
var fs = require('fs');
|
||||
var config = JSON.parse(fs.readFileSync('config.json'));
|
||||
var config = require('../config.js');
|
||||
|
||||
var databases = require('../databases/databases.js');
|
||||
var db = databases.db;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
var fs = require('fs');
|
||||
var config = JSON.parse(fs.readFileSync('config.json'));
|
||||
var config = require('../config.js');
|
||||
|
||||
var databases = require('../databases/databases.js');
|
||||
var db = databases.db;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
var fs = require('fs');
|
||||
var config = JSON.parse(fs.readFileSync('config.json'));
|
||||
var config = require('../config.js');
|
||||
|
||||
var getHash = require('../utils/getHash.js');
|
||||
var getIP = require('../utils/getIP.js');
|
||||
@@ -99,6 +99,7 @@ module.exports = async function voteOnSponsorTime(req, res) {
|
||||
err && console.log(err);
|
||||
return;
|
||||
}
|
||||
console.log(config.test);
|
||||
|
||||
request.post(config.discordReportChannelWebhookURL, {
|
||||
json: {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
var crypto = require('crypto');
|
||||
|
||||
module.exports = function (value, times=5000) {
|
||||
if (times <= 0) return "";
|
||||
|
||||
for (let i = 0; i < times; i++) {
|
||||
let hashCreator = crypto.createHash('sha256');
|
||||
value = hashCreator.update(value).digest('hex');
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
var fs = require('fs');
|
||||
var config = JSON.parse(fs.readFileSync('config.json'));
|
||||
var config = require('../config.js');
|
||||
|
||||
// YouTube API
|
||||
const YouTubeAPI = require("youtube-api");
|
||||
|
||||
35
test.js
Normal file
35
test.js
Normal file
@@ -0,0 +1,35 @@
|
||||
var Mocha = require('mocha'),
|
||||
fs = require('fs'),
|
||||
path = require('path');
|
||||
|
||||
var createServer = require('./src/app.js');
|
||||
var createMockServer = require('./test/mocks.js');
|
||||
|
||||
// Instantiate a Mocha instance.
|
||||
var mocha = new Mocha();
|
||||
|
||||
var testDir = './test/cases'
|
||||
|
||||
// Add each .js file to the mocha instance
|
||||
fs.readdirSync(testDir).filter(function(file) {
|
||||
// Only keep the .js files
|
||||
return file.substr(-3) === '.js';
|
||||
|
||||
}).forEach(function(file) {
|
||||
mocha.addFile(
|
||||
path.join(testDir, file)
|
||||
);
|
||||
});
|
||||
|
||||
var mockServer = createMockServer(() => {
|
||||
console.log("Started mock HTTP Server");
|
||||
var server = createServer(() => {
|
||||
console.log("Started main HTTP server");
|
||||
// Run the tests.
|
||||
mocha.run(function(failures) {
|
||||
mockServer.close();
|
||||
server.close();
|
||||
process.exitCode = failures ? 1 : 0; // exit with non-zero status if there were failures
|
||||
});
|
||||
});
|
||||
});
|
||||
17
test.json
Normal file
17
test.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"port": 8080,
|
||||
"mockPort": 8081,
|
||||
"globalSalt": "testSalt",
|
||||
"adminUserID": "testUserId",
|
||||
"youtubeAPIKey": "",
|
||||
"discordReportChannelWebhookURL": "http://127.0.0.1:8081/ReportChannelWebhook",
|
||||
"discordFirstTimeSubmissionsWebhookURL": "http://127.0.0.1:8081/FirstTimeSubmissionsWebhook",
|
||||
"behindProxy": true,
|
||||
"db": "./test/databases/sponsorTimes.db",
|
||||
"privateDB": "./test/databases/private.db",
|
||||
"createDatabaseIfNotExist": true,
|
||||
"dbSchema": "./test/databases/_sponsorTimes.db.sql",
|
||||
"privateDBSchema": "./test/databases/_private.db.sql",
|
||||
"mode": "development",
|
||||
"readOnly": false
|
||||
}
|
||||
29
test/cases/getHash.js
Normal file
29
test/cases/getHash.js
Normal file
@@ -0,0 +1,29 @@
|
||||
var getHash = require('../../src/utils/getHash.js');
|
||||
|
||||
var assert = require('assert');
|
||||
describe('getHash', () => {
|
||||
it('Should not output the input string', () => {
|
||||
assert(getHash("test") !== "test");
|
||||
assert(getHash("test", -1) !== "test");
|
||||
assert(getHash("test", 0) !== "test");
|
||||
assert(getHash("test", null) !== "test");
|
||||
});
|
||||
|
||||
it('Should return a hashed value', () => {
|
||||
assert.equal(getHash("test"), "2f327ef967ade1ebf4319163f7debbda9cc17bb0c8c834b00b30ca1cf1c256ee");
|
||||
});
|
||||
|
||||
it ('Should take a variable number of passes', () => {
|
||||
assert.equal(getHash("test", 1), "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08");
|
||||
assert.equal(getHash("test", 2), "7b3d979ca8330a94fa7e9e1b466d8b99e0bcdea1ec90596c0dcc8d7ef6b4300c");
|
||||
assert.equal(getHash("test", 3), "5b24f7aa99f1e1da5698a4f91ae0f4b45651a1b625c61ed669dd25ff5b937972");
|
||||
});
|
||||
|
||||
it ('Should default to 5000 passes', () => {
|
||||
assert.equal(getHash("test"), getHash("test", 5000));
|
||||
});
|
||||
|
||||
it ('Should not take a negative number of passes', () => {
|
||||
assert.equal(getHash("test", -1), "");
|
||||
});
|
||||
});
|
||||
22
test/databases/_private.db.sql
Normal file
22
test/databases/_private.db.sql
Normal file
@@ -0,0 +1,22 @@
|
||||
BEGIN TRANSACTION;
|
||||
DROP TABLE "shadowBannedUsers";
|
||||
DROP TABLE "votes";
|
||||
DROP TABLE "sponsorTimes";
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "shadowBannedUsers" (
|
||||
"userID" TEXT NOT NULL
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS "votes" (
|
||||
"UUID" TEXT NOT NULL,
|
||||
"userID" INTEGER NOT NULL,
|
||||
"hashedIP" INTEGER NOT NULL,
|
||||
"type" INTEGER NOT NULL
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS "sponsorTimes" (
|
||||
"videoID" TEXT NOT NULL,
|
||||
"hashedIP" TEXT NOT NULL,
|
||||
"timeSubmitted" INTEGER NOT NULL
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS sponsorTimes_hashedIP on sponsorTimes(hashedIP);
|
||||
CREATE INDEX IF NOT EXISTS votes_userID on votes(UUID);
|
||||
COMMIT;
|
||||
26
test/databases/_sponsorTimes.db.sql
Normal file
26
test/databases/_sponsorTimes.db.sql
Normal file
@@ -0,0 +1,26 @@
|
||||
BEGIN TRANSACTION;
|
||||
DROP TABLE "vipUsers";
|
||||
DROP TABLE "sponsorTimes";
|
||||
DROP TABLE "userNames";
|
||||
|
||||
CREATE TABLE IF NOT EXISTS "vipUsers" (
|
||||
"userID" TEXT NOT NULL
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS "sponsorTimes" (
|
||||
"videoID" TEXT NOT NULL,
|
||||
"startTime" REAL NOT NULL,
|
||||
"endTime" REAL NOT NULL,
|
||||
"votes" INTEGER NOT NULL,
|
||||
"UUID" TEXT NOT NULL UNIQUE,
|
||||
"userID" TEXT NOT NULL,
|
||||
"timeSubmitted" INTEGER NOT NULL,
|
||||
"views" INTEGER NOT NULL,
|
||||
"shadowHidden" INTEGER NOT NULL
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS "userNames" (
|
||||
"userID" TEXT NOT NULL,
|
||||
"userName" TEXT NOT NULL
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS sponsorTimes_videoID on sponsorTimes(videoID);
|
||||
CREATE INDEX IF NOT EXISTS sponsorTimes_UUID on sponsorTimes(UUID);
|
||||
COMMIT;
|
||||
BIN
test/databases/private.db
Normal file
BIN
test/databases/private.db
Normal file
Binary file not shown.
BIN
test/databases/sponsorTimes.db
Normal file
BIN
test/databases/sponsorTimes.db
Normal file
Binary file not shown.
16
test/mocks.js
Normal file
16
test/mocks.js
Normal file
@@ -0,0 +1,16 @@
|
||||
var express = require('express');
|
||||
var app = express();
|
||||
|
||||
var config = require('../src/config.js');
|
||||
|
||||
app.post('/ReportChannelWebhook', (req, res) => {
|
||||
res.status(200);
|
||||
});
|
||||
|
||||
app.post('/FirstTimeSubmissionsWebhook', (req, res) => {
|
||||
res.status(200);
|
||||
});
|
||||
|
||||
module.exports = function createMockServer(callback) {
|
||||
return app.listen(config.mockPort, callback);
|
||||
}
|
||||
Reference in New Issue
Block a user