package main import ( "os" "path/filepath" "strings" "testing" ) // The guard exists because the build tag is invisible in the binary's name and // in its version stamp: a wrong one is otherwise only discovered in production. // These cases pin the two directions that matter — shipping billing to a // deployment that runs without it, and shipping a stub to one that expects it. func TestVerifyAppviewBilling(t *testing.T) { t.Parallel() for _, tc := range []struct { name string content string want bool wantErr bool }{ {"billing build, billing wanted", "...github.com/stripe/stripe-go/v79...", true, false}, {"stub build, no billing wanted", "...Billing is not enabled on this deployment...", false, false}, {"billing build leaking into a no-billing deploy", "...stripe-go...", false, true}, {"stub build where billing was asked for", "...no payment code here...", true, true}, } { t.Run(tc.name, func(t *testing.T) { t.Parallel() path := filepath.Join(t.TempDir(), "atcr-appview") if err := os.WriteFile(path, []byte(tc.content), 0o600); err != nil { t.Fatalf("write fixture: %v", err) } err := verifyAppviewBilling(path, tc.want) if tc.wantErr && err == nil { t.Fatalf("want=%v: expected a mismatch error, got nil", tc.want) } if !tc.wantErr && err != nil { t.Fatalf("want=%v: unexpected error: %v", tc.want, err) } // The message has to say which way round the mismatch is, or the // operator cannot tell whether to add or drop the flag. if tc.wantErr && !strings.Contains(err.Error(), "billing mismatch") { t.Errorf("error should name the mismatch, got: %v", err) } }) } } // A missing binary must fail loudly rather than be read as "no stripe symbols, // therefore billing is off" — which would let a deploy proceed on a file that // was never built. func TestVerifyAppviewBillingMissingBinary(t *testing.T) { t.Parallel() err := verifyAppviewBilling(filepath.Join(t.TempDir(), "does-not-exist"), false) if err == nil { t.Fatal("expected an error for a missing binary, got nil") } }