package main import ( "encoding/json" "os" "path/filepath" "reflect" "regexp" "sort" "strings" "testing" ) // xdg's shape: it claims no seat (the conventions are not a role anything calls), needs no // display, owns the account's folders file whole and the machine's lowest list of default // applications, and holds the person's own list of defaults and every autostart entry as found. type manifest struct { Module string `json:"module"` Capabilities []string `json:"capabilities"` Requires []string `json:"requires"` Claims []any `json:"claims"` Tools []string `json:"tools"` Shell []any `json:"shell"` Contributions []any `json:"contributions"` Resources []map[string]any `json:"resources"` Build struct { Artifacts []map[string]any `json:"artifacts"` } `json:"build"` } func readManifest(t *testing.T) (manifest, string) { t.Helper() raw, err := os.ReadFile(filepath.Join("..", "..", "module.json")) if err != nil { t.Fatal(err) } var m manifest if err := json.Unmarshal(raw, &m); err != nil { t.Fatal(err) } return m, string(raw) } func TestItClaimsNoSeatNeedsNoDisplayAndContributesNothing(t *testing.T) { m, _ := readManifest(t) if m.Module != "xdg" || m.Claims != nil || m.Requires != nil || m.Shell != nil || m.Contributions != nil { t.Fatalf("%+v", m) } if !reflect.DeepEqual(m.Capabilities, []string{"package-manager"}) { t.Fatalf("%v", m.Capabilities) } } func TestItOwnsTheFilesItsSourcesHold(t *testing.T) { m, _ := readManifest(t) want := map[string][3]string{ "user-dirs": {"${machine:account-home}/.config/user-dirs.dirs", "0600", "user-dirs.dirs"}, "user-dirs-locale": {"${machine:account-home}/.config/user-dirs.locale", "0644", "user-dirs.locale"}, "user-dirs-update": {"${machine:account-home}/.config/user-dirs.conf", "0644", "user-dirs.conf"}, "default-applications": {MeshList, "0644", "mimeapps.list"}, } var pkgs []string files := 0 for _, r := range m.Resources { id, _ := r["id"].(string) if r["type"] == "package" { pkgs = append(pkgs, r["package"].(string)) continue } w, ok := want[id] if !ok || r["type"] != "file" { t.Errorf("unexpected resource %v", r) continue } files++ src, _ := os.ReadFile(filepath.Join("..", "..", "config", w[2])) if r["path"] != w[0] || r["mode"] != w[1] || r["content"] != string(src) || r["into"] != nil { t.Errorf("%s is not config/%s, whole, at %s mode %s: %v", id, w[2], w[0], w[1], r["path"]) } home := strings.HasPrefix(w[0], "${machine:account-home}/") if home != (r["owner"] == "${machine:account}") { t.Errorf("%s: a file in the home is the account's, a system file root's: owner %v", id, r["owner"]) } } if files != len(want) { t.Errorf("%d files, want %d", files, len(want)) } if !reflect.DeepEqual(pkgs, []string{"xdg-user-dirs", "xdg-utils"}) { t.Errorf("packages %v", pkgs) } for _, r := range m.Resources { if p, _ := r["path"].(string); strings.Contains(p, "mimeapps.list") && strings.Contains(p, "account-home") { t.Errorf("the person's mimeapps.list is held as found, never written: %v", r) } if p, _ := r["path"].(string); strings.Contains(p, "autostart") || strings.Contains(p, "xdg-desktop-portal") { t.Errorf("autostart entries are their applications' modules', the portal is adwaita's: %v", r) } } } func TestTheFoldersFileIsXdgUserDirsOwnFormatWithThreeSettings(t *testing.T) { raw, _ := os.ReadFile(filepath.Join("..", "..", "config", "user-dirs.dirs")) text := string(raw) settings := regexp.MustCompile(`\$\{setting:([a-z0-9-]+)\}`).FindAllStringSubmatch(text, -1) var names []string for _, s := range settings { names = append(names, s[1]) } sort.Strings(names) if !reflect.DeepEqual(names, []string{"desktop-dir", "publicshare-dir", "videos-dir"}) { t.Fatalf("the folders that differ between the workstations are the settings: %v", names) } lines := 0 for _, l := range strings.Split(strings.TrimSpace(text), "\n") { if strings.HasPrefix(l, "#") { continue } lines++ if !userDirLine.MatchString(l) { t.Errorf("not xdg-user-dirs' format: %q", l) } } // The eight folders GLib knows, and xdg-user-dirs' PROJECTS. if lines != 9 { t.Errorf("%d folders", lines) } if !strings.Contains(firstLines(text, 3), meshMark) { t.Error("the header xdg_check recognises the file by") } conf, _ := os.ReadFile(filepath.Join("..", "..", "config", "user-dirs.conf")) if !regexp.MustCompile(`(?m)^enabled=False$`).Match(conf) { t.Error("xdg-user-dirs-update must be disabled, or it rewrites the mesh's file at login") } } func TestTheMeshsDefaultsNameEachTypeOnceInOneGroupEach(t *testing.T) { raw, _ := os.ReadFile(filepath.Join("..", "..", "config", "mimeapps.list")) k := ParseKeyFile(string(raw)) if len(k.DupGroups)+len(k.DupKeys)+len(k.Unparsable) != 0 { t.Fatalf("%+v", k) } if !reflect.DeepEqual(k.Order, []string{"Default Applications", "Added Associations"}) { t.Fatalf("%v", k.Order) } for typ, v := range k.Groups["Default Applications"] { if _, err := Normalise(typ); err != nil { t.Errorf("%s: %v", typ, err) } for _, id := range List(v) { if !desktopID.MatchString(id) || regexp.MustCompile(`[0-9a-f]{8}-[0-9a-f]{4}-`).MatchString(id) { t.Errorf("%s=%s: an id one machine generated is not a default for every machine", typ, id) } if id == "code-oss.desktop" { t.Errorf("%s: code-oss is installed on neither workstation", typ) } } } if k.Groups["Default Applications"]["x-scheme-handler/https"] != "firefox.desktop;" { t.Error("the browser is the operator's") } } func TestTheToolsAgreeWithTheManifest(t *testing.T) { m, raw := readManifest(t) served := map[string]bool{} for _, tool := range tools(&Machine{}) { served[tool.Name] = true if !strings.HasPrefix(tool.Name, "xdg_") || strings.TrimSpace(tool.Description) == "" { t.Errorf("%s", tool.Name) } } if len(served) != len(m.Tools) { t.Fatalf("%v %v", served, m.Tools) } for _, n := range m.Tools { if !served[n] { t.Errorf("module.json lists %s, which the bundle does not serve", n) } } var bundle map[string]any for _, a := range m.Build.Artifacts { if a["kind"] == "bundle" { bundle = a } } if bundle == nil || bundle["language"] != "go" || bundle["system"] != "arch" || bundle["from"] != "cmd/xdg-tools" || bundle["binary"] != "xdg-tools" { t.Errorf("the Go tools bundle: %v", bundle) } s := strings.ToLower(raw) for _, never := range []string{"/home/", "jochen", "g14", "shanks", "novox.be", "zurag", ".hal/", "api_key"} { if strings.Contains(s, never) { t.Errorf("module.json names %q", never) } } }