from('/register')->post('/register', [ 'email' => 'bot1@example.com', 'website' => 'https://spam.example', ]); $response->assertRedirect('/register'); $response->assertSessionHasErrors('website'); $this->assertDatabaseMissing('users', ['email' => 'bot1@example.com']); }); it('throttles excessive registration attempts by ip', function () { Mail::fake(); config()->set('antispam.register.ip_per_minute', 2); config()->set('antispam.register.email_per_minute', 20); for ($i = 0; $i < 2; $i++) { $this->post('/register', [ 'email' => 'user-rate-' . $i . '@example.com', ])->assertRedirect('/register/notice'); } $this->post('/register', [ 'email' => 'user-rate-3@example.com', ])->assertStatus(429); RateLimiter::clear('register:ip:127.0.0.1'); }); it('rejects registration when recaptcha is enabled and verification fails', function () { Mail::fake(); $mock = \Mockery::mock(RecaptchaVerifier::class); $mock->shouldReceive('isEnabled')->andReturn(true); $mock->shouldReceive('verify')->once()->andReturn(false); $this->app->instance(RecaptchaVerifier::class, $mock); $response = $this->from('/register')->post('/register', [ 'email' => 'captcha-user@example.com', 'g-recaptcha-response' => 'bad-token', ]); $response->assertRedirect('/register'); $response->assertSessionHasErrors('captcha'); $this->assertDatabaseMissing('users', ['email' => 'captcha-user@example.com']); }); it('allows registration when recaptcha is enabled and verification succeeds', function () { Mail::fake(); $mock = \Mockery::mock(RecaptchaVerifier::class); $mock->shouldReceive('isEnabled')->andReturn(true); $mock->shouldReceive('verify')->once()->andReturn(true); $this->app->instance(RecaptchaVerifier::class, $mock); $response = $this->post('/register', [ 'email' => 'captcha-pass@example.com', 'g-recaptcha-response' => 'good-token', ]); $response->assertRedirect('/register/notice'); $this->assertDatabaseHas('users', ['email' => 'captcha-pass@example.com']); });