postJson('/api/waitlist', [ 'name' => 'Ada Lovelace', 'email' => 'ada@example.com', ]); $response->assertCreated() ->assertJsonStructure(['message']); $this->assertDatabaseHas('waitlist_subscribers', [ 'name' => 'Ada Lovelace', 'email' => 'ada@example.com', ]); }); it('treats a duplicate email as success without creating a second row', function () { WaitlistSubscriber::factory()->create(['email' => 'ada@example.com']); $this->postJson('/api/waitlist', [ 'name' => 'Someone Else', 'email' => 'ada@example.com', ])->assertCreated(); expect(WaitlistSubscriber::where('email', 'ada@example.com')->count())->toBe(1); }); it('stores the source and referrer sent with the request', function () { $this->postJson('/api/waitlist', [ 'name' => 'Ada Lovelace', 'email' => 'ada@example.com', 'source' => 'pricing', 'referrer' => 'https://duckduckgo.com/', ])->assertCreated(); $this->assertDatabaseHas('waitlist_subscribers', [ 'email' => 'ada@example.com', 'source' => 'pricing', 'referrer' => 'https://duckduckgo.com/', ]); }); it('requires a name', function () { $this->postJson('/api/waitlist', [ 'email' => 'ada@example.com', ])->assertStatus(422)->assertJsonValidationErrors('name'); }); it('rejects an invalid email', function () { $this->postJson('/api/waitlist', [ 'name' => 'Ada Lovelace', 'email' => 'not-an-email', ])->assertStatus(422)->assertJsonValidationErrors('email'); }); it('throttles the endpoint', function () { $route = collect(app('router')->getRoutes()) ->first(fn ($route) => $route->uri() === 'api/waitlist' && in_array('POST', $route->methods(), true)); expect($route?->gatherMiddleware())->toContain('throttle:10,1'); });