From 6e22deb8d6ef08917deb133632616893c838faf4 Mon Sep 17 00:00:00 2001 From: Daniel Wilkowski Date: Wed, 7 Feb 2024 12:47:08 +0100 Subject: [PATCH] Add test for "What's new" section --- app/Services/Widgets/WhatsNew.php | 54 +++++++++++-------- resources/views/homepage/whats-new.twig | 17 ++++-- tests/Unit/BaseFixture/ClearedCache.php | 20 +++++++ tests/Unit/Seo/Link/Fixture/Assertion.php | 13 +---- tests/Unit/WhatsNew/Fixture/Models.php | 50 +++++++++++++++++ tests/Unit/WhatsNew/Fixture/NewsItems.php | 36 +++++++++++++ tests/Unit/WhatsNew/Fixture/TrimmedString.php | 42 +++++++++++++++ tests/Unit/WhatsNew/Test.php | 29 ++++++++++ 8 files changed, 225 insertions(+), 36 deletions(-) create mode 100644 tests/Unit/BaseFixture/ClearedCache.php create mode 100644 tests/Unit/WhatsNew/Fixture/Models.php create mode 100644 tests/Unit/WhatsNew/Fixture/NewsItems.php create mode 100644 tests/Unit/WhatsNew/Fixture/TrimmedString.php create mode 100644 tests/Unit/WhatsNew/Test.php diff --git a/app/Services/Widgets/WhatsNew.php b/app/Services/Widgets/WhatsNew.php index 1ecb9e1ab0..ed8384010a 100644 --- a/app/Services/Widgets/WhatsNew.php +++ b/app/Services/Widgets/WhatsNew.php @@ -1,38 +1,50 @@ microblog = $microblog; - $this->user = $user; - $this->cache = $cache; } public function render(): string { - return $this->cache->remember('widget:whats-new', now()->addHour(), function () { - $this->user->resetCriteria(); - - $user = $this->user->findBy('name', '4programmers.net', ['id']); + return $this->cache->remember( + 'widget:whats-new', + now()->addHour(), + fn() => $this->widgetView()->render()); + } - $this->microblog->resetCriteria(); - $this->microblog->pushCriteria(new WithTag('4programmers.net')); - $this->microblog->pushCriteria(new OnlyMine($user->id ?? null)); + private function widgetView(): View + { + $this->microblog->resetCriteria(); + $this->microblog->pushCriteria(new WithTag('4programmers.net')); + $this->microblog->pushCriteria(new OnlyMine($this->userIdByName('4programmers.net'))); + + return view('homepage.whats-new', [ + 'href' => route('microblog.tag', ['4programmers.net']), + 'microblogs' => $this->microblog->recent()->map(fn(Microblog $microblog) => [ + 'id' => $microblog->id, + 'summary' => excerpt($microblog->html), + 'href' => route('microblog.view', [$microblog->id]), + 'date' => $microblog->created_at->formatLocalized('%d %b %y'), + ]), + ]); + } - return view('homepage.whats-new', ['microblogs' => $this->microblog->recent()])->render(); - }); + private function userIdByName(string $name): ?int + { + $user = User::query()->where('name', '=', $name)->first(['id']); + return $user->id ?? null; } } diff --git a/resources/views/homepage/whats-new.twig b/resources/views/homepage/whats-new.twig index 498999e520..ff5dd7dcfb 100644 --- a/resources/views/homepage/whats-new.twig +++ b/resources/views/homepage/whats-new.twig @@ -1,12 +1,21 @@
-
Nowości od #4programmers.net
- +
+ + Nowości od #4programmers.net + +
diff --git a/tests/Unit/BaseFixture/ClearedCache.php b/tests/Unit/BaseFixture/ClearedCache.php new file mode 100644 index 0000000000..ae9906f2f6 --- /dev/null +++ b/tests/Unit/BaseFixture/ClearedCache.php @@ -0,0 +1,20 @@ +laravel->app[Cache\Repository::class]; + $cache->clear(); + } +} diff --git a/tests/Unit/Seo/Link/Fixture/Assertion.php b/tests/Unit/Seo/Link/Fixture/Assertion.php index 8730905ffe..278a236576 100644 --- a/tests/Unit/Seo/Link/Fixture/Assertion.php +++ b/tests/Unit/Seo/Link/Fixture/Assertion.php @@ -2,23 +2,14 @@ namespace Tests\Unit\Seo\Link\Fixture; use Coyote\Services\Parser\Factories\PostFactory; -use Illuminate\Contracts\Cache; use PHPUnit\Framework\Assert; +use Tests\Unit\BaseFixture; use Tests\Unit\BaseFixture\Server\Laravel; trait Assertion { use Laravel\Application; - - /** - * @before - */ - function clearCache(): void - { - /** @var Cache\Repository $cache */ - $cache = $this->laravel->app[Cache\Repository::class]; - $cache->clear(); - } + use BaseFixture\ClearedCache; function assertRenderPost(string $text, string $expected): void { diff --git a/tests/Unit/WhatsNew/Fixture/Models.php b/tests/Unit/WhatsNew/Fixture/Models.php new file mode 100644 index 0000000000..62473623f9 --- /dev/null +++ b/tests/Unit/WhatsNew/Fixture/Models.php @@ -0,0 +1,50 @@ +newMicroblog( + $text, + new Carbon($dateTime), + $this->newTag('4programmers.net')); + } + + function newMicroblog(string $text, Carbon $date, Tag $tag): int + { + $microblog = new Microblog([ + 'user_id' => $this->systemUser()->id, + 'text' => $text, + ]); + $microblog->created_at = $date; + $microblog->save(); + $microblog->tags()->save($tag); + return $microblog->id; + } + + function newTag(string $name): Tag + { + $tag = new Tag(['name' => $name]); + $tag->save(); + return $tag; + } + + function systemUser(): User + { + $user = new User(); + $user->name = '4programmers.net'; + $user->email = 'irrelevant'; + $user->save(); + return $user; + } +} diff --git a/tests/Unit/WhatsNew/Fixture/NewsItems.php b/tests/Unit/WhatsNew/Fixture/NewsItems.php new file mode 100644 index 0000000000..584b21fde5 --- /dev/null +++ b/tests/Unit/WhatsNew/Fixture/NewsItems.php @@ -0,0 +1,36 @@ +htmlView('/')); + /** @var \DOMElement $listItem */ + foreach ($dom->elements(xPath:'//aside//div[@class="card bg-dark"]//ul/li') as $listItem) { + return $this->listItem($listItem); + } + throw new \AssertionError("Failed finding news item."); + } + + function listItem(\DOMElement $listItem): array + { + $item = []; + /** @var \DOMElement $child */ + foreach ($listItem->childNodes as $child) { + if ($child->nodeName === 'a') { + $item['text'] = $child->textContent; + $item['href'] = $child->getAttribute('href'); + } + if ($child->nodeName === 'div') { + $item['date'] = $child->textContent; + } + } + return $item; + } +} diff --git a/tests/Unit/WhatsNew/Fixture/TrimmedString.php b/tests/Unit/WhatsNew/Fixture/TrimmedString.php new file mode 100644 index 0000000000..1d21afa15c --- /dev/null +++ b/tests/Unit/WhatsNew/Fixture/TrimmedString.php @@ -0,0 +1,42 @@ +value === \trim($other); + if ($returnResult) { + return $success; + } + if (!$success) { + $this->fail($other, $description, new ComparisonFailure( + $this->value, + $other, + "'$this->value'", + "'$other'", + )); + } + return null; + } + + public function toString(): string + { + return 'is identical to trimmed ' . $this->exporter()->export($this->value); + } + + protected function failureDescription($other): string + { + if (\is_string($other)) { + return 'two strings are identical'; + } + return parent::failureDescription($other); + } +} diff --git a/tests/Unit/WhatsNew/Test.php b/tests/Unit/WhatsNew/Test.php new file mode 100644 index 0000000000..8b4b0de8fb --- /dev/null +++ b/tests/Unit/WhatsNew/Test.php @@ -0,0 +1,29 @@ +newWhatsNewItem('Valar morghulis.', '2005-04-02 21:37:13'); + $this->assertThat( + $this->newsItem(), + $this->logicalAnd( + new ArrayKey('text', new TrimmedString('Valar morghulis.')), + new ArrayKey('href', $this->relativeUri("/Mikroblogi/View/$id")), + new ArrayKey('date', new TrimmedString('— 02 kwi 05')), + )); + } +}