| index 245b55464..f9c39ac1f 100644 |
| --- a/internal/mail/sender_test.go |
| +++ b/internal/mail/sender_test.go |
| @@ -246,3 +246,49 @@ func TestResolveSenderNamesRetriesACollisionWithASalt(t *testing.T) { |
| t.Fatalf("the app sender's name changed: %q", appNames.IAMUser) |
| } |
| } |
| + |
| +// Parse first, index second. Every app enabled today short-circuits Enable |
| +// before MintKey, so it has no index entry until it next rotates: a |
| +// Get-only resolver would silently stop attributing their events the moment |
| +// it shipped. |
| +func TestSenderOfCallerParsesBeforeItReads(t *testing.T) { |
| + ctx := context.Background() |
| + s := release.NewDirStore(t.TempDir()) |
| + now := time.Date(2026, 9, 15, 12, 0, 0, 0, time.UTC) |
| + |
| + // No index entry exists at all, and the delivered and standalone names |
| + // still resolve, to the app sender. |
| + for _, caller := range []string{ |
| + UserName("bag", "harbourmail"), |
| + StandaloneUserName("bag", "harbourmail", "laptop"), |
| + "arn:aws:iam::123456789012:user/carlos-mail/carlos-mail-bag-harbourmail", |
| + } { |
| + acct, app, sender, ok := SenderOfCaller(ctx, s, caller) |
| + if !ok || acct != "bag" || app != "harbourmail" || sender != SenderAppID { |
| + t.Errorf("SenderOfCaller(%q) = %q %q %q %v", caller, acct, app, sender, ok) |
| + } |
| + } |
| + |
| + // A name nobody CARLOS minted stays unknown, and costs no read. |
| + for _, caller := range []string{"", "someone-else", "carlos-mail-bag-harbourmail+s+"} { |
| + if _, _, _, ok := SenderOfCaller(ctx, s, caller); ok { |
| + t.Errorf("SenderOfCaller(%q) claimed to know it", caller) |
| + } |
| + } |
| + |
| + // A slugged name is unparseable by construction and comes from the index. |
| + names, err := SenderNames("bag", "harbourmail", "book.example.com", "") |
| + if err != nil { |
| + t.Fatal(err) |
| + } |
| + if _, _, _, ok := SenderOfCaller(ctx, s, names.IAMUser); ok { |
| + t.Fatal("a slugged name resolved before it was ever indexed") |
| + } |
| + if err := PutCallerIndex(ctx, s, names.IAMUser, "bag", "harbourmail", "book.example.com", now); err != nil { |
| + t.Fatal(err) |
| + } |
| + acct, app, sender, ok := SenderOfCaller(ctx, s, names.IAMUser) |
| + if !ok || acct != "bag" || app != "harbourmail" || sender != "book.example.com" { |
| + t.Fatalf("SenderOfCaller(slug) = %q %q %q %v", acct, app, sender, ok) |
| + } |
| +} |