| index fc4aaa1c4..73fdf3f39 100644 |
| --- a/internal/console/apiauthorize_test.go |
| +++ b/internal/console/apiauthorize_test.go |
| @@ -3,8 +3,10 @@ package console |
| import ( |
| "context" |
| "encoding/json" |
| + "errors" |
| "net/http" |
| "testing" |
| + "time" |
| |
| "github.com/carlosframework/platform/internal/release" |
| ) |
| @@ -44,3 +46,37 @@ func TestAuthorizeDoorRefusesServiceCredentials(t *testing.T) { |
| t.Fatalf("a service credential reached authorize: %d", st) |
| } |
| } |
| + |
| +// TestAuthorizeDoorSpendsTheWriteBudget: the POST signs a record inside the |
| +// app's exclusive mutation, so it draws on the per-person write budget, like |
| +// resign, before any store work. The GET is a read and stays unbudgeted. |
| +func TestAuthorizeDoorSpendsTheWriteBudget(t *testing.T) { |
| + fx := newDigestsFixture(t) |
| + if err := fx.store.Delete(context.Background(), release.PromotionRecordKey("bab", "km", "v1")); err != nil { |
| + t.Fatal(err) |
| + } |
| + fx.srv.cli.write = newRateLimiter(1, time.Minute) |
| + u := fx.ts.URL + "/api/cli/apps/bab/km/releases/v1/authorize" |
| + st, out := getRaw(t, u, fx.member) |
| + if st != http.StatusOK { |
| + t.Fatalf("plan: %d %s", st, out) |
| + } |
| + var plan struct { |
| + ManifestDigest string `json:"manifest_digest"` |
| + } |
| + if err := json.Unmarshal([]byte(out), &plan); err != nil || plan.ManifestDigest == "" { |
| + t.Fatalf("plan body %s: %v", out, err) |
| + } |
| + if st, out := postRaw(t, u, map[string]string{"manifest_digest": "00"}, fx.member); st != http.StatusConflict { |
| + t.Fatalf("first request: %d %s", st, out) |
| + } |
| + if st, out := getRaw(t, u, fx.member); st != http.StatusOK { |
| + t.Fatalf("a read after the budget is spent: %d %s", st, out) |
| + } |
| + if st, out := postRaw(t, u, map[string]string{"manifest_digest": plan.ManifestDigest}, fx.member); st != http.StatusTooManyRequests || jsonErrorText(t, out) != textTooManyRequests { |
| + t.Fatalf("second request over the budget: %d %s", st, out) |
| + } |
| + if _, err := release.ReadPromotionRecord(context.Background(), fx.store, fx.pub, "bab", "km", "v1"); !errors.Is(err, release.ErrNoPromotionRecord) { |
| + t.Fatalf("a refused request wrote a record: %v", err) |
| + } |
| +} |