feat: Implement comments, notifications, and custom emojis with new API routes, UI components, and database migrations.
This commit is contained in:
22
debug/init_comments.mjs
Normal file
22
debug/init_comments.mjs
Normal file
@@ -0,0 +1,22 @@
|
||||
import db from "../src/inc/sql.mjs";
|
||||
import { promises as fs } from "fs";
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
const migration = await fs.readFile("./migration_comments.sql", "utf-8");
|
||||
console.log("Applying migration...");
|
||||
// Split by semicolon to handle multiple statements if the driver requires it,
|
||||
// but postgres.js usually handles simple files well or we can execute as one block
|
||||
// if it's just DDL. However, postgres.js template literal usually prefers single statements
|
||||
// or we can use `db.file` if available, or just execute the string.
|
||||
|
||||
// Simple approach: execute the whole string
|
||||
await db.unsafe(migration);
|
||||
|
||||
console.log("Migration applied successfully.");
|
||||
process.exit(0);
|
||||
} catch (e) {
|
||||
console.error("Migration failed:", e);
|
||||
process.exit(1);
|
||||
}
|
||||
})();
|
||||
34
debug/init_emojis.mjs
Normal file
34
debug/init_emojis.mjs
Normal file
@@ -0,0 +1,34 @@
|
||||
import db from "../src/inc/sql.mjs";
|
||||
|
||||
async function run() {
|
||||
try {
|
||||
console.log("Creating custom_emojis table...");
|
||||
|
||||
await db`
|
||||
CREATE TABLE IF NOT EXISTS custom_emojis (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name TEXT NOT NULL UNIQUE,
|
||||
url TEXT NOT NULL,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
||||
)
|
||||
`;
|
||||
|
||||
// Seed with existing default emojis if table is empty
|
||||
const count = await db`SELECT count(*) FROM custom_emojis`;
|
||||
if (count[0].count == 0) {
|
||||
console.log("Seeding default emojis...");
|
||||
await db`
|
||||
INSERT INTO custom_emojis (name, url) VALUES
|
||||
('f0ck', '/s/img/f0ck.png')
|
||||
`;
|
||||
}
|
||||
|
||||
console.log("Done.");
|
||||
process.exit(0);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
run();
|
||||
106
debug/verify_comments.mjs
Normal file
106
debug/verify_comments.mjs
Normal file
@@ -0,0 +1,106 @@
|
||||
import db from "../src/inc/sql.mjs";
|
||||
import http from "http";
|
||||
import crypto from "crypto";
|
||||
|
||||
const HOST = "localhost";
|
||||
const PORT = 3000;
|
||||
import { readFile } from "fs/promises";
|
||||
const cfg = JSON.parse(await readFile("../config.json", "utf8"));
|
||||
const serverPort = cfg.websrv.port;
|
||||
|
||||
const runTest = async () => {
|
||||
// 1. Setup Data
|
||||
console.log("Setting up test data...");
|
||||
const user = await db`SELECT id FROM "user" LIMIT 1`;
|
||||
const item = await db`SELECT id FROM "items" LIMIT 1`;
|
||||
|
||||
if (!user.length || !item.length) {
|
||||
console.error("No user or item found.");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const userId = user[0].id;
|
||||
const itemId = item[0].id;
|
||||
|
||||
// Create session
|
||||
const sessionKey = "testsession_" + Date.now();
|
||||
const sessionHash = crypto.createHash('md5').update(sessionKey).digest("hex");
|
||||
|
||||
await db`DELETE FROM user_sessions WHERE user_id = ${userId}`; // Clear old sessions for clean test
|
||||
await db`INSERT INTO user_sessions (user_id, session, browser, created_at, last_used, last_action)
|
||||
VALUES (${userId}, ${sessionHash}, 'test-bot', ${Math.floor(Date.now() / 1000)}, ${Math.floor(Date.now() / 1000)}, 'test')`;
|
||||
|
||||
console.log(`User: ${userId}, Item: ${itemId}, Session: ${sessionKey}`);
|
||||
|
||||
// Helper for requests
|
||||
const request = (method, path, body = null, cookie = null) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const options = {
|
||||
hostname: HOST,
|
||||
port: serverPort,
|
||||
path: path,
|
||||
method: method,
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Cookie': cookie ? `session=${cookie}` : ''
|
||||
}
|
||||
};
|
||||
|
||||
const req = http.request(options, (res) => {
|
||||
let data = '';
|
||||
res.on('data', chunk => data += chunk);
|
||||
res.on('end', () => resolve({ statusCode: res.statusCode, body: data }));
|
||||
});
|
||||
|
||||
req.on('error', reject);
|
||||
if (body) req.write(JSON.stringify(body));
|
||||
req.end();
|
||||
});
|
||||
};
|
||||
|
||||
// 2. Test GET (Empty)
|
||||
console.log("Testing GET /api/comments/" + itemId);
|
||||
let res = await request('GET', `/api/comments/${itemId}`);
|
||||
console.log("GET Response:", res.body);
|
||||
let json = JSON.parse(res.body);
|
||||
if (!json.success) throw new Error("GET failed");
|
||||
|
||||
// 3. Test POST
|
||||
console.log("Testing POST /api/comments");
|
||||
res = await request('POST', '/api/comments', {
|
||||
item_id: itemId,
|
||||
content: "Hello World from Test Bot"
|
||||
}, sessionKey);
|
||||
console.log("POST Response:", res.body);
|
||||
json = JSON.parse(res.body);
|
||||
if (!json.success) throw new Error("POST failed");
|
||||
const commentId = json.comment.id;
|
||||
|
||||
// 4. Test GET (With comment)
|
||||
console.log("Testing GET /api/comments/" + itemId);
|
||||
res = await request('GET', `/api/comments/${itemId}`);
|
||||
json = JSON.parse(res.body);
|
||||
if (json.comments.length === 0) throw new Error("Comment not found");
|
||||
console.log("Found comments:", json.comments.length);
|
||||
|
||||
// 5. Test Subscribe
|
||||
console.log("Testing POST /api/subscribe/" + itemId);
|
||||
res = await request('POST', `/api/subscribe/${itemId}`, {}, sessionKey);
|
||||
console.log("Subscribe Response:", res.body);
|
||||
json = JSON.parse(res.body);
|
||||
if (!json.success) throw new Error("Subscribe failed");
|
||||
if (!json.subscribed) throw new Error("Expected subscribed=true");
|
||||
|
||||
console.log("Testing Unsubscribe...");
|
||||
res = await request('POST', `/api/subscribe/${itemId}`, {}, sessionKey);
|
||||
json = JSON.parse(res.body);
|
||||
if (json.subscribed) throw new Error("Expected subscribed=false");
|
||||
|
||||
console.log("ALL TESTS PASSED");
|
||||
process.exit(0);
|
||||
};
|
||||
|
||||
runTest().catch(e => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
});
|
||||
62
debug/verify_db.mjs
Normal file
62
debug/verify_db.mjs
Normal file
@@ -0,0 +1,62 @@
|
||||
import db from "../src/inc/sql.mjs";
|
||||
|
||||
const runTest = async () => {
|
||||
console.log("Verifying Database Schema...");
|
||||
|
||||
// 1. Check Tables
|
||||
try {
|
||||
await db`SELECT 1 FROM comments LIMIT 1`;
|
||||
console.log("✔ Table 'comments' exists.");
|
||||
} catch (e) {
|
||||
console.error("✘ Table 'comments' missing.");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
await db`SELECT 1 FROM comment_subscriptions LIMIT 1`;
|
||||
console.log("✔ Table 'comment_subscriptions' exists.");
|
||||
} catch (e) {
|
||||
console.error("✘ Table 'comment_subscriptions' missing.");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// 2. Insert Test Data
|
||||
console.log("Testing Insert...");
|
||||
const user = await db`SELECT id FROM "user" LIMIT 1`;
|
||||
const item = await db`SELECT id FROM "items" LIMIT 1`;
|
||||
|
||||
if (!user.length || !item.length) {
|
||||
console.log("⚠ No user/item to test insert. Skipping.");
|
||||
} else {
|
||||
const userId = user[0].id;
|
||||
const itemId = item[0].id;
|
||||
|
||||
const comment = await db`
|
||||
INSERT INTO comments (item_id, user_id, content)
|
||||
VALUES (${itemId}, ${userId}, 'Test Comment DB Verify')
|
||||
RETURNING id
|
||||
`;
|
||||
console.log("✔ Inserted comment ID:", comment[0].id);
|
||||
|
||||
const fetch = await db`SELECT content FROM comments WHERE id = ${comment[0].id}`;
|
||||
if (fetch[0].content === 'Test Comment DB Verify') {
|
||||
console.log("✔ Verified content.");
|
||||
} else {
|
||||
console.error("✘ Content mismatch.");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
await db`DELETE FROM comments WHERE id = ${comment[0].id}`;
|
||||
}
|
||||
|
||||
console.log("DB Schema Verification Passed.");
|
||||
|
||||
// 3. Optional: subscription test
|
||||
await db`INSERT INTO comment_subscriptions (user_id, item_id) VALUES (${user[0].id}, ${item[0].id}) ON CONFLICT DO NOTHING`;
|
||||
console.log("✔ Subscription table write access confirmed.");
|
||||
|
||||
process.exit(0);
|
||||
};
|
||||
|
||||
runTest().catch(console.error);
|
||||
Reference in New Issue
Block a user