user = User::factory()->create(); }); test('an inertia write without a fresh confirmation is refused in place, not redirected', function () { $this->actingAs($this->user) ->withHeaders(['X-Inertia' => 'true']) ->post('/settings/two-factor') ->assertStatus(423) ->assertHeader('X-Password-Confirmation', 'required') ->assertJson(['has_local_password' => true]); // Refused, not half-done: the action did not run. expect($this->user->refresh()->two_factor_secret)->toBeNull(); }); test('the refusal tells the dialog when there is no password to type', function () { $user = User::factory()->create(['auth_source' => AuthSource::Social]); $this->actingAs($user) ->withHeaders(['X-Inertia' => 'true']) ->post('/settings/two-factor') ->assertStatus(423) ->assertJson(['has_local_password' => false]); }); test('a plain form post is still redirected to the confirm-password screen', function () { $this->actingAs($this->user) ->post('/settings/two-factor') ->assertRedirect(route('password.confirm')); }); test('the dialog confirms over json, and the replayed request goes through', function () { $this->actingAs($this->user) ->postJson('/confirm-password', ['password' => 'password']) ->assertNoContent(); $this->actingAs($this->user) ->withHeaders(['X-Inertia' => 'true']) ->post('/settings/two-factor') ->assertRedirect(); expect($this->user->refresh()->two_factor_secret)->not->toBeNull(); }); test('a wrong password in the dialog is a validation error, and confirms nothing', function () { $this->actingAs($this->user) ->postJson('/confirm-password', ['password' => 'wrong-password']) ->assertStatus(422) ->assertJsonValidationErrors('password'); $this->actingAs($this->user) ->withHeaders(['X-Inertia' => 'true']) ->post('/settings/two-factor') ->assertStatus(423); });