. */ namespace Tests\Feature; use App\Account; use App\EmailChangeCode; use Tests\TestCase; class ApiAccountEmailChangeTest extends TestCase { protected $route = '/api/accounts/me/email'; protected $method = 'POST'; public function testRequest() { $account = Account::factory()->withConsumedAccountCreationToken()->create(); $account->generateApiKey(); $otherAccount = Account::factory()->withEmail()->create(); $account->generateApiKey(); $newEmail = 'test@test.com'; $this->keyAuthenticated($account) ->json($this->method, $this->route.'/request', [ 'email' => 'blabla' ]) ->assertStatus(422); $this->keyAuthenticated($account) ->json($this->method, $this->route.'/request', [ 'email' => $newEmail ]) ->assertStatus(200); // Same email $this->keyAuthenticated($account) ->json($this->method, $this->route.'/request', [ 'email' => $account->email ]) ->assertStatus(422); $this->keyAuthenticated($account) ->get('/api/accounts/me') ->assertStatus(200) ->assertJson([ 'username' => $account->username, 'email_change_code' => [ 'email' => $newEmail ] ]); // Email already exists config()->set('app.account_email_unique', true); $this->keyAuthenticated($account) ->json($this->method, $this->route . '/request', [ 'email' => $otherAccount->email ])->assertJsonValidationErrors(['email']); } public function testCodeExpiration() { $account = Account::factory()->withConsumedAccountCreationToken()->create(); $account->generateApiKey(); $this->keyAuthenticated($account) ->json($this->method, $this->route.'/request', [ 'email' => 'new@email.com' ]) ->assertStatus(200); config()->set('app.email_change_code_expiration_minutes', 10); EmailChangeCode::where('id', $account->emailChangeCode->id) ->update(['created_at' => $account->emailChangeCode->created_at->subMinutes(1000)]); $this->keyAuthenticated($account) ->json($this->method, $this->route, [ 'code' => $account->emailChangeCode->code ]) ->assertStatus(410); } public function testUnvalidatedAccount() { $account = Account::factory()->create(); $account->generateApiKey(); $this->keyAuthenticated($account) ->json($this->method, $this->route.'/request', [ 'email' => 'test@test.com' ]) ->assertStatus(403); } public function testConfirmWrongCode() { $emailChange = EmailChangeCode::factory()->create(); $this->keyAuthenticated($emailChange->account) ->json($this->method, $this->route, [ 'code' => 'wrong' ]) ->assertStatus(422); } public function testConfirmGoodCode() { $emailChange = EmailChangeCode::factory()->create(); $email = $emailChange->email; $admin = Account::factory()->admin()->create(); $admin->generateApiKey(); $this->keyAuthenticated($emailChange->account) ->get('/api/accounts/me') ->assertStatus(200) ->assertJson([ 'email' => null ]); // Check who can see the code $this->keyAuthenticated($admin) ->json('GET', '/api/accounts/' . $emailChange->account->id) ->assertStatus(200) ->assertSee($emailChange->code); $this->keyAuthenticated($emailChange->account) ->json('GET', '/api/accounts/me') ->assertStatus(200) ->assertDontSee($emailChange->code); $this->keyAuthenticated($emailChange->account) ->json($this->method, $this->route, [ 'code' => $emailChange->code ]) ->assertStatus(200) ->assertJson([ 'email' => $email, ]); $this->keyAuthenticated($emailChange->account) ->get('/api/accounts/me') ->assertStatus(200) ->assertJson([ 'email' => $email ]); // Check that the code is gone $this->keyAuthenticated($admin) ->json('GET', '/api/accounts/' . $emailChange->account->id) ->assertStatus(200) ->assertDontSee($emailChange->code); } }