updated webclient setttings

This commit is contained in:
2026-08-15 21:49:25 +01:00
parent 15678c1b6e
commit f60dbcc6b0
41 changed files with 3147 additions and 770 deletions
+140 -3
View File
@@ -20,7 +20,7 @@ func TestWebmailRulesAddAndRemove(t *testing.T) {
cookie := webmailLoginSession(t, app, mailboxID)
form := "priority=0&condition_field=subject&condition_op=contains&condition_value=newsletter&action=move_to_folder&action_value=Newsletters"
req := httptest.NewRequest(http.MethodPost, MailboxPrefix+"/rules/add", strings.NewReader(form))
req := httptest.NewRequest(http.MethodPost, MailboxPrefix+"/rules/save", strings.NewReader(form))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.AddCookie(cookie)
rec := httptest.NewRecorder()
@@ -80,7 +80,7 @@ func TestWebmailRulesAddMultiCondition(t *testing.T) {
"action": {"mark_as_spam"},
"action_value": {""},
}
req := httptest.NewRequest(http.MethodPost, MailboxPrefix+"/rules/add", strings.NewReader(form.Encode()))
req := httptest.NewRequest(http.MethodPost, MailboxPrefix+"/rules/save", strings.NewReader(form.Encode()))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.AddCookie(cookie)
rec := httptest.NewRecorder()
@@ -113,7 +113,7 @@ func TestWebmailRulesRejectsInvalidInput(t *testing.T) {
// move_to_folder with no destination folder named.
form := "priority=0&condition_field=subject&condition_op=contains&condition_value=x&action=move_to_folder&action_value="
req := httptest.NewRequest(http.MethodPost, MailboxPrefix+"/rules/add", strings.NewReader(form))
req := httptest.NewRequest(http.MethodPost, MailboxPrefix+"/rules/save", strings.NewReader(form))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.AddCookie(cookie)
rec := httptest.NewRecorder()
@@ -127,6 +127,143 @@ func TestWebmailRulesRejectsInvalidInput(t *testing.T) {
}
}
// TestWebmailRulesEditUpdatesInPlace confirms submitting the builder form with an
// existing rule_id updates that rule (via UpdateRuleMulti) rather than creating a
// second one — the same form/endpoint (/rules/save) serves both add and edit.
func TestWebmailRulesEditUpdatesInPlace(t *testing.T) {
app := newTestApp(t)
mux := app.Mux()
domains, _ := app.DB.ListDomains()
mailboxID := createTestMailboxWithPassword(t, app, "ruler4@example.com", domains[0].ID, "ruler-password-1!")
cookie := webmailLoginSession(t, app, mailboxID)
ruleID, err := app.DB.CreateRule(mailboxID, 0, "subject", "contains", "old", "delete", "")
if err != nil {
t.Fatal(err)
}
form := url.Values{
"rule_id": {strconv.FormatInt(ruleID, 10)},
"name": {"Renamed"},
"priority": {"5"},
"match_type": {"all"},
"condition_field": {"subject"},
"condition_op": {"contains"},
"condition_value": {"new"},
"action": {"mark_read"},
"action_value": {""},
}
req := httptest.NewRequest(http.MethodPost, MailboxPrefix+"/rules/save", strings.NewReader(form.Encode()))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.AddCookie(cookie)
rec := httptest.NewRecorder()
mux.ServeHTTP(rec, req)
if rec.Code != http.StatusFound {
t.Fatalf("edit rule: status=%d body=%s", rec.Code, rec.Body.String())
}
rules, err := app.DB.ListRulesForMailbox(mailboxID)
if err != nil || len(rules) != 1 {
t.Fatalf("expected still exactly 1 rule (updated, not duplicated), got %d (err=%v)", len(rules), err)
}
if rules[0].ID != ruleID || rules[0].Name != "Renamed" || rules[0].Action != "mark_read" || rules[0].ConditionValue != "new" {
t.Errorf("unexpected rule after edit: %+v", rules[0])
}
}
// TestWebmailRulesEditPersistsEnabledCheckbox reproduces a live bug: the edit
// builder's "Enabled" checkbox visually reflected a disabled rule's state but
// submitting an edit never actually persisted it — UpdateRuleMulti's column list
// never included is_active, so editing (with or without touching the checkbox) never
// changed enabled/disabled state at all, only the separate toggle button did.
func TestWebmailRulesEditPersistsEnabledCheckbox(t *testing.T) {
app := newTestApp(t)
mux := app.Mux()
domains, _ := app.DB.ListDomains()
mailboxID := createTestMailboxWithPassword(t, app, "ruler6@example.com", domains[0].ID, "ruler-password-1!")
cookie := webmailLoginSession(t, app, mailboxID)
ruleID, err := app.DB.CreateRule(mailboxID, 0, "subject", "contains", "x", "delete", "")
if err != nil {
t.Fatal(err)
}
if err := app.DB.SetRuleActive(ruleID, mailboxID, false); err != nil {
t.Fatal(err)
}
// Edit the disabled rule with the "Enabled" checkbox checked (is_active=1 present
// in the form) — should re-enable it.
form := url.Values{
"rule_id": {strconv.FormatInt(ruleID, 10)}, "priority": {"0"}, "match_type": {"all"},
"condition_field": {"subject"}, "condition_op": {"contains"}, "condition_value": {"x"},
"action": {"delete"}, "action_value": {""}, "is_active": {"1"},
}
req := httptest.NewRequest(http.MethodPost, MailboxPrefix+"/rules/save", strings.NewReader(form.Encode()))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.AddCookie(cookie)
rec := httptest.NewRecorder()
mux.ServeHTTP(rec, req)
if rec.Code != http.StatusFound {
t.Fatalf("edit rule: status=%d", rec.Code)
}
rule, err := app.DB.GetRuleByID(mailboxID, ruleID)
if err != nil || rule == nil || !rule.IsActive {
t.Fatalf("expected rule re-enabled via edit form's checkbox, got %+v (err=%v)", rule, err)
}
// Edit again with the checkbox omitted entirely (as a real unchecked <input
// type=checkbox> submits) — should disable it.
form.Del("is_active")
req = httptest.NewRequest(http.MethodPost, MailboxPrefix+"/rules/save", strings.NewReader(form.Encode()))
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.AddCookie(cookie)
rec = httptest.NewRecorder()
mux.ServeHTTP(rec, req)
if rec.Code != http.StatusFound {
t.Fatalf("edit rule: status=%d", rec.Code)
}
rule, err = app.DB.GetRuleByID(mailboxID, ruleID)
if err != nil || rule == nil || rule.IsActive {
t.Fatalf("expected rule disabled via edit form's omitted checkbox, got %+v (err=%v)", rule, err)
}
}
// TestWebmailRulesToggleFlipsActive confirms the quick enable/disable toggle button
// flips is_active without needing the full edit form.
func TestWebmailRulesToggleFlipsActive(t *testing.T) {
app := newTestApp(t)
mux := app.Mux()
domains, _ := app.DB.ListDomains()
mailboxID := createTestMailboxWithPassword(t, app, "ruler5@example.com", domains[0].ID, "ruler-password-1!")
cookie := webmailLoginSession(t, app, mailboxID)
ruleID, err := app.DB.CreateRule(mailboxID, 0, "subject", "contains", "x", "delete", "")
if err != nil {
t.Fatal(err)
}
toggle := func() {
req := httptest.NewRequest(http.MethodPost, MailboxPrefix+"/rules/"+strconv.FormatInt(ruleID, 10)+"/toggle", nil)
req.AddCookie(cookie)
rec := httptest.NewRecorder()
mux.ServeHTTP(rec, req)
if rec.Code != http.StatusFound {
t.Fatalf("toggle: status=%d", rec.Code)
}
}
toggle()
rules, _ := app.DB.ListRulesForMailbox(mailboxID)
if rules[0].IsActive {
t.Fatalf("expected rule disabled after first toggle, got IsActive=true")
}
toggle()
rules, _ = app.DB.ListRulesForMailbox(mailboxID)
if !rules[0].IsActive {
t.Fatalf("expected rule re-enabled after second toggle, got IsActive=false")
}
}
// TestWebmailRulesScopedToOwnMailbox confirms one mailbox owner can't remove another
// mailbox's rule by guessing its ID.
func TestWebmailRulesScopedToOwnMailbox(t *testing.T) {