From 917d3a9707c29a50d4db87eee56b09ad006660c3 Mon Sep 17 00:00:00 2001 From: Stuart Laverick Date: Tue, 16 Jan 2024 12:08:43 +0000 Subject: [PATCH] Added video content type tpo page content --- app/Models/Page.php | 3 + app/Rules/PageContent.php | 27 ++++++- tests/Feature/PagesTest.php | 153 ++++++++++++++++++++++++++++++++++++ 3 files changed, 181 insertions(+), 2 deletions(-) diff --git a/app/Models/Page.php b/app/Models/Page.php index 4d2021262..26fee3c6d 100644 --- a/app/Models/Page.php +++ b/app/Models/Page.php @@ -78,6 +78,9 @@ public function toSearchableArray(): array case 'cta': $content[] = $this->makeSearchable($contentBlock['title'] . ' ' . $contentBlock['description']); break; + case 'video': + $content[] = $this->makeSearchable($contentBlock['title']); + break; default: break; } diff --git a/app/Rules/PageContent.php b/app/Rules/PageContent.php index c3863e9be..5bfe2551c 100644 --- a/app/Rules/PageContent.php +++ b/app/Rules/PageContent.php @@ -4,6 +4,7 @@ use Closure; use Illuminate\Contracts\Validation\ValidationRule; +use Illuminate\Support\Str; class PageContent implements ValidationRule { @@ -50,8 +51,7 @@ public function validate(string $attribute, mixed $value, Closure $fail): void $fail('Page content is required for introduction'); } - } - if ($value['type'] === 'cta') { + } elseif ($value['type'] === 'cta') { if (empty($value['title']) || !is_string($value['title'])) { $fail('Call to action title is required'); } @@ -67,7 +67,30 @@ public function validate(string $attribute, mixed $value, Closure $fail): void if (!empty($value['url']) && filter_var($value['url'], FILTER_VALIDATE_URL) === false) { $fail('Call to action link must be a valid URL'); } + } elseif ($value['type'] === 'video') { + if (empty($value['title']) || !is_string($value['title'])) { + $fail('Video title is required'); + } + if (empty($value['url']) || !is_string($value['url'])) { + $fail('Video url is required'); + } + + if (!empty($value['url'])) { + if (filter_var($value['url'], FILTER_VALIDATE_URL) === false) { + $fail('Video url must be a valid URL'); + } + + if (!Str::startsWith($value['url'], [ + 'https://www.youtube.com', + 'https://player.vimeo.com', + 'https://vimeo.com', + ])) { + $fail('The video url must be provided by either YouTube or Vimeo.'); + } + } + } else { + $fail('Invalid content type'); } } } diff --git a/tests/Feature/PagesTest.php b/tests/Feature/PagesTest.php index 8020d6b7d..b39ac63f0 100644 --- a/tests/Feature/PagesTest.php +++ b/tests/Feature/PagesTest.php @@ -2084,6 +2084,7 @@ public function createInformationPageWithCallToActionAsContentAdmin422(): void $parentPage = Page::factory()->create(); + // Missing title $data = [ 'title' => $this->faker->sentence(), 'excerpt' => trim(substr($this->faker->paragraph(2), 0, 149)), @@ -2111,6 +2112,7 @@ public function createInformationPageWithCallToActionAsContentAdmin422(): void $response->assertStatus(Response::HTTP_UNPROCESSABLE_ENTITY); + // Missing description $data = [ 'title' => $this->faker->sentence(), 'excerpt' => trim(substr($this->faker->paragraph(2), 0, 149)), @@ -2138,6 +2140,7 @@ public function createInformationPageWithCallToActionAsContentAdmin422(): void $response->assertStatus(Response::HTTP_UNPROCESSABLE_ENTITY); + // Missing button text $data = [ 'title' => $this->faker->sentence(), 'excerpt' => trim(substr($this->faker->paragraph(2), 0, 149)), @@ -2165,6 +2168,7 @@ public function createInformationPageWithCallToActionAsContentAdmin422(): void $response->assertStatus(Response::HTTP_UNPROCESSABLE_ENTITY); + // Invalid URL $data = [ 'title' => $this->faker->sentence(), 'excerpt' => trim(substr($this->faker->paragraph(2), 0, 149)), @@ -2236,6 +2240,49 @@ public function createInformationPageWithCallToActionAsContentAdmin200(): void $response->assertStatus(Response::HTTP_OK); } + /** + * @test + */ + public function createInformationPageWithVideoAsContentAdmin200(): void + { + /** + * @var \App\Models\User $user + */ + $user = User::factory()->create(); + $user->makeContentAdmin(); + + Passport::actingAs($user); + + $parentPage = Page::factory()->create(); + + $data = [ + 'title' => $this->faker->sentence(), + 'excerpt' => trim(substr($this->faker->paragraph(2), 0, 149)), + 'content' => [ + 'introduction' => [ + 'content' => [ + [ + 'type' => 'copy', + 'value' => $this->faker->realText(), + ], + [ + 'type' => 'video', + 'title' => $this->faker->sentence(), + 'url' => 'https://www.youtube.com/watch?v=dummy_id', + ], + ], + ], + ], + 'parent_id' => $parentPage->id, + 'page_type' => 'information', + ]; + $response = $this->json('POST', '/core/v1/pages', $data); + + $response->assertStatus(Response::HTTP_OK); + + $response->assertJsonFragment($data); + } + /** * @test */ @@ -2320,6 +2367,86 @@ public function createLandingPageWithCallToActionsAsContentAdmin200(): void $response->assertStatus(Response::HTTP_OK); } + /** + * @test + */ + public function createLandingPageWithVideosAsContentAdmin200(): void + { + /** + * @var \App\Models\User $user + */ + $user = User::factory()->create(); + $user->makeContentAdmin(); + + Passport::actingAs($user); + + $data = [ + 'title' => $this->faker->sentence(), + 'excerpt' => trim(substr($this->faker->paragraph(2), 0, 149)), + 'content' => [ + 'introduction' => [ + 'content' => [ + [ + 'type' => 'copy', + 'value' => $this->faker->realText(), + ], + [ + 'type' => 'video', + 'title' => $this->faker->sentence(), + 'url' => 'https://www.youtube.com/watch?v=dummy_id', + ], + ], + ], + 'about' => [ + 'content' => [ + [ + 'type' => 'copy', + 'value' => $this->faker->realText(), + ], + [ + 'type' => 'video', + 'title' => $this->faker->sentence(), + 'url' => 'https://www.youtube.com/watch?v=dummy_id', + ], + [ + 'type' => 'copy', + 'value' => $this->faker->realText(), + ], + ], + ], + 'info_pages' => [ + 'title' => $this->faker->sentence(), + 'content' => [ + [ + 'type' => 'copy', + 'value' => $this->faker->realText(), + ], + [ + 'type' => 'video', + 'title' => $this->faker->sentence(), + 'url' => 'https://www.youtube.com/watch?v=dummy_id', + ], + ], + ], + 'collections' => [ + 'title' => $this->faker->sentence(), + 'content' => [ + [ + 'type' => 'copy', + 'value' => $this->faker->realText(), + ], + ], + ], + ], + 'page_type' => Page::PAGE_TYPE_LANDING, + ]; + $response = $this->json('POST', '/core/v1/pages', $data); + + $response->assertStatus(Response::HTTP_OK); + + $response->assertJsonFragment($data); + } + /** * @test */ @@ -2904,6 +3031,28 @@ public function updatePageAsContentAdmin200(): void $data = [ 'title' => 'New Title', 'enabled' => true, + 'content' => [ + 'introduction' => [ + 'content' => [ + [ + 'type' => 'copy', + 'value' => $this->faker->realText(), + ], + [ + 'type' => 'cta', + 'title' => $this->faker->sentence(), + 'description' => $this->faker->realText(), + 'url' => $this->faker->url(), + 'buttonText' => $this->faker->words(3, true), + ], + [ + 'type' => 'video', + 'title' => $this->faker->sentence(), + 'url' => 'https://www.youtube.com/watch?v=dummy_id', + ], + ], + ], + ], ]; $response = $this->json('PUT', '/core/v1/pages/' . $page->id, $data); @@ -2938,6 +3087,10 @@ public function updatePageAsContentAdmin200(): void 'title' => 'New Title', 'enabled' => true, ]); + + $response = $this->json('GET', '/core/v1/pages/' . $page->id); + + $response->assertJsonFragment($data); } /**