From 361d6dbe0399a394d85fc202ce425ad2eaf115f6 Mon Sep 17 00:00:00 2001 From: Joe Julian Date: Mon, 13 Apr 2026 17:26:51 -0700 Subject: [PATCH] Add failing Android autofill binding tests --- internal/autofillcache/bindings_test.go | 102 ++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 internal/autofillcache/bindings_test.go diff --git a/internal/autofillcache/bindings_test.go b/internal/autofillcache/bindings_test.go new file mode 100644 index 0000000..8617d58 --- /dev/null +++ b/internal/autofillcache/bindings_test.go @@ -0,0 +1,102 @@ +package autofillcache + +import ( + "path/filepath" + "testing" + "time" +) + +func TestResolvePrefersLearnedAndroidAppBinding(t *testing.T) { + t.Parallel() + + cache := File{ + Entries: []Entry{ + { + ID: "danny-ocean", + Title: "Bellagio Vault", + Username: "danny", + Password: "secret1", + URL: "https://bellagio.example.invalid/login", + Host: "bellagio.example.invalid", + }, + { + ID: "rusty-ryan", + Title: "Mirage Crew", + Username: "rusty", + Password: "secret2", + URL: "https://mirage.example.invalid/login", + Host: "mirage.example.invalid", + }, + }, + } + bindings := BindingsFile{ + Apps: map[string]string{ + "androidapp://com.samsung.android.shealth": "rusty-ryan", + }, + } + + got := ResolveWithBindings(cache, bindings, "androidapp://com.samsung.android.shealth") + if got.Status != MatchStatusFound { + t.Fatalf("ResolveWithBindings() status = %q, want found", got.Status) + } + if got.Entry.ID != "rusty-ryan" { + t.Fatalf("ResolveWithBindings() entry = %q, want rusty-ryan", got.Entry.ID) + } +} + +func TestChooserCandidatesFallBackToAllEntriesForUnknownAndroidApp(t *testing.T) { + t.Parallel() + + cache := File{ + Entries: []Entry{ + { + ID: "basher-tarr", + Title: "Bellagio Vault", + Username: "basher", + Password: "secret1", + URL: "https://bellagio.example.invalid/login", + Host: "bellagio.example.invalid", + Path: []string{"Crew"}, + }, + { + ID: "linus-caldwell", + Title: "Bank Floor", + Username: "linus", + Password: "secret2", + URL: "https://bank.example.invalid/sign-in", + Host: "bank.example.invalid", + Path: []string{"Operations"}, + }, + }, + } + + got := ChooserCandidates(cache, "androidapp://com.samsung.android.shealth") + if len(got) != 2 { + t.Fatalf("len(ChooserCandidates()) = %d, want 2", len(got)) + } + if got[0].ID != "linus-caldwell" || got[1].ID != "basher-tarr" { + t.Fatalf("ChooserCandidates() = %#v, want title-sorted fallback candidates", got) + } +} + +func TestRememberBindingPersistsAndroidAppSelection(t *testing.T) { + t.Parallel() + + path := filepath.Join(t.TempDir(), "autofill-bindings.json") + now := time.Date(2026, time.April, 13, 18, 0, 0, 0, time.UTC) + + if err := RememberBinding(path, "androidapp://com.samsung.android.shealth", "saul-bloom", now); err != nil { + t.Fatalf("RememberBinding() error = %v", err) + } + + got, err := ReadBindings(path) + if err != nil { + t.Fatalf("ReadBindings() error = %v", err) + } + if got.UpdatedAt != now.UTC().Format(time.RFC3339) { + t.Fatalf("UpdatedAt = %q, want %q", got.UpdatedAt, now.UTC().Format(time.RFC3339)) + } + if got.Apps["androidapp://com.samsung.android.shealth"] != "saul-bloom" { + t.Fatalf("binding = %#v, want samsung health -> saul-bloom", got.Apps) + } +}