create(); $codes = $user->replaceRecoveryCodes(); // Opened from "Backup-Codes verwalten" with no fresh-generation flag: never reveal. Livewire::actingAs($user)->test(RecoveryCodes::class) ->assertSet('revealed', false) ->assertDontSee($codes[0]) ->assertDontSee($codes[7]) ->assertSee(__('auth.recovery_hidden_notice')); } public function test_fresh_flag_reveals_the_codes_once(): void { $user = User::factory()->create(); $codes = $user->replaceRecoveryCodes(); session(['2fa.codes_fresh' => true]); Livewire::actingAs($user)->test(RecoveryCodes::class) ->assertSet('revealed', true) ->assertSee($codes[0]) ->assertSee($codes[7]); // pull() forgets the flag — it is single-use. $this->assertFalse(session()->has('2fa.codes_fresh')); } public function test_regenerate_from_manage_view_reveals_the_new_codes(): void { $user = User::factory()->create(); $old = $user->replaceRecoveryCodes(); // Manage view (no flag) → not revealed → regenerate → the NEW set is revealed once. Livewire::actingAs($user)->test(RecoveryCodes::class) ->assertSet('revealed', false) ->call('regenerate') ->assertSet('revealed', true) ->assertDontSee($old[0]); $new = $user->fresh()->recoveryCodes(); $this->assertNotEquals($old, $new); Livewire::actingAs($user)->test(RecoveryCodes::class) ->call('regenerate') ->assertSee($user->fresh()->recoveryCodes()[0]); } public function test_old_recovery_route_is_gone(): void { $this->assertFalse(Route::has('two-factor.recovery')); $this->assertTrue(Route::has('two-factor.recovery.download')); } }