mirror of
https://github.com/tdurieux/anonymous_github.git
synced 2026-10-19 22:27:20 +02:00
fix: keep settings links on profile and fill the project table (#887)
This commit is contained in:
1 parent
c67d8ec3b2
commit
7319a5a744
10 files changed
+152
-25
No files matched your search
@@ -166,7 +166,8 @@ describe("owner access notifications", () => {
|
||||
describe("owner email settings", () => {
|
||||
const utils = require("../src/server/routes/route-utils");
|
||||
const router = require("../src/server/routes/github-app").githubAppRouter;
|
||||
const endpoint = router.stack.find(layer => layer.route?.path === "/connections/email").route.stack[0].handle;
|
||||
const endpoint = router.stack.find(layer => layer.route?.path === "/connections/email" && layer.route.methods.post).route.stack[0].handle;
|
||||
const readEmail = router.stack.find(layer => layer.route?.path === "/connections/email" && layer.route.methods.get).route.stack[0].handle;
|
||||
const csrf = router.stack.find(layer => !layer.route && layer.handle.toString().includes("x-csrf-token")).handle;
|
||||
let oldUser, oldUpdate, writes;
|
||||
beforeEach(() => {
|
||||
@@ -177,6 +178,17 @@ describe("owner email settings", () => {
|
||||
});
|
||||
afterEach(() => { utils.getUser = oldUser; User.updateOne = oldUpdate; });
|
||||
const response = () => ({ statusCode: 200, status(code) { this.statusCode = code; return this; }, json(body) { this.body = body; } });
|
||||
for (const email of ["", "primary@example.com"]) it(`loads the account email and persists its save token (${email || "no address"})`, async () => {
|
||||
utils.getUser = async () => ({ id: "signed-in-owner", model: { emails: [], notificationEmail: email } });
|
||||
let saved = false;
|
||||
const req = { sessionID: "profile-session", session: { save: done => { saved = true; done(); } } };
|
||||
const res = response();
|
||||
await readEmail(req, res);
|
||||
expect(saved).to.equal(true);
|
||||
expect(res.body).to.deep.equal({ notificationEmail: email, csrf: req.session.githubConnectionCSRF });
|
||||
expect(res.body.csrf).to.be.a("string").with.length(64);
|
||||
expect(writes).to.have.length(0);
|
||||
});
|
||||
it("updates only the signed-in owner's address", async () => {
|
||||
const res = response();
|
||||
await endpoint({ body: { email: " owner@example.com ", ownerId: "someone-else" } }, res);
|
||||
|
||||
+58
-1
@@ -17,7 +17,8 @@ async function browser(route = "/", overrides = {}, storage = {}) {
|
||||
errors.push(error.message);
|
||||
});
|
||||
virtualConsole.on("error", error => errors.push(error?.message || String(error)));
|
||||
const dom = new JSDOM('<!doctype html><html><head></head><body><div id="app"></div></body></html>', {
|
||||
const base = fs.readFileSync(path.join(publicDir, "index.html"), "utf8").match(/<base\b[^>]*>/i)?.[0] || "";
|
||||
const dom = new JSDOM(`<!doctype html><html><head>${base}</head><body><div id="app"></div></body></html>`, {
|
||||
resources: {
|
||||
interceptors: [requestInterceptor(request => {
|
||||
const url = request.url;
|
||||
@@ -80,6 +81,62 @@ describe("Vue 3 UI", function () {
|
||||
let ui;
|
||||
afterEach(() => ui?.close());
|
||||
|
||||
it("keeps native settings section links on the profile page", async () => {
|
||||
ui = await browser("/profile", { "/api/user": { username: "owner" } });
|
||||
const account = ui.window.document.querySelector('.paper-settings-toc a[href="#settings-account"]');
|
||||
expect(account.href).to.equal("http://localhost/profile#settings-account");
|
||||
account.click();
|
||||
await delay(30);
|
||||
expect(ui.window.location.pathname).to.equal("/profile");
|
||||
expect(ui.window.location.hash).to.equal("#settings-account");
|
||||
expect(ui.window.document.querySelector("#settings-account")).not.to.equal(null);
|
||||
expect(ui.errors).to.deep.equal([]);
|
||||
});
|
||||
|
||||
it("loads and saves account email separately from defaults with CSRF", async () => {
|
||||
ui = await browser("/profile", {
|
||||
"/api/user": { username: "owner" },
|
||||
"/github/connections/email": request => request.method === "POST"
|
||||
? { notificationEmail: request.payload.email.trim() }
|
||||
: { notificationEmail: "old@example.com", csrf: "profile-csrf" },
|
||||
});
|
||||
expect(ui.window.document.querySelector("#account-email").value).to.equal("old@example.com");
|
||||
await ui.input("#account-email", "new@example.com");
|
||||
ui.window.document.querySelector('.paper-account-email button[type="submit"]').click();
|
||||
await delay(30);
|
||||
const save = ui.requests.find(r => r.url.pathname === "/github/connections/email" && r.method === "POST");
|
||||
expect(save.payload).to.deep.equal({ email: "new@example.com" });
|
||||
expect(save.headers["X-CSRF-Token"]).to.equal("profile-csrf");
|
||||
expect(ui.requests.filter(r => r.url.pathname === "/api/user/default" && r.method === "POST")).to.have.length(0);
|
||||
expect(ui.window.document.querySelector(".paper-account-email").textContent).to.include("Email address saved.");
|
||||
expect(ui.errors).to.deep.equal([]);
|
||||
});
|
||||
|
||||
it("retries email loading and keeps failed edits while preventing duplicate saves", async () => {
|
||||
let failLoad = true, finishSave;
|
||||
ui = await browser("/profile", {
|
||||
"/api/user": { username: "owner" },
|
||||
"/github/connections/email": request => request.method === "POST"
|
||||
? new Promise(resolve => { finishSave = () => resolve({ __status: 503, body: {} }); })
|
||||
: failLoad ? { __status: 503, body: {} } : { notificationEmail: "", csrf: "profile-csrf" },
|
||||
});
|
||||
expect(ui.window.document.querySelector("#account-email").disabled).to.equal(true);
|
||||
failLoad = false;
|
||||
ui.window.document.querySelector('.paper-account-email button[type="button"]').click();
|
||||
await delay(30);
|
||||
await ui.input("#account-email", "owner+alerts@example.com");
|
||||
const form = ui.window.document.querySelector(".paper-account-email");
|
||||
form.dispatchEvent(new ui.window.Event("submit", { bubbles: true, cancelable: true }));
|
||||
form.dispatchEvent(new ui.window.Event("submit", { bubbles: true, cancelable: true }));
|
||||
await delay(10);
|
||||
expect(ui.requests.filter(r => r.url.pathname === "/github/connections/email" && r.method === "POST")).to.have.length(1);
|
||||
expect(ui.window.document.querySelector("#account-email").disabled).to.equal(true);
|
||||
finishSave(); await delay(30);
|
||||
expect(ui.window.document.querySelector("#account-email").value).to.equal("owner+alerts@example.com");
|
||||
expect(form.querySelector('[role="alert"]').textContent).to.include("Unable to save");
|
||||
expect(ui.errors).to.deep.equal([]);
|
||||
});
|
||||
|
||||
it("prompts owners without email and saves their alert address with CSRF", async () => {
|
||||
ui = await browser("/dashboard", {
|
||||
"/api/user": { username: "owner", notificationEmail: "", emailNotificationsEnabled: true, showEmailPrompt: true, emailPromptCSRF: "email-csrf" },
|
||||
|
||||
Reference in new issue
Block a user