seed(RolePermissionSeeder::class); Queue::fake(); } #[Test] public function the_bin_gathers_everything_deleted(): void { Page::factory()->create(['title' => ['es' => 'Borrada']])->delete(); Project::factory()->create(['title' => ['es' => 'Borrado']])->delete(); $this->actingAs($this->userWithRoles('admin')); // Recovering something used to mean remembering which resource it had // been in and then turning on a filter. $this->get(Trash::getUrl()) ->assertSuccessful() ->assertSee('Borrada') ->assertSee('Borrado'); } #[Test] public function something_can_be_put_back_from_the_bin(): void { $page = Page::factory()->create(); $page->delete(); $this->actingAs($this->userWithRoles('admin')); Livewire::test(Trash::class) ->call('restoreRecord', Page::class, $page->id); $this->assertNull($page->fresh()->deleted_at); } #[Test] public function the_bin_refuses_a_model_it_does_not_list(): void { $this->actingAs($this->userWithRoles('admin')); // An id and a class name arriving from the browser must not be able to // reach anything the page did not declare. Livewire::test(Trash::class) ->call('restoreRecord', User::class, 1) ->assertOk(); $this->assertTrue(true); } #[Test] public function a_viewer_sees_only_what_they_may_see(): void { Application::factory()->create()->delete(); Page::factory()->create(['title' => ['es' => 'Una página']])->delete(); $this->actingAs($this->userWithRoles('viewer')); // A viewer has no business reading a stranger's message, in the bin or // anywhere else. $this->get(Trash::getUrl()) ->assertSuccessful() ->assertSee('Una página') ->assertDontSee(__('panel.applications.plural')); } #[Test] public function a_preview_link_points_at_the_record_it_was_made_for(): void { $project = Project::factory()->draft()->create([ 'title' => ['es' => 'Borrador'], 'slug' => ['es' => 'borrador'], ]); $url = PreviewLink::for($project, 'project', 'es'); $this->assertStringContainsString('/proyectos/borrador', $url); $this->assertStringContainsString('preview=', $url); $token = urldecode((string) parse_url($url, PHP_URL_QUERY)); $token = str_replace('preview=', '', $token); $payload = PreviewLink::open($token); $this->assertSame('project', $payload['type']); $this->assertSame($project->id, $payload['id']); $this->assertSame('es', $payload['locale']); } #[Test] public function a_preview_link_opens_a_draft_on_the_api(): void { $project = Project::factory()->draft()->create([ 'title' => ['es' => 'Borrador'], 'slug' => ['es' => 'borrador'], ]); $url = PreviewLink::for($project, 'project', 'es'); $token = str_replace('preview=', '', urldecode((string) parse_url($url, PHP_URL_QUERY))); $this->withHeaders(['Accept-Language' => 'es']) ->getJson('/api/public/v1/projects/borrador') ->assertNotFound(); $this->withHeaders(['Accept-Language' => 'es']) ->getJson('/api/public/v1/projects/borrador?preview='.urlencode($token)) ->assertOk(); } #[Test] public function a_forged_or_expired_link_opens_nothing(): void { $this->assertNull(PreviewLink::open('no-es-un-token')); $project = Project::factory()->draft()->create([ 'title' => ['es' => 'Borrador'], 'slug' => ['es' => 'borrador'], ]); $url = PreviewLink::for($project, 'project', 'es'); $token = str_replace('preview=', '', urldecode((string) parse_url($url, PHP_URL_QUERY))); $this->travel(PreviewLink::HOURS + 1)->hours(); // Short-lived on purpose: one forwarded in an e-mail thread stops // working rather than living for ever. $this->assertNull(PreviewLink::open($token)); } #[Test] public function a_record_with_no_slug_in_a_language_has_no_link_for_it(): void { $project = Project::factory()->draft()->create(['slug' => ['es' => 'solo-es']]); $this->assertNotNull(PreviewLink::for($project, 'project', 'es')); $this->assertNull(PreviewLink::for($project, 'project', 'ca')); } }