diff --git a/app/Enums/ProfileSectionType.php b/app/Enums/ProfileSectionType.php new file mode 100644 index 00000000..3973dcf7 --- /dev/null +++ b/app/Enums/ProfileSectionType.php @@ -0,0 +1,44 @@ + 8, + self::Appointments => 10, + self::Awards => 10, + self::Affiliations => 10, + self::News => 5, + self::Support => 5, + self::Presentations => 5, + self::Projects => 5, + self::Additionals => 3, + self::Activities => 6, + self::Areas => 4, + self::Preparation => 7, + self::Default => 5, + }; + } +} \ No newline at end of file diff --git a/app/Http/Livewire/ProfileDataCard.php b/app/Http/Livewire/ProfileDataCard.php index 0e087898..2bdd723f 100644 --- a/app/Http/Livewire/ProfileDataCard.php +++ b/app/Http/Livewire/ProfileDataCard.php @@ -5,24 +5,12 @@ use App\Profile; use Livewire\Component; use Livewire\WithPagination; +use App\Enums\ProfileSectionType; class ProfileDataCard extends Component { use WithPagination; - const PER_PAGE_FOR_SECTION = [ - 'default' => 5, - 'publications' => 8, - 'appointments' => 10, - 'awards' => 10, - 'news' => 5, - 'support' => 5, - 'presentations' => 5, - 'projects' => 5, - 'additionals' => 3, - 'affiliations' => 10 - ]; - protected $paginationTheme = 'bootstrap'; public $profile; public $data_type; @@ -40,9 +28,25 @@ public function mount(Profile $profile, $editable, $data_type, $paginated = true $this->public_filtered = $public_filtered; } + public function updatingDataType() + { + $this->validateOnly('data_type', [ + 'data_type' => 'required|in:' . implode(',', ProfileSectionType::values()), + ]); + } + public function data() { - $data_query = $this->profile->{$this->data_type}(); + $section = ProfileSectionType::tryFrom($this->data_type); + + if (!$section) { + $this->addError('data_type', 'Invalid section.'); + $this->emit('alert', 'Invalid section.', 'danger'); + + return null; + } + + $data_query = $this->profile->{$section->value}(); if ($this->public_filtered) { $data_query = $data_query->public(); @@ -50,7 +54,7 @@ public function data() if ($this->paginated) { return $data_query->paginate( - $this::PER_PAGE_FOR_SECTION[$this->data_type] ?? $this::PER_PAGE_FOR_SECTION['default'], + $section->perPage(), ['*'], $this->data_type ); @@ -63,7 +67,7 @@ public function render() { $data = $this->data(); - if ($data->isEmpty() && !$this->editable) { + if ($data === null || ($data->isEmpty() && !$this->editable)) { return ''; } diff --git a/tests/Feature/Livewire/ProfileDataCardTest.php b/tests/Feature/Livewire/ProfileDataCardTest.php index 3206d7bc..ca41abbc 100644 --- a/tests/Feature/Livewire/ProfileDataCardTest.php +++ b/tests/Feature/Livewire/ProfileDataCardTest.php @@ -10,6 +10,7 @@ use Livewire\Livewire; use Tests\Feature\Traits\LoginWithRole; use Tests\TestCase; +use App\Enums\ProfileSectionType; class ProfileDataCardTest extends TestCase { @@ -31,7 +32,7 @@ class ProfileDataCardTest extends TestCase */ public function testPaginatedItemsOnFirstAndLastPage() { - $sections = [ 'publications', 'presentations', 'projects', 'additionals' ]; + $section_options = [ 'publications', 'presentations', 'projects', 'additionals' ]; $profile = Profile::factory() ->hasData() @@ -49,30 +50,34 @@ public function testPaginatedItemsOnFirstAndLastPage() $user = $this->loginAsUser(); $editable = $user && $user->can('update', $profile); - foreach ($sections as $section) { + foreach ($section_options as $section_opt) { + $section = ProfileSectionType::from($section_opt); + + $this->assertNotNull($section, 'Invalid section'); + $this->assertTrue( - method_exists($profile, $section), - 'Profile does not have method '.$section + method_exists($profile, $section->value), + 'Profile does not have method '.$section->value ); - $section_data = $profile->$section; + $section_data = $profile->{$section->value}; $data_count = $section_data->count(); - $per_page = ProfileDataCard::PER_PAGE_FOR_SECTION[$section]; + $per_page = $section->perPage(); - $this->assertDatabaseHas('profile_data', ['type' => $section]); + $this->assertDatabaseHas('profile_data', ['type' => $section->value]); $this->assertIsIterable($section_data); $this->assertGreaterThanOrEqual($per_page, $data_count); - $component = Livewire::test(ProfileDataCard::class, ['profile' => $profile, 'editable' => $editable, 'data_type' => $section ]) - ->assertSet('data_type', $section) + $component = Livewire::test(ProfileDataCard::class, ['profile' => $profile, 'editable' => $editable, 'data_type' => $section_opt]) + ->assertSet('data_type', $section_opt) ->assertViewHas('data') - ->assertSeeHtmlInOrder(["
", '

', '
'] ); + ->assertSeeHtmlInOrder(["
", '

', '
']); - if ($section === 'additionals') { + if ($section_opt === 'additionals') { $component->assertSee('Additional Information'); } else { - $component->assertSee(ucwords($section)); + $component->assertSee(ucwords($section->value)); } $first_page_items_count = $data_count >= $per_page ? $per_page : $data_count; @@ -80,8 +85,8 @@ public function testPaginatedItemsOnFirstAndLastPage() $this->assertIsIterable($component->lastRenderedView->data); $this->assertCount($first_page_items_count, $component->lastRenderedView->data); - $component->call('gotoPage', $component->lastRenderedView->data->lastPage(), $section) - ->assertSet('data_type', $section) + $component->call('gotoPage', $component->lastRenderedView->data->lastPage(), $section_opt) + ->assertSet('data_type', $section_opt) ->assertViewHas('data'); $last_page_items_count = fmod($data_count, $per_page) > 0 ? fmod($data_count, $per_page) : $per_page; @@ -150,4 +155,31 @@ public function testPaginatedItemsOnSecondPage() } } + /** + * Test profile section type value + * + * @return void + */ + public function testProfileSectionType() + { + $profile = Profile::factory()->hasData()->create(); + + $section = 'wrong_data_type_value'; + + $invalid_section = ProfileSectionType::tryFrom($section); + + $this->assertNull($invalid_section, 'Invalid section'); + + $component = Livewire::test(ProfileDataCard::class, ['profile' => $profile, 'editable' => true, 'data_type' => 'news']) + ->assertHasNoErrors() + ->assertViewIs("livewire.profile-data-cards.news"); + + $component + ->set('data_type', $section) + ->assertHasErrors('data_type') + ->assertDontSee('data') + ->assertEmitted('alert', 'Invalid section.', 'danger') + ->assertDontSeeHtml("
", '

', '
'); + } + } \ No newline at end of file