createMock(\medoo::class); $mockDb->expects($this->once()) ->method('get') ->with('pp_banners', '*', ['id' => 1]) ->willReturn(['id' => 1, 'name' => 'Baner testowy', 'status' => 1]); $mockDb->expects($this->once()) ->method('select') ->with('pp_banners_langs', '*', [ 'id_banner' => 1, 'ORDER' => ['id' => 'ASC'], ]) ->willReturn([ ['id_lang' => 'pl', 'src' => 'banner.jpg', 'url' => '/promo'], ['id_lang' => 'en', 'src' => 'banner-en.jpg', 'url' => '/promo-en'], ]); $repository = new BannerRepository($mockDb); // Act $banner = $repository->find(1); // Assert $this->assertIsArray($banner); $this->assertEquals('Baner testowy', $banner['name']); $this->assertArrayHasKey('languages', $banner); $this->assertCount(2, $banner['languages']); $this->assertEquals('banner.jpg', $banner['languages']['pl']['src']); } /** * Test pobierania banera - nie istnieje */ public function testFindReturnsNullWhenNotFound() { // Arrange $mockDb = $this->createMock(\medoo::class); $mockDb->method('get')->willReturn(false); $repository = new BannerRepository($mockDb); // Act $banner = $repository->find(999); // Assert $this->assertNull($banner); } /** * Test usuwania banera - sukces */ public function testDeleteReturnsTrue() { // Arrange $mockDb = $this->createMock(\medoo::class); $mockDb->expects($this->once()) ->method('delete') ->with('pp_banners', ['id' => 5]) ->willReturn($this->createMock(\PDOStatement::class)); $repository = new BannerRepository($mockDb); // Act $result = $repository->delete(5); // Assert $this->assertTrue($result); } /** * Test zapisywania nowego banera (stary format danych - zachowano kompatybilność) */ public function testSaveInsertsNewBanner() { // Arrange $mockDb = $this->createMock(\medoo::class); // insert() wywoływane 2x: raz dla banera, raz dla tłumaczenia $mockDb->expects($this->exactly(2)) ->method('insert'); $mockDb->expects($this->once()) ->method('id') ->willReturn(10); // get() for checking existing translations - returns false (no existing) $mockDb->method('get')->willReturn(false); $repository = new BannerRepository($mockDb); // Act - nowy format z FormRequestHandler (przetworzone dane) $result = $repository->save([ 'name' => 'Nowy baner', 'status' => 1, // już przetworzone na int 'date_start' => null, 'date_end' => null, 'home_page' => 1, // już przetworzone na int 'translations' => [ 1 => [ // id języka jako klucz 'src' => 'banner.jpg', 'url' => '/promo', 'html' => '', 'text' => 'Tekst', ], ], ]); // Assert $this->assertEquals(10, $result); } /** * Test zapisywania banera ze starym formatem danych (backward compatibility) */ public function testSaveWithLegacyFormat() { // Arrange $mockDb = $this->createMock(\medoo::class); // insert() wywoływane 2x: raz dla banera, raz dla tłumaczenia $mockDb->expects($this->exactly(2)) ->method('insert'); $mockDb->expects($this->once()) ->method('id') ->willReturn(11); // get() for checking existing translations - returns false (no existing) $mockDb->method('get')->willReturn(false); $repository = new BannerRepository($mockDb); // Act - stary format (dla kompatybilności wstecznej) $result = $repository->save([ 'name' => 'Baner legacy', 'status' => 'on', 'date_start' => '', 'date_end' => '', 'home_page' => 'on', 'src' => ['pl' => 'banner.jpg'], 'url' => ['pl' => '/promo'], 'html' => ['pl' => ''], 'text' => ['pl' => 'Tekst'], ]); // Assert $this->assertEquals(11, $result); } /** * Test zapisu istniejacego banera - aktualizacja tlumaczen po id_banner + id_lang */ public function testSaveUpdatesExistingTranslationsByBannerAndLang(): void { $mockDb = $this->createMock(\medoo::class); $mockDb->expects($this->exactly(2)) ->method('update') ->withConsecutive( [ 'pp_banners', $this->arrayHasKey('name'), ['id' => 5], ], [ 'pp_banners_langs', $this->callback(function (array $data): bool { return $data['id_banner'] === 5 && $data['id_lang'] === 'pl' && $data['src'] === 'banner-new.jpg'; }), ['AND' => ['id_banner' => 5, 'id_lang' => 'pl']], ] ); $mockDb->expects($this->once()) ->method('count') ->with('pp_banners_langs', ['AND' => ['id_banner' => 5, 'id_lang' => 'pl']]) ->willReturn(2); $mockDb->expects($this->never()) ->method('insert'); $repository = new BannerRepository($mockDb); $result = $repository->save([ 'id' => 5, 'name' => 'Baner update', 'status' => 1, 'date_start' => null, 'date_end' => null, 'home_page' => 0, 'translations' => [ 'pl' => [ 'src' => 'banner-new.jpg', 'url' => '/promo-new', 'html' => 'promo', 'text' => 'Nowa tresc', ], ], ]); $this->assertSame(5, $result); } public function testListForAdminIncludesThumbnailSrc(): void { $mockDb = $this->createMock(\medoo::class); $countStmt = $this->createMock(\PDOStatement::class); $countStmt->expects($this->once()) ->method('fetchAll') ->willReturn([[2]]); $itemsStmt = $this->createMock(\PDOStatement::class); $itemsStmt->expects($this->once()) ->method('fetchAll') ->willReturn([ [ 'id' => 10, 'name' => 'Baner A', 'status' => 1, 'home_page' => 0, 'date_start' => null, 'date_end' => null, ], [ 'id' => 11, 'name' => 'Baner B', 'status' => 1, 'home_page' => 1, 'date_start' => null, 'date_end' => null, ], ]); $thumbsStmt = $this->createMock(\PDOStatement::class); $thumbsStmt->expects($this->once()) ->method('fetchAll') ->willReturn([ ['id_banner' => 10, 'src' => '/uploads/banner-a.jpg'], ]); $mockDb->expects($this->exactly(3)) ->method('query') ->willReturnOnConsecutiveCalls($countStmt, $itemsStmt, $thumbsStmt); $repository = new BannerRepository($mockDb); $result = $repository->listForAdmin([], 'name', 'ASC', 1, 15); $this->assertSame(2, $result['total']); $this->assertCount(2, $result['items']); $this->assertSame('/uploads/banner-a.jpg', $result['items'][0]['thumbnail_src']); $this->assertSame('', $result['items'][1]['thumbnail_src']); } // ─── Frontend methods ─────────────────────────────────────────── /** * Test banners() — cache miss, zwraca aktywne banery z plaskim formatem languages */ public function testBannersReturnsActiveBannersWithFlatLanguages(): void { $mockDb = $this->createMock(\medoo::class); $queryStmt = $this->createMock(\PDOStatement::class); $queryStmt->expects($this->once()) ->method('fetchAll') ->willReturn([ ['id' => 1, 'name' => 'Baner A'], ['id' => 2, 'name' => 'Baner B'], ]); $mockDb->expects($this->once()) ->method('query') ->willReturn($queryStmt); $mockDb->expects($this->exactly(2)) ->method('get') ->with('pp_banners_langs', '*', $this->anything()) ->willReturnOnConsecutiveCalls( ['id_banner' => 1, 'id_lang' => 'pl', 'src' => 'a.jpg', 'url' => '/a', 'html' => '', 'text' => ''], ['id_banner' => 2, 'id_lang' => 'pl', 'src' => 'b.jpg', 'url' => '/b', 'html' => '', 'text' => ''] ); $repo = new BannerRepository($mockDb); $result = $repo->banners('pl'); $this->assertIsArray($result); $this->assertCount(2, $result); // Format plaski — $banner['languages']['src'], nie $banner['languages']['pl']['src'] $this->assertSame('a.jpg', $result[0]['languages']['src']); $this->assertSame('b.jpg', $result[1]['languages']['src']); } /** * Test banners() — brak wynikow zwraca null */ public function testBannersReturnsNullWhenNoBanners(): void { $mockDb = $this->createMock(\medoo::class); $queryStmt = $this->createMock(\PDOStatement::class); $queryStmt->expects($this->once()) ->method('fetchAll') ->willReturn([]); $mockDb->expects($this->once()) ->method('query') ->willReturn($queryStmt); $repo = new BannerRepository($mockDb); $result = $repo->banners('pl'); $this->assertNull($result); } /** * Test mainBanner() — cache miss, zwraca baner z plaskim formatem languages */ public function testMainBannerReturnsActiveBannerWithFlatLanguages(): void { $mockDb = $this->createMock(\medoo::class); $queryStmt = $this->createMock(\PDOStatement::class); $queryStmt->expects($this->once()) ->method('fetchAll') ->willReturn([ ['id' => 5, 'name' => 'Main Banner', 'status' => 1, 'home_page' => 1], ]); $mockDb->expects($this->once()) ->method('query') ->willReturn($queryStmt); $mockDb->expects($this->once()) ->method('get') ->with('pp_banners_langs', '*', ['AND' => ['id_banner' => 5, 'id_lang' => 'pl']]) ->willReturn(['id_banner' => 5, 'id_lang' => 'pl', 'src' => 'main.jpg', 'url' => '/main', 'html' => '', 'text' => '']); $repo = new BannerRepository($mockDb); $result = $repo->mainBanner('pl'); $this->assertIsArray($result); $this->assertSame(5, (int)$result['id']); $this->assertSame('main.jpg', $result['languages']['src']); $this->assertSame('/main', $result['languages']['url']); } /** * Test mainBanner() — brak wynikow zwraca null */ public function testMainBannerReturnsNullWhenNoBanner(): void { $mockDb = $this->createMock(\medoo::class); $queryStmt = $this->createMock(\PDOStatement::class); $queryStmt->expects($this->once()) ->method('fetchAll') ->willReturn([]); $mockDb->expects($this->once()) ->method('query') ->willReturn($queryStmt); $repo = new BannerRepository($mockDb); $result = $repo->mainBanner('pl'); $this->assertNull($result); } }