From 485ebcc150a6ac725f85767cec1953f71344e956 Mon Sep 17 00:00:00 2001 From: laurell seville Date: Thu, 14 Nov 2024 20:18:26 +0000 Subject: [PATCH 1/8] feat, show preview of avatar style --- .../UserPreferencesIndexViewHelper.php | 11 ++ .../js/Pages/Settings/Preferences/Index.vue | 4 + .../Preferences/Partials/AvatarStyles.vue | 134 ++++++++++++++++++ resources/js/Shared/Avatar.vue | 1 + 4 files changed, 150 insertions(+) create mode 100644 resources/js/Pages/Settings/Preferences/Partials/AvatarStyles.vue diff --git a/app/Domains/Settings/ManageUserPreferences/Web/ViewHelpers/UserPreferencesIndexViewHelper.php b/app/Domains/Settings/ManageUserPreferences/Web/ViewHelpers/UserPreferencesIndexViewHelper.php index 65ecf1f7056..7e896f2c01b 100644 --- a/app/Domains/Settings/ManageUserPreferences/Web/ViewHelpers/UserPreferencesIndexViewHelper.php +++ b/app/Domains/Settings/ManageUserPreferences/Web/ViewHelpers/UserPreferencesIndexViewHelper.php @@ -13,6 +13,7 @@ class UserPreferencesIndexViewHelper public static function data(User $user): array { return [ + 'contact_avatar' => self::dtoContactAvatar($user), 'help' => self::dtoHelp($user), 'name_order' => self::dtoNameOrder($user), 'date_format' => self::dtoDateFormat($user), @@ -38,6 +39,16 @@ public static function dtoHelp(User $user): array ]; } + public static function dtoContactAvatar(User $user): array + { + $contact = new Contact([ + 'first_name' => $user->first_name, + 'last_name' => $user->last_name, + ]); + + return $contact->avatar; + } + public static function dtoNameOrder(User $user): array { $contact = new Contact([ diff --git a/resources/js/Pages/Settings/Preferences/Index.vue b/resources/js/Pages/Settings/Preferences/Index.vue index 6cd2057a5e8..7062c74f5ce 100644 --- a/resources/js/Pages/Settings/Preferences/Index.vue +++ b/resources/js/Pages/Settings/Preferences/Index.vue @@ -33,6 +33,8 @@
+ + @@ -64,9 +66,11 @@ import Timezone from '@/Pages/Settings/Preferences/Partials/Timezone.vue'; import Maps from '@/Pages/Settings/Preferences/Partials/Maps.vue'; import Locale from '@/Pages/Settings/Preferences/Partials/Locale.vue'; import HelpPreference from '@/Pages/Settings/Preferences/Partials/HelpPreference.vue'; +import AvatarStyles from '@/Pages/Settings/Preferences/Partials/AvatarStyles.vue'; export default { components: { + AvatarStyles, InertiaLink: Link, Layout, NameOrder, diff --git a/resources/js/Pages/Settings/Preferences/Partials/AvatarStyles.vue b/resources/js/Pages/Settings/Preferences/Partials/AvatarStyles.vue new file mode 100644 index 00000000000..bc5d39d580d --- /dev/null +++ b/resources/js/Pages/Settings/Preferences/Partials/AvatarStyles.vue @@ -0,0 +1,134 @@ + + + + + diff --git a/resources/js/Shared/Avatar.vue b/resources/js/Shared/Avatar.vue index 57b496afee6..4bec3561f04 100644 --- a/resources/js/Shared/Avatar.vue +++ b/resources/js/Shared/Avatar.vue @@ -7,5 +7,6 @@ defineProps({ From a9d1df9e6660b926ae77c2e2f5c181deaea68864 Mon Sep 17 00:00:00 2001 From: laurell seville Date: Thu, 14 Nov 2024 23:40:21 +0000 Subject: [PATCH 2/8] feat, implement dicebear avatar logic --- .../Services/StoreAvatarStylePreference.php | 53 +++++++++++++++++++ .../PreferencesAvatarStyleController.php | 27 ++++++++++ .../UserPreferencesIndexViewHelper.php | 14 +++-- app/Helpers/AvatarHelper.php | 28 ++++++++-- app/Models/Contact.php | 13 +++-- app/Models/User.php | 1 + ...11_14_225521_add_avatar_style_to_users.php | 28 ++++++++++ .../js/Pages/Settings/Preferences/Index.vue | 2 +- .../Preferences/Partials/AvatarStyles.vue | 37 +++++++------ routes/web.php | 2 + tests/Unit/Helpers/AvatarHelperTest.php | 37 +++++++++++-- 11 files changed, 202 insertions(+), 40 deletions(-) create mode 100644 app/Domains/Settings/ManageUserPreferences/Services/StoreAvatarStylePreference.php create mode 100644 app/Domains/Settings/ManageUserPreferences/Web/Controllers/PreferencesAvatarStyleController.php create mode 100644 database/migrations/2024_11_14_225521_add_avatar_style_to_users.php diff --git a/app/Domains/Settings/ManageUserPreferences/Services/StoreAvatarStylePreference.php b/app/Domains/Settings/ManageUserPreferences/Services/StoreAvatarStylePreference.php new file mode 100644 index 00000000000..0a1d45a88a5 --- /dev/null +++ b/app/Domains/Settings/ManageUserPreferences/Services/StoreAvatarStylePreference.php @@ -0,0 +1,53 @@ + 'required|uuid|exists:accounts,id', + 'author_id' => 'required|uuid|exists:users,id', + 'avatar_style' => 'nullable|string', + ]; + } + + /** + * Get the permissions that apply to the user calling the service. + */ + public function permissions(): array + { + return [ + 'author_must_belong_to_account', + ]; + } + + /** + * Saves the avatar style preferences. + * Determines which dicebear style is used to generate avatar's across the app for this user. + */ + public function execute(array $data): User + { + $this->data = $data; + + $this->validateRules($data); + $this->updateUser(); + + return $this->author; + } + + private function updateUser(): void + { + $this->author->avatar_style = $this->data['avatar_style']; + $this->author->save(); + } +} diff --git a/app/Domains/Settings/ManageUserPreferences/Web/Controllers/PreferencesAvatarStyleController.php b/app/Domains/Settings/ManageUserPreferences/Web/Controllers/PreferencesAvatarStyleController.php new file mode 100644 index 00000000000..7fa65305770 --- /dev/null +++ b/app/Domains/Settings/ManageUserPreferences/Web/Controllers/PreferencesAvatarStyleController.php @@ -0,0 +1,27 @@ + Auth::user()->account_id, + 'author_id' => Auth::id(), + 'avatar_style' => $request->input('avatarStyle'), + ]; + + (new StoreAvatarStylePreference)->execute($request); + + return response()->json([ + 'data' => UserPreferencesIndexViewHelper::dtoAvatarStyle(Auth::user()), + ], 200); + } +} diff --git a/app/Domains/Settings/ManageUserPreferences/Web/ViewHelpers/UserPreferencesIndexViewHelper.php b/app/Domains/Settings/ManageUserPreferences/Web/ViewHelpers/UserPreferencesIndexViewHelper.php index 7e896f2c01b..a64786b1c3c 100644 --- a/app/Domains/Settings/ManageUserPreferences/Web/ViewHelpers/UserPreferencesIndexViewHelper.php +++ b/app/Domains/Settings/ManageUserPreferences/Web/ViewHelpers/UserPreferencesIndexViewHelper.php @@ -2,6 +2,7 @@ namespace App\Domains\Settings\ManageUserPreferences\Web\ViewHelpers; +use App\Helpers\AvatarHelper; use App\Helpers\MonetaryNumberHelper; use App\Helpers\NameHelper; use App\Models\Contact; @@ -13,7 +14,7 @@ class UserPreferencesIndexViewHelper public static function data(User $user): array { return [ - 'contact_avatar' => self::dtoContactAvatar($user), + 'avatar_style' => self::dtoAvatarStyle($user), 'help' => self::dtoHelp($user), 'name_order' => self::dtoNameOrder($user), 'date_format' => self::dtoDateFormat($user), @@ -39,14 +40,21 @@ public static function dtoHelp(User $user): array ]; } - public static function dtoContactAvatar(User $user): array + public static function dtoAvatarStyle(User $user): array { $contact = new Contact([ 'first_name' => $user->first_name, 'last_name' => $user->last_name, ]); - return $contact->avatar; + return [ + 'url' => [ + 'store' => route('settings.preferences.avatar-style.store'), + ], + 'style' => $user->avatar_style, + 'avatar' => $contact->avatar, + 'default_avatar' => AvatarHelper::generateRandomAvatar($contact), + ]; } public static function dtoNameOrder(User $user): array diff --git a/app/Helpers/AvatarHelper.php b/app/Helpers/AvatarHelper.php index d3c199bf7e0..dda000fc889 100644 --- a/app/Helpers/AvatarHelper.php +++ b/app/Helpers/AvatarHelper.php @@ -11,21 +11,39 @@ class AvatarHelper /** * Generate a new random avatar. * - * The Multiavatar library takes a name to generate a unique avatar. + * If the user has an avatar_style value set from his settings page the Dicebear + * avatar library will be used, otherwise it defaults to Multiavatar. + * + * The Multiavatar and Dicebear libraries take a name to generate a unique avatar. * However, contacts can be created in Monica without a name. When this case * happens, we'll generate a fake name for the contact, and generate an avatar * based on that name. */ - public static function generateRandomAvatar(Contact $contact): string + public static function generateRandomAvatar(Contact $contact, $avatarStyle = null): array { - $multiavatar = new MultiAvatar; - if (is_null($contact->first_name)) { $name = Faker::create()->name(); } else { $name = $contact->first_name.' '.$contact->last_name; } - return $multiavatar($name, null, null); + if ($avatarStyle) { + return [ + 'type' => Contact::AVATAR_TYPE_URL, + 'content' => self::getDicebearLink($avatarStyle, $name), + ]; + } else { + $multiavatar = new MultiAvatar; + + return [ + 'type' => Contact::AVATAR_TYPE_SVG, + 'content' => $multiavatar($name, null, null), + ]; + } + } + + public static function getDicebearLink($avatarStyle, $name) + { + return "https://api.dicebear.com/9.x/{$avatarStyle}/svg?seed={$name}"; } } diff --git a/app/Models/Contact.php b/app/Models/Contact.php index 623015e84ff..8fb0cac3c0b 100644 --- a/app/Models/Contact.php +++ b/app/Models/Contact.php @@ -436,18 +436,17 @@ protected function avatar(): Attribute { return Attribute::make( get: function ($value) { - $type = self::AVATAR_TYPE_SVG; - $content = AvatarHelper::generateRandomAvatar($this); - if ($this->file) { $type = self::AVATAR_TYPE_URL; $content = 'https://ucarecdn.com/'.$this->file->uuid.'/-/scale_crop/300x300/smart/-/format/auto/-/quality/smart_retina/'; + + return [ + 'type' => $type, + 'content' => $content, + ]; } - return [ - 'type' => $type, - 'content' => $content, - ]; + return AvatarHelper::generateRandomAvatar($this, Auth::user()->avatar_style); } ); } diff --git a/app/Models/User.php b/app/Models/User.php index 6d8960128ab..d817eae76e3 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -100,6 +100,7 @@ class User extends Authenticatable implements HasLocalePreference, MustVerifyEma 'locale', 'help_shown', 'contact_sort_order', + 'avatar_style', ]; /** diff --git a/database/migrations/2024_11_14_225521_add_avatar_style_to_users.php b/database/migrations/2024_11_14_225521_add_avatar_style_to_users.php new file mode 100644 index 00000000000..457d8c7c29d --- /dev/null +++ b/database/migrations/2024_11_14_225521_add_avatar_style_to_users.php @@ -0,0 +1,28 @@ +string('avatar_style')->nullable()->after('help_shown'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('users', function (Blueprint $table) { + $table->dropColumn('avatar_style'); + }); + } +}; diff --git a/resources/js/Pages/Settings/Preferences/Index.vue b/resources/js/Pages/Settings/Preferences/Index.vue index 7062c74f5ce..cbcc61ee0f8 100644 --- a/resources/js/Pages/Settings/Preferences/Index.vue +++ b/resources/js/Pages/Settings/Preferences/Index.vue @@ -33,7 +33,7 @@
- + diff --git a/resources/js/Pages/Settings/Preferences/Partials/AvatarStyles.vue b/resources/js/Pages/Settings/Preferences/Partials/AvatarStyles.vue index bc5d39d580d..76d543cea94 100644 --- a/resources/js/Pages/Settings/Preferences/Partials/AvatarStyles.vue +++ b/resources/js/Pages/Settings/Preferences/Partials/AvatarStyles.vue @@ -81,7 +81,7 @@ export default { 'adventurer-neutral', 'avataaars', 'avataaars-neutral', // TODO: add all current styles - ], // The dicebear documentation does not seem to have an api link that lists all styles + ], // Dicebear does not have an endpoint that lists all styles loadingState: '', editMode: false, form: { @@ -97,14 +97,12 @@ export default { type: 'dicebear', content: `https://api.dicebear.com/9.x/${this.form.avatarStyle}/svg?seed=${this.$page.props.auth.user?.name}`, }; - console.log(this.data); - return this.form.avatarStyle ? dicebearAvatar : this.data; + return this.form.avatarStyle ? dicebearAvatar : this.data.default_avatar; }, }, mounted() { - // TODO: pass data to component and get avatar style if it exists - // this.form.avatarStyle = this.data.avatarStyle; + this.form.avatarStyle = this.data.style; }, methods: { @@ -112,20 +110,21 @@ export default { this.editMode = true; }, submit() { - // this.loadingState = 'loading'; - // TODO: handle avatar style change logic - // axios - // .post(this.data.url.store, this.form) - // .then((response) => { - // this.flash(this.$t('Changes saved'), 'success'); - // this.localTimezone = response.data.data.timezone; - // this.editMode = false; - // this.loadingState = null; - // }) - // .catch((error) => { - // this.loadingState = null; - // this.form.errors = error.response.data; - // }); + this.loadingState = 'loading'; + + axios + .post(this.data.url.store, this.form) + .then((response) => { + this.flash(this.$t('Changes saved'), 'success'); + + this.avatarStyle = response.data.data.style; + this.editMode = false; + this.loadingState = null; + }) + .catch((error) => { + this.loadingState = null; + this.form.errors = error.response.data; + }); }, }, }; diff --git a/routes/web.php b/routes/web.php index 07ebc096e84..e2e571dfc67 100644 --- a/routes/web.php +++ b/routes/web.php @@ -85,6 +85,7 @@ use App\Domains\Settings\ManageTemplates\Web\Controllers\PersonalizeTemplatePagePositionController; use App\Domains\Settings\ManageTemplates\Web\Controllers\PersonalizeTemplatePagesController; use App\Domains\Settings\ManageTemplates\Web\Controllers\PersonalizeTemplatesController; +use App\Domains\Settings\ManageUserPreferences\Web\Controllers\PreferencesAvatarStyleController; use App\Domains\Settings\ManageUserPreferences\Web\Controllers\PreferencesController; use App\Domains\Settings\ManageUserPreferences\Web\Controllers\PreferencesDateFormatController; use App\Domains\Settings\ManageUserPreferences\Web\Controllers\PreferencesDistanceFormatController; @@ -556,6 +557,7 @@ Route::post('maps', [PreferencesMapsPreferenceController::class, 'store'])->name('maps.store'); Route::post('locale', [PreferencesLocaleController::class, 'store'])->name('locale.store'); Route::post('help', [PreferencesHelpController::class, 'store'])->name('help.store'); + Route::post('avatar-style', [PreferencesAvatarStyleController::class, 'store'])->name('avatar-style.store'); }); // notifications diff --git a/tests/Unit/Helpers/AvatarHelperTest.php b/tests/Unit/Helpers/AvatarHelperTest.php index 264c23dbcac..61ba6a543af 100644 --- a/tests/Unit/Helpers/AvatarHelperTest.php +++ b/tests/Unit/Helpers/AvatarHelperTest.php @@ -11,19 +11,46 @@ class AvatarHelperTest extends TestCase { use DatabaseTransactions; + public function it_creates_an_multiavatar_for_a_contact_with_a_name(): void + { + $contact = Contact::factory()->create([ + 'first_name' => 'Regis', + 'last_name' => 'Troyat', + ]); + + // Multiavatar test + $avatar = AvatarHelper::generateRandomAvatar($contact); + + $this->assertEquals([ + 'type' => Contact::AVATAR_TYPE_SVG, + 'content' => '', + ], $avatar); + } + /** @test */ - public function it_creates_an_avatar_for_a_contact_with_a_name(): void + public function it_creates_an_dicebear_for_a_contact_with_a_name(): void { $contact = Contact::factory()->create([ 'first_name' => 'Regis', 'last_name' => 'Troyat', ]); + // Multiavatar test $avatar = AvatarHelper::generateRandomAvatar($contact); - $this->assertEquals( - '', - $avatar - ); + $this->assertEquals([ + 'type' => Contact::AVATAR_TYPE_SVG, + 'content' => '', + ], $avatar); + + // Dicebear test + $avatarStyle = 'dicebear-placeholder-style'; + $avatar = AvatarHelper::generateRandomAvatar($contact, $avatarStyle); + $name = AvatarHelper::getName($contact); + + $this->assertEquals([ + 'type' => Contact::AVATAR_TYPE_URL, + 'content' => AvatarHelper::getDicebearLink($avatarStyle, $name), + ], $avatar); } } From 3f8f77f7bd0a648dc3796e8255ec143a008b6aad Mon Sep 17 00:00:00 2001 From: laurell seville Date: Thu, 14 Nov 2024 23:50:56 +0000 Subject: [PATCH 3/8] feat, add all current art styles --- .../Preferences/Partials/AvatarStyles.vue | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/resources/js/Pages/Settings/Preferences/Partials/AvatarStyles.vue b/resources/js/Pages/Settings/Preferences/Partials/AvatarStyles.vue index 76d543cea94..07025e6e53b 100644 --- a/resources/js/Pages/Settings/Preferences/Partials/AvatarStyles.vue +++ b/resources/js/Pages/Settings/Preferences/Partials/AvatarStyles.vue @@ -80,7 +80,33 @@ export default { 'adventurer', 'adventurer-neutral', 'avataaars', - 'avataaars-neutral', // TODO: add all current styles + 'avataaars-neutral', + 'big-ears', + 'big-ears-neutral', + 'big-smile', + 'bottts', + 'bottts-neutral', + 'croodles', + 'croodles-neutral', + 'dylan', + 'fun-emoji', + 'glass', + 'icons', + 'identicon', + 'initials', + 'lorelei', + 'lorelei-neutral', + 'micah', + 'miniavs', + 'notionists', + 'notionists-neutral', + 'open-peeps', + 'personas', + 'pixel-art', + 'pixel-art-neutral', + 'rings', + 'shapes', + 'thumbs', ], // Dicebear does not have an endpoint that lists all styles loadingState: '', editMode: false, From b247b0bc3961f378eb6b19d1cc5558666bddd77a Mon Sep 17 00:00:00 2001 From: laurell seville Date: Thu, 14 Nov 2024 23:51:35 +0000 Subject: [PATCH 4/8] fix, remove todos --- .../js/Pages/Settings/Preferences/Partials/AvatarStyles.vue | 2 -- 1 file changed, 2 deletions(-) diff --git a/resources/js/Pages/Settings/Preferences/Partials/AvatarStyles.vue b/resources/js/Pages/Settings/Preferences/Partials/AvatarStyles.vue index 07025e6e53b..5b8eb8339ff 100644 --- a/resources/js/Pages/Settings/Preferences/Partials/AvatarStyles.vue +++ b/resources/js/Pages/Settings/Preferences/Partials/AvatarStyles.vue @@ -31,7 +31,6 @@
- -
From a03209461caff5e87521134faf6b21891ae64e17 Mon Sep 17 00:00:00 2001 From: laurell seville Date: Fri, 15 Nov 2024 00:00:33 +0000 Subject: [PATCH 5/8] fix: remove else --- app/Helpers/AvatarHelper.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/app/Helpers/AvatarHelper.php b/app/Helpers/AvatarHelper.php index dda000fc889..611d51c41fd 100644 --- a/app/Helpers/AvatarHelper.php +++ b/app/Helpers/AvatarHelper.php @@ -32,14 +32,14 @@ public static function generateRandomAvatar(Contact $contact, $avatarStyle = nul 'type' => Contact::AVATAR_TYPE_URL, 'content' => self::getDicebearLink($avatarStyle, $name), ]; - } else { - $multiavatar = new MultiAvatar; - - return [ - 'type' => Contact::AVATAR_TYPE_SVG, - 'content' => $multiavatar($name, null, null), - ]; } + + $multiavatar = new MultiAvatar; + + return [ + 'type' => Contact::AVATAR_TYPE_SVG, + 'content' => $multiavatar($name, null, null), + ]; } public static function getDicebearLink($avatarStyle, $name) From 435bae7e58362855ea94dfbadb363082b53d9b76 Mon Sep 17 00:00:00 2001 From: laurell seville Date: Fri, 15 Nov 2024 00:04:01 +0000 Subject: [PATCH 6/8] feat: add service test --- .../StoreAvatarStylePreferenceTest.php | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 tests/Unit/Domains/Settings/ManageUserPreferences/Services/StoreAvatarStylePreferenceTest.php diff --git a/tests/Unit/Domains/Settings/ManageUserPreferences/Services/StoreAvatarStylePreferenceTest.php b/tests/Unit/Domains/Settings/ManageUserPreferences/Services/StoreAvatarStylePreferenceTest.php new file mode 100644 index 00000000000..916cd9eac4c --- /dev/null +++ b/tests/Unit/Domains/Settings/ManageUserPreferences/Services/StoreAvatarStylePreferenceTest.php @@ -0,0 +1,68 @@ +createUser(); + $this->executeService($ross, $ross->account); + } + + /** @test */ + public function it_fails_if_wrong_parameters_are_given(): void + { + $request = [ + 'title' => 'Ross', + ]; + + $this->expectException(ValidationException::class); + (new StoreAvatarStylePreference)->execute($request); + } + + /** @test */ + public function it_fails_if_user_doesnt_belong_to_account(): void + { + $this->expectException(ModelNotFoundException::class); + + $ross = $this->createAdministrator(); + $account = $this->createAccount(); + $this->executeService($ross, $account); + } + + private function executeService(User $author, Account $account): void + { + $avatarStyle = 'placeholder-dicebear-style'; + + $request = [ + 'account_id' => $account->id, + 'author_id' => $author->id, + 'avatar_style' => $avatarStyle, + ]; + + $user = (new StoreAvatarStylePreference)->execute($request); + + $this->assertDatabaseHas('users', [ + 'id' => $user->id, + 'account_id' => $account->id, + 'avatar_style' => $avatarStyle, + ]); + + $this->assertInstanceOf( + User::class, + $user + ); + } +} From aa0b5ff8507acf5c995356fdc076355f3b1b8826 Mon Sep 17 00:00:00 2001 From: laurell seville Date: Fri, 15 Nov 2024 00:08:03 +0000 Subject: [PATCH 7/8] fix: remove new avatar type --- .../js/Pages/Settings/Preferences/Partials/AvatarStyles.vue | 2 +- resources/js/Shared/Avatar.vue | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/resources/js/Pages/Settings/Preferences/Partials/AvatarStyles.vue b/resources/js/Pages/Settings/Preferences/Partials/AvatarStyles.vue index 5b8eb8339ff..b44d40c9489 100644 --- a/resources/js/Pages/Settings/Preferences/Partials/AvatarStyles.vue +++ b/resources/js/Pages/Settings/Preferences/Partials/AvatarStyles.vue @@ -118,7 +118,7 @@ export default { computed: { avatarData() { const dicebearAvatar = { - type: 'dicebear', + type: 'url', content: `https://api.dicebear.com/9.x/${this.form.avatarStyle}/svg?seed=${this.$page.props.auth.user?.name}`, }; return this.form.avatarStyle ? dicebearAvatar : this.data.default_avatar; diff --git a/resources/js/Shared/Avatar.vue b/resources/js/Shared/Avatar.vue index 4bec3561f04..57b496afee6 100644 --- a/resources/js/Shared/Avatar.vue +++ b/resources/js/Shared/Avatar.vue @@ -7,6 +7,5 @@ defineProps({ From 9da17d2e99c8917266f7406aed8b7f5762a0af84 Mon Sep 17 00:00:00 2001 From: laurell seville Date: Fri, 15 Nov 2024 00:17:04 +0000 Subject: [PATCH 8/8] test: update helper test --- app/Models/Contact.php | 2 +- .../UserPreferencesIndexViewHelperTest.php | 34 ++++++++++++++++++- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/app/Models/Contact.php b/app/Models/Contact.php index 8fb0cac3c0b..3aeb928a80f 100644 --- a/app/Models/Contact.php +++ b/app/Models/Contact.php @@ -446,7 +446,7 @@ protected function avatar(): Attribute ]; } - return AvatarHelper::generateRandomAvatar($this, Auth::user()->avatar_style); + return AvatarHelper::generateRandomAvatar($this, Auth::user()?->avatar_style); } ); } diff --git a/tests/Unit/Domains/Settings/ManageUserPreferences/Web/ViewHelpers/UserPreferencesIndexViewHelperTest.php b/tests/Unit/Domains/Settings/ManageUserPreferences/Web/ViewHelpers/UserPreferencesIndexViewHelperTest.php index 33d3c7c4a0a..c3bf9b5a511 100644 --- a/tests/Unit/Domains/Settings/ManageUserPreferences/Web/ViewHelpers/UserPreferencesIndexViewHelperTest.php +++ b/tests/Unit/Domains/Settings/ManageUserPreferences/Web/ViewHelpers/UserPreferencesIndexViewHelperTest.php @@ -3,6 +3,8 @@ namespace Tests\Unit\Domains\Settings\ManageUserPreferences\Web\ViewHelpers; use App\Domains\Settings\ManageUserPreferences\Web\ViewHelpers\UserPreferencesIndexViewHelper; +use App\Helpers\AvatarHelper; +use App\Models\Contact; use App\Models\User; use Carbon\Carbon; use Illuminate\Foundation\Testing\DatabaseTransactions; @@ -25,10 +27,11 @@ public function it_gets_the_data_needed_for_the_view(): void $array = UserPreferencesIndexViewHelper::data($user); $this->assertEquals( - 9, + 10, count($array) ); + $this->assertArrayHasKey('avatar_style', $array); $this->assertArrayHasKey('help', $array); $this->assertArrayHasKey('name_order', $array); $this->assertArrayHasKey('date_format', $array); @@ -48,6 +51,35 @@ public function it_gets_the_data_needed_for_the_view(): void ); } + /** @test */ + public function it_gets_the_data_needed_for_avatar_style(): void + { + $avatarStyle = 'placeholder-dicebear-style'; + + $user = User::factory()->create([ + 'avatar_style' => $avatarStyle, + ]); + + $array = UserPreferencesIndexViewHelper::dtoAvatarStyle($user); + + $contact = new Contact([ + 'first_name' => $user->first_name, + 'last_name' => $user->last_name, + ]); + + $this->assertEquals( + [ + 'url' => [ + 'store' => env('APP_URL').'/settings/preferences/avatar-style', + ], + 'style' => $avatarStyle, + 'avatar' => $contact->avatar, + 'default_avatar' => AvatarHelper::generateRandomAvatar($contact), + ], + $array + ); + } + /** @test */ public function it_gets_the_data_needed_for_help(): void {