package main import ( "archive/zip" "encoding/json" "os" "path/filepath" "strings" "testing" "time" ) // What the mesh installs, as the tools say it (novox/hq ADR 0316 ยง16): the version against the pin and the // newest published build, the policy, Owl against its pin; and the reminder test, visibly a test. func (f *fake) xpi(path, version string) { f.t.Helper() full := filepath.Join(f.Root, path) if err := os.MkdirAll(filepath.Dir(full), 0o755); err != nil { f.t.Fatal(err) } out, err := os.Create(full) if err != nil { f.t.Fatal(err) } w := zip.NewWriter(out) m, _ := w.Create("manifest.json") m.Write([]byte(`{"version": "` + version + `", "browser_specific_settings": {"gecko": {"id": "owl@beonex.com"}}}`)) w.Close() out.Close() } // placedByTheMesh is a node after the switch: the release, the policy and Owl's xpi in /opt/betterbird, and // the profile running Owl at the pin. func (f *fake) placedByTheMesh() { f.noPackage() f.write(appIni, "[App]\nVendor=Betterbird Project\nVersion=153.4.0\nBuildID=20260929222610\n") raw, err := os.ReadFile(filepath.Join("..", "..", "install", "distribution", "policies.json")) if err != nil { f.t.Fatal(err) } f.write(policyFile, string(raw)) f.xpi(owlFile, "1.5.6.1") f.write(profileDir+"/extensions.json", `{"addons":[{"id":"owl@beonex.com","version":"1.5.6.1","active":true,"location":"app-profile"}]}`) } func TestTheStatusSaysTheInstallationAgainstThePinTheNewestBuildThePolicyAndOwl(t *testing.T) { f := newFake(t) f.betterbird() f.placedByTheMesh() links(t, nil) publishedBuilds = func() (string, error) { return "blocklist,{}\nLinux,153,20261101000000\nLinux,140,20260829111240\n", nil } t.Cleanup(func() { publishedBuilds = func() (string, error) { return "", os.ErrDeadlineExceeded } }) s, err := f.Status() if err != nil { t.Fatal(err) } in := s.Installation if in.From != "the mesh" || in.Version != "153.4.0" || in.Newest != "20261101000000" || !in.Behind || !strings.HasPrefix(in.Policy, "placed:") || in.Owl == nil || in.Owl.Pinned != "1.5.6.1" || !in.Owl.AtThePin || !in.Owl.Active { t.Fatalf("%+v %+v", in, in.Owl) } c, err := f.Check() if err != nil { t.Fatal(err) } found := false for _, x := range c.Findings { found = found || strings.Contains(x.What, "behind the newest published build 20261101000000") } if !found { t.Fatalf("a release left behind is said: %+v", c.Findings) } } func TestTheCommunityPackageAPolicyThatIsNotTheModulesAndAnOwlOffItsPinAreSaid(t *testing.T) { f := newFake(t) f.betterbird() f.placedByTheMesh() links(t, nil) f.write(policyFile, `{"policies": {"ExtensionSettings": {"owl@beonex.com": {"installation_mode": "force_installed", "install_url": "https://vendor.example/owl.xpi", "updates_disabled": true}}}}`) f.write(profileDir+"/extensions.json", `{"addons":[{"id":"owl@beonex.com","version":"1.5.7","active":true,"location":"app-profile"}]}`) in := f.installation(filepath.Join(f.Root, profileDir)) if !strings.Contains(in.Policy, "DisableAppUpdate") || in.Owl.AtThePin || in.Owl.InProfile != "1.5.7" { t.Fatalf("%+v %+v", in, in.Owl) } // A newer Owl than the pin is a fact with the real remedy, never a finding to remove it. if !strings.Contains(in.Owl.Note, "move the module's pin") { t.Fatalf("%+v", in.Owl) } f.write(policyFile, `{"policies": {"DisableAppUpdate": true, "ExtensionSettings": {"owl@beonex.com": {"installation_mode": "force_installed", "install_url": "file:///opt/betterbird/owl/owl.xpi", "updates_disabled": true}}}}`) c, _ := f.Check() for _, x := range c.Findings { if strings.Contains(x.What, "Owl") { t.Errorf("a newer Owl is not a finding: %+v", x) } } f.write(profileDir+"/extensions.json", `{"addons":[{"id":"owl@beonex.com","version":"1.5.5","active":true,"location":"app-profile"}]}`) c, _ = f.Check() found := false for _, x := range c.Findings { found = found || (strings.Contains(x.What, "older than the mesh's pin") && strings.Contains(x.Do, "move the module's Owl pin")) } if !found { t.Fatalf("an older Owl is a finding whose remedy is the pin: %+v", c.Findings) } f.write(policyFile, `{"policies": {"DisableAppUpdate": true, "ExtensionSettings": {"owl@beonex.com": {"installation_mode": "force_installed", "install_url": "https://vendor.example/owl.xpi", "updates_disabled": true}}}}`) if in := f.installation(""); !strings.Contains(in.Policy, "not from the mesh's xpi") { t.Fatalf("%s", in.Policy) } f.answer = func(name string, args []string) Output { if name == "pacman" && args[0] == "-Q" { return Output{Stdout: "betterbird-bin 153.1.0esr-1\n"} } return Output{} } in = f.installation("") if !strings.HasPrefix(in.From, "the community package betterbird-bin 153.1.0esr-1") || !strings.Contains(in.From, "operator") { t.Fatalf("%s", in.From) } raw, _ := json.Marshal(in) if strings.Contains(string(raw), "example.org") { t.Fatalf("%s", raw) } } func TestTheReminderTestIsVisiblyATestAndSaysItOpensAWindow(t *testing.T) { f := newFake(t) f.desktopSession() f.betterbird() links(t, nil) f.declare("// none") f.declareAccounts(personal) a, err := f.ReminderTest(40*time.Second, nil, false) if err != nil { t.Fatal(err) } dir := filepath.Join("/run/user/1000", testUnit) css := f.read(dir + "/profile/chrome/userChrome.css") user := f.read(dir + "/profile/user.js") cal := f.read(dir + "/test.ics") if !strings.Contains(css, "MESH TEST") || !strings.Contains(css, `:root:not([windowtype="Calendar:AlarmWindow"])`) { t.Fatalf("the test's windows but the reminder carry a MESH TEST band: %s", css) } if !strings.Contains(user, `user_pref("toolkit.legacyUserProfileCustomizations.stylesheets", true);`) || strings.Contains(user, "mesh_personal") || strings.Contains(user, "example.org") { t.Fatalf("the test profile reads its userChrome.css and holds no declared account: %s", user) } if !strings.Contains(cal, "SUMMARY:MESH TEST reminder") || !strings.Contains(a.OnScreen, "operator's screen") { t.Fatalf("the event and the answer say it is a test on the operator's screen: %s %+v", cal, a) } if !f.called("systemd-run --user --collect --quiet --unit="+testUnit) || !strings.Contains(strings.Join(f.calls, "\n"), startBin+" --no-remote") { t.Fatalf("the test starts Betterbird itself, never the module's start: %v", f.calls) } for _, tool := range tools() { if tool.Name == "betterbird_reminder_test" && !strings.HasPrefix(tool.Description, "OPENS WINDOWS ON THE OPERATOR'S SCREEN") { t.Fatalf("the description says first that a window opens on the operator's screen: %s", tool.Description) } } } func TestTheUserJSDescriptionSaysAdoption(t *testing.T) { for _, tool := range tools() { if tool.Name == "betterbird_user_js" && (!strings.Contains(tool.Description, "adopted under its own keys") || strings.Contains(tool.Description, "refuses the apply")) { t.Fatalf("%s", tool.Description) } } } // Betterbird never asks at its start to be the default mail client: the module's policy locks // mail.shell.checkDefaultClient off, and the check says so when it is on (novox/hq issue 345). func TestTheDefaultClientAskIsLockedOffAndTheCheckSaysWhenItIsOn(t *testing.T) { f := newFake(t) f.betterbird() f.placedByTheMesh() links(t, nil) asks := func() string { t.Helper() c, err := f.Check() if err != nil { t.Fatal(err) } for _, x := range c.Findings { if strings.Contains(x.What, "asks at its start") { return x.What + " | " + x.Do } } return "" } if got := asks(); got != "" { t.Fatalf("the module's policy locks the ask off, yet: %s", got) } unlocked := `{"policies": {"DisableAppUpdate": true, "ExtensionSettings": {"owl@beonex.com": {"installation_mode": "force_installed", "install_url": "file:///opt/betterbird/owl/owl.xpi", "updates_disabled": true}}}}` if why := policyProblem([]byte(unlocked)); !strings.Contains(why, defaultClientPref) { t.Fatalf("a policy that leaves the ask on is said: %q", why) } f.write(policyFile, unlocked) if got := asks(); !strings.Contains(got, "default mail client") || !strings.Contains(got, "push the module") { t.Fatalf("the ask on is a finding with its remedy: %q", got) } f.write(policyFile, `{"policies": {"DisableAppUpdate": true, "Preferences": {"mail.shell.checkDefaultClient": {"Value": false, "Status": "default"}}, "ExtensionSettings": {"owl@beonex.com": {"installation_mode": "force_installed", "install_url": "file:///opt/betterbird/owl/owl.xpi", "updates_disabled": true}}}}`) if why := policyProblem(mustRead(t, f, policyFile)); !strings.Contains(why, "locked") { t.Fatalf("a default the profile can override is not a lock: %q", why) } f.write(profileDir+"/prefs.js", `user_pref("mail.shell.checkDefaultClient", true);`+"\n") if got := asks(); got == "" { t.Fatal("a profile that turned the ask back on over an unlocked default is a finding") } f.write(policyFile, unlocked) f.write(profileDir+"/prefs.js", `user_pref("mail.shell.checkDefaultClient", false);`+"\n") if got := asks(); got != "" { t.Fatalf("a profile with the ask off does not ask: %s", got) } } func mustRead(t *testing.T, f *fake, p string) []byte { t.Helper() raw, err := os.ReadFile(filepath.Join(f.Root, p)) if err != nil { t.Fatal(err) } return raw }