v0.321.0: FileBrowser's stale password and its own banners; one backup section on the Data tab; install address of an installed app
gates / gates (push) Successful in 43s
gates / gates (push) Successful in 43s
R-1101: the change-it line is gone for FileBrowser; in the generated state the page asks FileBrowser whether
the stored password still logs in (only its own 401/403 counts) and, refused, says so and offers the
new-password press. The rendered FileBrowser config switches off its update notice and its Install-app
prompt. The Data tab's backup part is one section in plain words (no off-drive, no PBS); the export
password eye is a text button. R-1095: /apps/{slug}/install of an installed app 302s to its settings tab.
Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -352,3 +352,91 @@ func TestFileBrowserResetEndpoint_Refusals(t *testing.T) {
|
||||
t.Errorf("reset in the generated state = %d, want 409", c)
|
||||
}
|
||||
}
|
||||
|
||||
// R-1101 (v0.321.0): FileBrowser refuses the stored password → a sentence and the new-password press, no eye, and no
|
||||
// „change it after the first login" line (which is how it went stale).
|
||||
// RED-PROOF (2026-10-16, REPORT): with the `s.fbStoredPasswordRefused()` branch removed from appCommonData, this failed
|
||||
// at „stale: the page still offers the reveal".
|
||||
func TestFileBrowserLogin_StoredPasswordRefusedOffersReset(t *testing.T) {
|
||||
s := lfHarness(t, settings.FileBrowserAdminGenerated, lfDriveA)
|
||||
s.fbStoredRefused = func() bool { return true }
|
||||
_, html, _ := lfGet(t, s, "/apps/filebrowser")
|
||||
if strings.Contains(html, `id="initcred-reveal"`) {
|
||||
t.Fatal("stale: the page still offers the reveal of a password FileBrowser refuses")
|
||||
}
|
||||
if !strings.Contains(html, `data-fb-stale="1"`) || !strings.Contains(html, `data-fb-reset="1"`) {
|
||||
t.Fatal("stale: no sentence or no new-password button")
|
||||
}
|
||||
s.fbStoredRefused = func() bool { return false }
|
||||
_, ok, _ := lfGet(t, s, "/apps/filebrowser")
|
||||
if !strings.Contains(ok, `id="initcred-reveal"`) || strings.Contains(ok, `data-fb-stale`) || strings.Contains(ok, `data-fb-reset`) {
|
||||
t.Fatal("a stored password FileBrowser accepts must show the reveal and no reset")
|
||||
}
|
||||
// Positive control first: the line exists in the bundle; then: it is not on the FileBrowser page.
|
||||
if !strings.Contains(s.msgLang("hu", "app_info.az_elso_bejelentkezes_utan_azonnal"), "hagyd figyelmen") {
|
||||
t.Fatal("control: the change-it line no longer carries the fragment this test looks for")
|
||||
}
|
||||
if strings.Contains(ok, "hagyd figyelmen") {
|
||||
t.Fatal("FileBrowser still says to change the password after the first login (R-1101)")
|
||||
}
|
||||
}
|
||||
|
||||
// ── v0.321.0 — the Data tab's backup part (Part 4) and the install address (R-1095) ────────────────────────────────
|
||||
|
||||
var lfOffDriveOrPBS = regexp.MustCompile(`(?i)off-drive|\bPBS\b`)
|
||||
|
||||
// The Data tab has ONE „Biztonsagi mentes" section, with no „off-drive" and no „PBS" in either language.
|
||||
// RED-PROOF (2026-10-16, REPORT): with the old `tier2_config.a_2_mentes_egy_masik` text put back in hu.json, this
|
||||
// failed at „hu: off-drive/PBS on the Data tab"; with the second <div class="app-section"> put back, at „2 sections".
|
||||
func TestAppData_OneBackupSection(t *testing.T) {
|
||||
if !lfOffDriveOrPBS.MatchString("a teljes rendszermentés/PBS — off-drive") {
|
||||
t.Fatal("control: the matcher does not find the words it looks for")
|
||||
}
|
||||
s := i18nTestServer(t)
|
||||
var c i18nCase
|
||||
for _, x := range i18nCases() {
|
||||
if x.name == "app_data_deployed" {
|
||||
c = x
|
||||
}
|
||||
}
|
||||
if c.name == "" {
|
||||
t.Fatal("control: the parity case app_data_deployed (a data tab with the 2nd copy) is gone")
|
||||
}
|
||||
for _, lang := range []string{"hu", "en"} {
|
||||
html := renderI18nCase(t, s, lang, c)
|
||||
if n := strings.Count(html, `data-backup-section="1"`); n != 1 {
|
||||
t.Errorf("%s: %d backup sections, want 1", lang, n)
|
||||
}
|
||||
if !strings.Contains(html, `data-backup-row="nightly"`) || !strings.Contains(html, `data-backup-row="second"`) ||
|
||||
!strings.Contains(html, `data-second-backup-form="1"`) {
|
||||
t.Errorf("%s: the nightly row, the 2nd-copy row or its form is missing", lang)
|
||||
}
|
||||
if m := lfOffDriveOrPBS.FindString(html); m != "" {
|
||||
t.Errorf("%s: off-drive/PBS on the Data tab (%q)", lang, m)
|
||||
}
|
||||
if strings.Contains(html, "👁") || strings.Contains(html, "\U0001F441") {
|
||||
t.Errorf("%s: the export password eye is still an emoji", lang)
|
||||
}
|
||||
if !strings.Contains(html, `id="exportPwToggle" aria-label=`) {
|
||||
t.Errorf("%s: the export password toggle has no aria-label", lang)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// R-1095: an INSTALLED app's /install answers 302 to its settings tab (GET only); a not-installed app keeps its form.
|
||||
// RED-PROOF (2026-10-16, REPORT): with the Deployed redirect removed from appInstallPageHandler, this failed at
|
||||
// „installed: 200".
|
||||
func TestInstallAddress_InstalledRedirectsToSettings(t *testing.T) {
|
||||
s := tuningHarness(t, tuningEnv())
|
||||
if c, _, loc := lfGet(t, s, "/apps/calibre-web/install"); c != http.StatusFound || loc != "/apps/calibre-web/settings" {
|
||||
t.Fatalf("installed: %d → %q, want 302 → /apps/calibre-web/settings", c, loc)
|
||||
}
|
||||
if c, html, _ := lfGet(t, s, "/apps/calibre-new/install"); c != http.StatusOK || !strings.Contains(html, "deploy-form") {
|
||||
t.Fatalf("not installed: %d, the install form must still render", c)
|
||||
}
|
||||
w := httptest.NewRecorder()
|
||||
s.ServeHTTP(w, httptest.NewRequest(http.MethodPost, "/apps/calibre-web/install", nil))
|
||||
if w.Code == http.StatusFound && w.Header().Get("Location") == "/apps/calibre-web/settings" {
|
||||
t.Fatal("a POST to /install was redirected — the redirect is for reads only")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user