From 19808d43113061dd57312d92ab7e5ac25996f783 Mon Sep 17 00:00:00 2001 From: Wes Copeland Date: Sat, 18 Jan 2025 11:39:35 -0500 Subject: [PATCH] feat(home): show user's current AOTW unlock status (#3054) --- .../BuildAchievementOfTheWeekDataAction.php | 34 +++++--- app/Http/Controllers/HomeController.php | 7 +- .../Data/AchievementOfTheWeekPropsData.php | 19 +++++ app/Http/Data/HomePagePropsData.php | 3 +- app/Models/Event.php | 10 +++ app/Models/EventAchievement.php | 25 ++++++ .../factories/EventAchievementFactory.php | 30 +++++++ database/factories/EventFactory.php | 33 ++++++++ public/API/API_GetAchievementOfTheWeek.php | 5 +- .../AchievementOfTheWeek.test.tsx | 83 +++++++++++++------ .../AchievementOfTheWeek.tsx | 37 ++++++--- .../AotwUnlockedIndicator.test.tsx | 60 ++++++++++++++ .../AotwUnlockedIndicator.tsx | 20 +++++ .../AotwUnlockedIndicator/index.ts | 1 + .../createAchievementOfTheWeekProps.ts | 11 +++ .../createHomePageProps.ts | 4 +- .../factories/createHomePageProps/index.ts | 1 + resources/js/types/generated.d.ts | 25 +++--- resources/js/ziggy.d.ts | 43 ++++------ .../Http/Controllers/HomeControllerTest.php | 20 ++--- 20 files changed, 365 insertions(+), 106 deletions(-) create mode 100644 app/Http/Data/AchievementOfTheWeekPropsData.php create mode 100644 database/factories/EventAchievementFactory.php create mode 100644 database/factories/EventFactory.php create mode 100644 resources/js/features/home/components/+sidebar/AchievementOfTheWeek/AotwUnlockedIndicator/AotwUnlockedIndicator.test.tsx create mode 100644 resources/js/features/home/components/+sidebar/AchievementOfTheWeek/AotwUnlockedIndicator/AotwUnlockedIndicator.tsx create mode 100644 resources/js/features/home/components/+sidebar/AchievementOfTheWeek/AotwUnlockedIndicator/index.ts create mode 100644 resources/js/test/factories/createHomePageProps/createAchievementOfTheWeekProps.ts diff --git a/app/Http/Actions/BuildAchievementOfTheWeekDataAction.php b/app/Http/Actions/BuildAchievementOfTheWeekDataAction.php index 0457d27c9c..873cc7e5a8 100644 --- a/app/Http/Actions/BuildAchievementOfTheWeekDataAction.php +++ b/app/Http/Actions/BuildAchievementOfTheWeekDataAction.php @@ -4,28 +4,24 @@ namespace App\Http\Actions; +use App\Http\Data\AchievementOfTheWeekPropsData; use App\Models\EventAchievement; +use App\Models\User; use App\Platform\Data\EventAchievementData; class BuildAchievementOfTheWeekDataAction { - public function execute(): ?EventAchievementData + public function execute(?User $user = null): ?AchievementOfTheWeekPropsData { - $achievementOfTheWeek = EventAchievement::active() - ->whereNotNull('active_from') - ->whereNotNull('active_until') - ->whereHas('achievement.game', function ($query) { // only from the current AotW event - $query->where('Title', 'like', '%of the week%'); - }) - ->whereRaw(dateCompareStatement('active_until', 'active_from', '< 20')) // ignore AotM achievements - don't specifically look for 7 days because of the extended duration of the week 52 event - ->with(['achievement.game', 'sourceAchievement.game']) + $achievementOfTheWeek = EventAchievement::currentAchievementOfTheWeek() + ->with(['event', 'achievement.game', 'sourceAchievement.game']) ->first(); - if (!$achievementOfTheWeek?->source_achievement_id) { + if (!$achievementOfTheWeek?->sourceAchievement) { return null; } - $data = EventAchievementData::from($achievementOfTheWeek)->include( + $currentEventAchievementData = EventAchievementData::from($achievementOfTheWeek)->include( 'achievement.id', 'achievement.title', 'achievement.description', @@ -38,6 +34,20 @@ public function execute(): ?EventAchievementData 'activeUntil', ); - return $data; + return new AchievementOfTheWeekPropsData( + currentEventAchievement: $currentEventAchievementData, + doesUserHaveUnlock: $this->getDoesUserHaveUnlock($user, $achievementOfTheWeek), + ); + } + + private function getDoesUserHaveUnlock(?User $user, EventAchievement $achievementOfTheWeek): bool + { + if (!$user) { + return false; + } + + return $user->playerAchievements() + ->whereAchievementId($achievementOfTheWeek->achievement_id) + ->exists(); } } diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index 1f035fe090..9916959e86 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -38,10 +38,13 @@ public function index( BuildHomePageClaimsDataAction $buildHomePageClaimsData, BuildThinRecentForumPostsDataAction $buildThinRecentForumPostsData, ): InertiaResponse { + /** @var ?User $user */ + $user = Auth::user(); + $staticData = StaticData::first(); $staticDataData = StaticDataData::fromStaticData($staticData); - $achievementOfTheWeek = $buildAchievementOfTheWeekData->execute(); + $achievementOfTheWeek = $buildAchievementOfTheWeekData->execute($user); $mostRecentGameMastered = $buildMostRecentGameAwardData->execute($staticData, AwardType::Mastery); $mostRecentGameBeaten = $buildMostRecentGameAwardData->execute($staticData, AwardType::GameBeaten); $recentNews = $buildNewsData->execute(); @@ -53,8 +56,6 @@ public function index( $activePlayers = $buildActivePlayers->execute(perPage: 20, search: $persistedActivePlayersSearch); $trendingGames = $buildTrendingGames->execute(); - /** @var ?User $user */ - $user = Auth::user(); $permissions = $user ? (int) $user->getAttribute('Permissions') : Permissions::Unregistered; $recentForumPosts = $buildThinRecentForumPostsData->execute( permissions: $permissions, diff --git a/app/Http/Data/AchievementOfTheWeekPropsData.php b/app/Http/Data/AchievementOfTheWeekPropsData.php new file mode 100644 index 0000000000..4081fc881e --- /dev/null +++ b/app/Http/Data/AchievementOfTheWeekPropsData.php @@ -0,0 +1,19 @@ + */ + use HasFactory; + use LogsActivity { LogsActivity::activities as auditLog; } @@ -39,6 +44,11 @@ class Event extends BaseModel 'active_through', ]; + protected static function newFactory(): EventFactory + { + return EventFactory::new(); + } + // == logging public function getActivitylogOptions(): LogOptions diff --git a/app/Models/EventAchievement.php b/app/Models/EventAchievement.php index 0dcbf59421..e1d0d2ed4e 100644 --- a/app/Models/EventAchievement.php +++ b/app/Models/EventAchievement.php @@ -6,7 +6,9 @@ use App\Support\Database\Eloquent\BaseModel; use Carbon\Carbon; +use Database\Factories\EventAchievementFactory; use Illuminate\Database\Eloquent\Builder; +use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\HasOneThrough; use Spatie\Activitylog\LogOptions; @@ -14,6 +16,9 @@ class EventAchievement extends BaseModel { + /** @use HasFactory */ + use HasFactory; + use LogsActivity { LogsActivity::activities as auditLog; } @@ -37,6 +42,11 @@ class EventAchievement extends BaseModel 'active_through', ]; + protected static function newFactory(): EventAchievementFactory + { + return EventAchievementFactory::new(); + } + public const RAEVENTS_USER_ID = 279854; public const DEVQUEST_USER_ID = 240336; @@ -112,6 +122,21 @@ public function sourceAchievement(): BelongsTo // == scopes + /** + * @param Builder $query + * @return Builder + */ + public function scopeCurrentAchievementOfTheWeek(Builder $query): Builder + { + return $query->active() + ->whereHas('achievement.game', function ($query) { // only from the current AotW event + $query->where('Title', 'like', '%of the week%'); + }) + ->whereNotNull('active_from') + ->whereNotNull('active_until') + ->whereRaw(dateCompareStatement('active_until', 'active_from', '< 20')); // ignore AotM achievements. + } + /** * @param Builder $query * @return Builder diff --git a/database/factories/EventAchievementFactory.php b/database/factories/EventAchievementFactory.php new file mode 100644 index 0000000000..3f2c5f7de3 --- /dev/null +++ b/database/factories/EventAchievementFactory.php @@ -0,0 +1,30 @@ + + */ +class EventAchievementFactory extends Factory +{ + protected $model = EventAchievement::class; + + /** + * @return array + */ + public function definition(): array + { + return [ + 'achievement_id' => Achievement::factory(), + 'source_achievement_id' => Achievement::factory(), + 'active_from' => now(), + 'active_until' => now()->addWeek(), + ]; + } +} diff --git a/database/factories/EventFactory.php b/database/factories/EventFactory.php new file mode 100644 index 0000000000..76daba48cd --- /dev/null +++ b/database/factories/EventFactory.php @@ -0,0 +1,33 @@ + + */ +class EventFactory extends Factory +{ + protected $model = Event::class; + + /** + * @return array + */ + public function definition(): array + { + $activeFrom = Carbon::instance($this->faker->dateTimeBetween('-1 year', '+1 year')); + + return [ + 'legacy_game_id' => Game::factory(), + 'slug' => $this->faker->unique()->slug(), + 'active_from' => $activeFrom, + 'active_until' => $activeFrom->clone()->addYear(), + ]; + } +} diff --git a/public/API/API_GetAchievementOfTheWeek.php b/public/API/API_GetAchievementOfTheWeek.php index 046f1dcd16..5caba9cd4b 100644 --- a/public/API/API_GetAchievementOfTheWeek.php +++ b/public/API/API_GetAchievementOfTheWeek.php @@ -1,7 +1,6 @@ execute(); -$achievementId = $aotwData->achievement->id ?? 0; +$achievementId = $aotwData->currentEventAchievement->achievement->id ?? 0; $eventAchievement = EventAchievement::active()->where('achievement_id', $achievementId)->first(); if (!$eventAchievement?->sourceAchievement) { @@ -86,7 +85,7 @@ ]; $forumTopic = [ - 'ID' => $aotwData->forumTopicId->resolve() ?? null, + 'ID' => $aotwData->currentEventAchievement->forumTopicId->resolve() ?? null, ]; $unlocks = collect(); diff --git a/resources/js/features/home/components/+sidebar/AchievementOfTheWeek/AchievementOfTheWeek.test.tsx b/resources/js/features/home/components/+sidebar/AchievementOfTheWeek/AchievementOfTheWeek.test.tsx index 8d935c013a..484cac279c 100644 --- a/resources/js/features/home/components/+sidebar/AchievementOfTheWeek/AchievementOfTheWeek.test.tsx +++ b/resources/js/features/home/components/+sidebar/AchievementOfTheWeek/AchievementOfTheWeek.test.tsx @@ -2,6 +2,7 @@ import { createAuthenticatedUser } from '@/common/models'; import { render, screen } from '@/test'; import { createAchievement, + createAchievementOfTheWeekProps, createEventAchievement, createGame, createHomePageProps, @@ -30,7 +31,7 @@ describe('Component: AchievementOfTheWeek', () => { expect(screen.getByRole('heading', { name: /achievement of the week/i })).toBeVisible(); }); - it('given there is no achievement of the week, does not crash', () => { + it('given there is no achievement of the week data, does not crash', () => { // ARRANGE const { container } = render(, { pageProps: createHomePageProps({ achievementOfTheWeek: null }), @@ -40,6 +41,18 @@ describe('Component: AchievementOfTheWeek', () => { expect(container).toBeTruthy(); }); + it('given there is no current event achievement, does not crash', () => { + // ARRANGE + const { container } = render(, { + pageProps: createHomePageProps({ + achievementOfTheWeek: { currentEventAchievement: null } as any, + }), + }); + + // ASSERT + expect(container).toBeTruthy(); + }); + it('displays an accessible link to the event page', () => { // ARRANGE const legacyGame = createGame(); @@ -47,7 +60,9 @@ describe('Component: AchievementOfTheWeek', () => { render(, { pageProps: createHomePageProps({ - achievementOfTheWeek: createEventAchievement({ event }), + achievementOfTheWeek: createAchievementOfTheWeekProps({ + currentEventAchievement: createEventAchievement({ event }), + }), }), }); @@ -64,7 +79,9 @@ describe('Component: AchievementOfTheWeek', () => { render(, { pageProps: createHomePageProps({ - achievementOfTheWeek: createEventAchievement({ event }), + achievementOfTheWeek: createAchievementOfTheWeekProps({ + currentEventAchievement: createEventAchievement({ event }), + }), }), }); @@ -74,8 +91,10 @@ describe('Component: AchievementOfTheWeek', () => { it('has a link to the achievement', () => { // ARRANGE - const achievementOfTheWeek = createEventAchievement({ - achievement: createAchievement({ id: 9, title: 'That Was Easy' }), + const achievementOfTheWeek = createAchievementOfTheWeekProps({ + currentEventAchievement: createEventAchievement({ + achievement: createAchievement({ id: 9, title: 'That Was Easy' }), + }), }); render(, { @@ -94,9 +113,11 @@ describe('Component: AchievementOfTheWeek', () => { const system = createSystem({ name: 'Sega Genesis/Mega Drive', nameShort: 'MD' }); const game = createGame({ system, id: 1, title: 'Sonic the Hedgehog' }); const sourceAchievement = createAchievement({ game, id: 9, title: 'That Was Easy' }); - const achievementOfTheWeek = createEventAchievement({ - achievement: sourceAchievement, - sourceAchievement, + const achievementOfTheWeek = createAchievementOfTheWeekProps({ + currentEventAchievement: createEventAchievement({ + achievement: sourceAchievement, + sourceAchievement, + }), }); render(, { @@ -115,9 +136,11 @@ describe('Component: AchievementOfTheWeek', () => { const system = createSystem({ name: 'Sega Genesis/Mega Drive', nameShort: 'MD' }); const game = createGame({ system, id: 1, title: 'Sonic the Hedgehog' }); const sourceAchievement = createAchievement({ game, id: 9, title: 'That Was Easy' }); - const achievementOfTheWeek = createEventAchievement({ - achievement: sourceAchievement, - sourceAchievement, + const achievementOfTheWeek = createAchievementOfTheWeekProps({ + currentEventAchievement: createEventAchievement({ + achievement: sourceAchievement, + sourceAchievement, + }), }); render(, { @@ -134,9 +157,11 @@ describe('Component: AchievementOfTheWeek', () => { const system = createSystem({ name: 'Sega Genesis/Mega Drive', nameShort: 'MD' }); const game = createGame({ system, id: 1, title: 'Sonic the Hedgehog' }); const sourceAchievement = createAchievement({ game, id: 9, title: 'That Was Easy' }); - const achievementOfTheWeek = createEventAchievement({ - achievement: sourceAchievement, - sourceAchievement, + const achievementOfTheWeek = createAchievementOfTheWeekProps({ + currentEventAchievement: createEventAchievement({ + achievement: sourceAchievement, + sourceAchievement, + }), }); render(, { @@ -157,10 +182,12 @@ describe('Component: AchievementOfTheWeek', () => { title: 'That Was Easy', description: 'foo', }); - const achievementOfTheWeek = createEventAchievement({ - achievement: sourceAchievement, - sourceAchievement, - activeUntil: tomorrow.toISOString(), + const achievementOfTheWeek = createAchievementOfTheWeekProps({ + currentEventAchievement: createEventAchievement({ + achievement: sourceAchievement, + sourceAchievement, + activeUntil: tomorrow.toISOString(), + }), }); render(, { @@ -179,10 +206,12 @@ describe('Component: AchievementOfTheWeek', () => { title: 'That Was Easy', description: 'foo', }); - const achievementOfTheWeek = createEventAchievement({ - achievement: sourceAchievement, - sourceAchievement, - activeUntil: new Date('2030-04-08').toISOString(), + const achievementOfTheWeek = createAchievementOfTheWeekProps({ + currentEventAchievement: createEventAchievement({ + achievement: sourceAchievement, + sourceAchievement, + activeUntil: new Date('2030-04-08').toISOString(), + }), }); render(, { @@ -208,10 +237,12 @@ describe('Component: AchievementOfTheWeek', () => { title: 'That Was Easy', description: 'foo', }); - const achievementOfTheWeek = createEventAchievement({ - achievement: sourceAchievement, - sourceAchievement, - activeUntil: undefined, + const achievementOfTheWeek = createAchievementOfTheWeekProps({ + currentEventAchievement: createEventAchievement({ + achievement: sourceAchievement, + sourceAchievement, + activeUntil: undefined, + }), }); render(, { diff --git a/resources/js/features/home/components/+sidebar/AchievementOfTheWeek/AchievementOfTheWeek.tsx b/resources/js/features/home/components/+sidebar/AchievementOfTheWeek/AchievementOfTheWeek.tsx index 0d5840377c..39cfc5533a 100644 --- a/resources/js/features/home/components/+sidebar/AchievementOfTheWeek/AchievementOfTheWeek.tsx +++ b/resources/js/features/home/components/+sidebar/AchievementOfTheWeek/AchievementOfTheWeek.tsx @@ -11,16 +11,23 @@ import { buildTrackingClassNames } from '@/common/utils/buildTrackingClassNames' import { cn } from '@/common/utils/cn'; import { HomeHeading } from '../../HomeHeading'; +import { AotwUnlockedIndicator } from './AotwUnlockedIndicator'; export const AchievementOfTheWeek: FC = () => { const { achievementOfTheWeek, auth } = usePageProps(); const { t } = useTranslation(); - const game = achievementOfTheWeek?.sourceAchievement?.game; + if (!achievementOfTheWeek) { + return null; + } + + const { currentEventAchievement } = achievementOfTheWeek; + + const game = currentEventAchievement?.sourceAchievement?.game; const system = game?.system; - if (!achievementOfTheWeek?.achievement || !game || !system) { + if (!currentEventAchievement?.achievement || !game || !system) { return null; } @@ -29,11 +36,11 @@ export const AchievementOfTheWeek: FC = () => { {t('Achievement of the Week')}
-
+
-
+
{
- {achievementOfTheWeek.achievement.title} + {currentEventAchievement.achievement.title} -

{achievementOfTheWeek.achievement.description}

+

{currentEventAchievement.achievement.description}

@@ -60,15 +67,15 @@ export const AchievementOfTheWeek: FC = () => {
- {achievementOfTheWeek.activeUntil ? ( + {currentEventAchievement.activeUntil ? ( ), @@ -80,13 +87,17 @@ export const AchievementOfTheWeek: FC = () => {
+ +
+ +
- {achievementOfTheWeek.event?.legacyGame ? ( + {currentEventAchievement.event?.legacyGame ? (
{t("View this year's event")} diff --git a/resources/js/features/home/components/+sidebar/AchievementOfTheWeek/AotwUnlockedIndicator/AotwUnlockedIndicator.test.tsx b/resources/js/features/home/components/+sidebar/AchievementOfTheWeek/AotwUnlockedIndicator/AotwUnlockedIndicator.test.tsx new file mode 100644 index 0000000000..651e915959 --- /dev/null +++ b/resources/js/features/home/components/+sidebar/AchievementOfTheWeek/AotwUnlockedIndicator/AotwUnlockedIndicator.test.tsx @@ -0,0 +1,60 @@ +import { render, screen } from '@/test'; +import { createAchievementOfTheWeekProps } from '@/test/factories'; + +import { AotwUnlockedIndicator } from './AotwUnlockedIndicator'; + +describe('Component: AotwUnlockedIndicator', () => { + it('renders without crashing', () => { + // ARRANGE + const { container } = render(, { + pageProps: { + achievementOfTheWeek: createAchievementOfTheWeekProps({ + doesUserHaveUnlock: false, + }), + }, + }); + + // ASSERT + expect(container).toBeTruthy(); + }); + + it('given there is no achievement of the week progress data, renders nothing', () => { + // ARRANGE + render(, { + pageProps: { + achievementOfTheWeek: null, + }, + }); + + // ASSERT + expect(screen.queryByTestId('aotw-progress')).not.toBeInTheDocument(); + }); + + it('given the user has unlocked the current week, shows an unlocked message', () => { + // ARRANGE + render(, { + pageProps: { + achievementOfTheWeek: { + doesUserHaveUnlock: true, + }, + }, + }); + + // ASSERT + expect(screen.getByText(/unlocked/i)).toBeVisible(); + }); + + it('given the user has not unlocked the current week, renders nothing', () => { + // ARRANGE + render(, { + pageProps: { + achievementOfTheWeek: { + doesUserHaveUnlock: false, + }, + }, + }); + + // ASSERT + expect(screen.queryByTestId('aotw-progress')).not.toBeInTheDocument(); + }); +}); diff --git a/resources/js/features/home/components/+sidebar/AchievementOfTheWeek/AotwUnlockedIndicator/AotwUnlockedIndicator.tsx b/resources/js/features/home/components/+sidebar/AchievementOfTheWeek/AotwUnlockedIndicator/AotwUnlockedIndicator.tsx new file mode 100644 index 0000000000..558c954e32 --- /dev/null +++ b/resources/js/features/home/components/+sidebar/AchievementOfTheWeek/AotwUnlockedIndicator/AotwUnlockedIndicator.tsx @@ -0,0 +1,20 @@ +import type { FC } from 'react'; +import { useTranslation } from 'react-i18next'; + +import { usePageProps } from '@/common/hooks/usePageProps'; + +export const AotwUnlockedIndicator: FC = () => { + const { achievementOfTheWeek } = usePageProps(); + + const { t } = useTranslation(); + + if (!achievementOfTheWeek?.doesUserHaveUnlock) { + return null; + } + + return ( +
+

{t('Unlocked')}

+
+ ); +}; diff --git a/resources/js/features/home/components/+sidebar/AchievementOfTheWeek/AotwUnlockedIndicator/index.ts b/resources/js/features/home/components/+sidebar/AchievementOfTheWeek/AotwUnlockedIndicator/index.ts new file mode 100644 index 0000000000..4ce7f6088c --- /dev/null +++ b/resources/js/features/home/components/+sidebar/AchievementOfTheWeek/AotwUnlockedIndicator/index.ts @@ -0,0 +1 @@ +export * from './AotwUnlockedIndicator'; diff --git a/resources/js/test/factories/createHomePageProps/createAchievementOfTheWeekProps.ts b/resources/js/test/factories/createHomePageProps/createAchievementOfTheWeekProps.ts new file mode 100644 index 0000000000..4622d9d86c --- /dev/null +++ b/resources/js/test/factories/createHomePageProps/createAchievementOfTheWeekProps.ts @@ -0,0 +1,11 @@ +import { createFactory } from '@/test/createFactory'; + +import { createEventAchievement } from '../createEventAchievement'; + +export const createAchievementOfTheWeekProps = + createFactory((faker) => { + return { + currentEventAchievement: createEventAchievement(), + doesUserHaveUnlock: faker.datatype.boolean(), + }; + }); diff --git a/resources/js/test/factories/createHomePageProps/createHomePageProps.ts b/resources/js/test/factories/createHomePageProps/createHomePageProps.ts index 998d26ed61..7e2099f38d 100644 --- a/resources/js/test/factories/createHomePageProps/createHomePageProps.ts +++ b/resources/js/test/factories/createHomePageProps/createHomePageProps.ts @@ -3,17 +3,17 @@ import { createFactory } from '@/test/createFactory'; import { createAchievementSetClaim } from '../createAchievementSetClaim'; import { createActivePlayer } from '../createActivePlayer'; -import { createEventAchievement } from '../createEventAchievement'; import { createNews } from '../createNews'; import { createPaginatedData } from '../createPaginatedData'; import { createRecentActiveForumTopic } from '../createRecentActiveForumTopic'; import { createTrendingGame } from '../createTrendingGame'; +import { createAchievementOfTheWeekProps } from './createAchievementOfTheWeekProps'; import { createStaticData } from './createStaticData'; import { createStaticGameAward } from './createStaticGameAward'; export const createHomePageProps = createFactory((faker) => { return { - achievementOfTheWeek: createEventAchievement(), + achievementOfTheWeek: createAchievementOfTheWeekProps(), staticData: createStaticData(), mostRecentGameBeaten: createStaticGameAward(), mostRecentGameMastered: createStaticGameAward(), diff --git a/resources/js/test/factories/createHomePageProps/index.ts b/resources/js/test/factories/createHomePageProps/index.ts index ac925d80f9..dde12da0ac 100644 --- a/resources/js/test/factories/createHomePageProps/index.ts +++ b/resources/js/test/factories/createHomePageProps/index.ts @@ -1,3 +1,4 @@ +export * from './createAchievementOfTheWeekProps'; export * from './createHomePageProps'; export * from './createStaticData'; export * from './createStaticGameAward'; diff --git a/resources/js/types/generated.d.ts b/resources/js/types/generated.d.ts index 6f20656284..61ee23cdae 100644 --- a/resources/js/types/generated.d.ts +++ b/resources/js/types/generated.d.ts @@ -312,9 +312,13 @@ declare namespace App.Enums { | 18; } declare namespace App.Http.Data { + export type AchievementOfTheWeekProps = { + currentEventAchievement: App.Platform.Data.EventAchievement; + doesUserHaveUnlock: boolean; + }; export type HomePageProps = { staticData: App.Data.StaticData; - achievementOfTheWeek: App.Platform.Data.EventAchievement | null; + achievementOfTheWeek: App.Http.Data.AchievementOfTheWeekProps | null; mostRecentGameMastered: App.Data.StaticGameAward | null; mostRecentGameBeaten: App.Data.StaticGameAward | null; recentNews: Array; @@ -631,18 +635,9 @@ declare namespace App.Platform.Data { }; } declare namespace App.Platform.Enums { - export type UnlockMode = 0 | 1; export type AchievementAuthorTask = 'artwork' | 'design' | 'logic' | 'testing' | 'writing'; export type AchievementFlag = 3 | 5; export type AchievementSetAuthorTask = 'artwork'; - export type AchievementSetType = - | 'core' - | 'bonus' - | 'specialty' - | 'exclusive' - | 'will_be_bonus' - | 'will_be_specialty' - | 'will_be_exclusive'; export type GameListProgressFilterValue = | 'unstarted' | 'unfinished' @@ -655,6 +650,15 @@ declare namespace App.Platform.Enums { | 'eq_mastered' | 'revised' | 'neq_mastered'; + export type UnlockMode = 0 | 1; + export type AchievementSetType = + | 'core' + | 'bonus' + | 'specialty' + | 'exclusive' + | 'will_be_bonus' + | 'will_be_specialty' + | 'will_be_exclusive'; export type GameListSortField = | 'title' | 'system' @@ -680,6 +684,7 @@ declare namespace App.Platform.Enums { export type PlayerPreferredMode = 'softcore' | 'hardcore' | 'mixed'; export type ReleasedAtGranularity = 'day' | 'month' | 'year'; export type TicketableType = 'achievement' | 'leaderboard' | 'rich-presence'; + export type TriggerableType = 'achievement' | 'leaderboard' | 'game'; } declare namespace App.Platform.Services.GameSuggestions.Enums { export type SourceGameKind = 'beaten' | 'mastered' | 'want-to-play'; diff --git a/resources/js/ziggy.d.ts b/resources/js/ziggy.d.ts index a74b1f5b00..33cf52f334 100644 --- a/resources/js/ziggy.d.ts +++ b/resources/js/ziggy.d.ts @@ -1,13 +1,6 @@ /* This file is generated by Ziggy. */ declare module 'ziggy-js' { interface RouteList { - "forum.post.edit": [ - { - "name": "forumTopicComment", - "required": true, - "binding": "id" - } - ], "forum-topic.create": [ { "name": "forum", @@ -32,49 +25,49 @@ declare module 'ziggy-js' { { "name": "user", "required": true, - "binding": "User" + "binding": "ID" } ], "reporter.tickets": [ { "name": "user", "required": true, - "binding": "User" + "binding": "ID" } ], "developer.tickets.resolved": [ { "name": "user", "required": true, - "binding": "User" + "binding": "ID" } ], "user.tickets.created": [ { "name": "user", "required": true, - "binding": "User" + "binding": "ID" } ], "developer.claims": [ { "name": "user", "required": true, - "binding": "User" + "binding": "ID" } ], "developer.sets": [ { "name": "user", "required": true, - "binding": "User" + "binding": "ID" } ], "game.compare-unlocks": [ { "name": "user", "required": true, - "binding": "User" + "binding": "ID" }, { "name": "game", @@ -86,7 +79,7 @@ declare module 'ziggy-js' { { "name": "user", "required": true, - "binding": "User" + "binding": "ID" } ], "game.tickets": [ @@ -199,7 +192,7 @@ declare module 'ziggy-js' { { "name": "user", "required": true, - "binding": "User" + "binding": "ID" }, { "name": "game", @@ -303,14 +296,14 @@ declare module 'ziggy-js' { { "name": "user", "required": true, - "binding": "User" + "binding": "ID" } ], "api.user.moderation-comment.store": [ { "name": "user", "required": true, - "binding": "User" + "binding": "ID" } ], "api.achievement.comment.destroy": [ @@ -389,7 +382,7 @@ declare module 'ziggy-js' { { "name": "user", "required": true, - "binding": "User" + "binding": "ID" }, { "name": "comment", @@ -401,7 +394,7 @@ declare module 'ziggy-js' { { "name": "user", "required": true, - "binding": "User" + "binding": "ID" }, { "name": "comment", @@ -489,21 +482,21 @@ declare module 'ziggy-js' { { "name": "user", "required": true, - "binding": "User" + "binding": "ID" } ], "user.achievement-author.feed": [ { "name": "user", "required": true, - "binding": "User" + "binding": "ID" } ], "user.moderation-comment.index": [ { "name": "user", "required": true, - "binding": "User" + "binding": "ID" } ], "forum.recent-posts": [], @@ -518,14 +511,14 @@ declare module 'ziggy-js' { { "name": "user", "required": true, - "binding": "User" + "binding": "ID" } ], "user.achievement-checklist": [ { "name": "user", "required": true, - "binding": "User" + "binding": "ID" } ], "settings.show": [], diff --git a/tests/Feature/Http/Controllers/HomeControllerTest.php b/tests/Feature/Http/Controllers/HomeControllerTest.php index 0e8a3601d8..edfac870f0 100644 --- a/tests/Feature/Http/Controllers/HomeControllerTest.php +++ b/tests/Feature/Http/Controllers/HomeControllerTest.php @@ -183,19 +183,19 @@ public function testItCorrectlySendsAchievementOfTheWeekProps(): void // Assert $response->assertInertia(fn (Assert $page) => $page - ->where('achievementOfTheWeek.achievement.id', $eventAchievement->id) - ->where('achievementOfTheWeek.achievement.title', $achievement->title) - ->where('achievementOfTheWeek.achievement.description', $achievement->description) + ->where('achievementOfTheWeek.currentEventAchievement.achievement.id', $eventAchievement->id) + ->where('achievementOfTheWeek.currentEventAchievement.achievement.title', $achievement->title) + ->where('achievementOfTheWeek.currentEventAchievement.achievement.description', $achievement->description) - ->where('achievementOfTheWeek.sourceAchievement.game.id', $game->id) - ->where('achievementOfTheWeek.sourceAchievement.game.title', $game->title) - ->where('achievementOfTheWeek.sourceAchievement.game.badgeUrl', $game->badgeUrl) + ->where('achievementOfTheWeek.currentEventAchievement.sourceAchievement.game.id', $game->id) + ->where('achievementOfTheWeek.currentEventAchievement.sourceAchievement.game.title', $game->title) + ->where('achievementOfTheWeek.currentEventAchievement.sourceAchievement.game.badgeUrl', $game->badgeUrl) - ->where('achievementOfTheWeek.sourceAchievement.game.system.name', $system->name) - ->where('achievementOfTheWeek.sourceAchievement.game.system.iconUrl', $system->iconUrl) + ->where('achievementOfTheWeek.currentEventAchievement.sourceAchievement.game.system.name', $system->name) + ->where('achievementOfTheWeek.currentEventAchievement.sourceAchievement.game.system.iconUrl', $system->iconUrl) - ->where('achievementOfTheWeek.event.id', $event->id) - ->where('achievementOfTheWeek.event.legacyGame.id', $eventGame->id) + ->where('achievementOfTheWeek.currentEventAchievement.event.id', $event->id) + ->where('achievementOfTheWeek.currentEventAchievement.event.legacyGame.id', $eventGame->id) ); }