createMock(\medoo::class); $repository = new NewsletterRepository($mockDb, $this->createMock(SettingsRepository::class)); $this->assertNull($repository->templateDetails(0)); } public function testTemplateDetailsReturnsArray(): void { $mockDb = $this->createMock(\medoo::class); $mockDb->expects($this->once()) ->method('get') ->with('pp_newsletter_templates', '*', ['id' => 7]) ->willReturn(['id' => 7, 'name' => 'Tpl']); $repository = new NewsletterRepository($mockDb, $this->createMock(SettingsRepository::class)); $details = $repository->templateDetails(7); $this->assertIsArray($details); $this->assertSame(7, $details['id']); } public function testSaveSettingsUpdatesHeaderAndFooter(): void { $mockDb = $this->createMock(\medoo::class); $settingsRepository = $this->createMock(SettingsRepository::class); $settingsRepository->expects($this->exactly(2)) ->method('updateSetting') ->withConsecutive( ['newsletter_footer', 'Footer'], ['newsletter_header', 'Header'] ); $repository = new NewsletterRepository($mockDb, $settingsRepository); $this->assertTrue($repository->saveSettings([ 'newsletter_header' => 'Header', 'newsletter_footer' => 'Footer', ])); } public function testDeleteTemplateReturnsFalseForAdminTemplate(): void { $mockDb = $this->createMock(\medoo::class); $mockDb->expects($this->once()) ->method('get') ->with('pp_newsletter_templates', 'is_admin', ['id' => 5]) ->willReturn(1); $repository = new NewsletterRepository($mockDb, $this->createMock(SettingsRepository::class)); $this->assertFalse($repository->deleteTemplate(5)); } public function testTemplateByNameReturnsText(): void { $mockDb = $this->createMock(\medoo::class); $mockDb->expects($this->once()) ->method('get') ->with('pp_newsletter_templates', 'text', ['name' => '#abc']) ->willReturn('Template text'); $repository = new NewsletterRepository($mockDb, $this->createMock(SettingsRepository::class)); $this->assertSame('Template text', $repository->templateByName('#abc')); } // ── Frontend methods tests ── public function testUnsubscribeReturnsFalseForInvalidHash(): void { $mockDb = $this->createMock(\medoo::class); $mockDb->expects($this->once()) ->method('get') ->with('pp_newsletter', 'id', ['hash' => 'bad-hash']) ->willReturn(null); $repository = new NewsletterRepository($mockDb, $this->createMock(SettingsRepository::class)); $this->assertFalse($repository->unsubscribe('bad-hash')); } public function testUnsubscribeDeletesSubscriber(): void { $mockDb = $this->createMock(\medoo::class); $mockDb->expects($this->once()) ->method('get') ->with('pp_newsletter', 'id', ['hash' => 'abc123']) ->willReturn(42); $mockDb->expects($this->once()) ->method('delete') ->with('pp_newsletter', ['id' => 42]); $repository = new NewsletterRepository($mockDb, $this->createMock(SettingsRepository::class)); $this->assertTrue($repository->unsubscribe('abc123')); } public function testConfirmSubscriptionReturnsFalseForInvalidHash(): void { $mockDb = $this->createMock(\medoo::class); $mockDb->expects($this->once()) ->method('get') ->with('pp_newsletter', 'id', ['AND' => ['hash' => 'bad', 'status' => 0]]) ->willReturn(null); $repository = new NewsletterRepository($mockDb, $this->createMock(SettingsRepository::class)); $this->assertFalse($repository->confirmSubscription('bad')); } public function testConfirmSubscriptionUpdatesStatus(): void { $mockDb = $this->createMock(\medoo::class); $mockDb->expects($this->once()) ->method('get') ->with('pp_newsletter', 'id', ['AND' => ['hash' => 'valid', 'status' => 0]]) ->willReturn(10); $mockDb->expects($this->once()) ->method('update') ->with('pp_newsletter', ['status' => 1], ['id' => 10]); $repository = new NewsletterRepository($mockDb, $this->createMock(SettingsRepository::class)); $this->assertTrue($repository->confirmSubscription('valid')); } public function testGetHashByEmailReturnsHash(): void { $mockDb = $this->createMock(\medoo::class); $mockDb->expects($this->once()) ->method('get') ->with('pp_newsletter', 'hash', ['email' => 'test@test.pl']) ->willReturn('abc123'); $repository = new NewsletterRepository($mockDb, $this->createMock(SettingsRepository::class)); $this->assertSame('abc123', $repository->getHashByEmail('test@test.pl')); } public function testGetHashByEmailReturnsNullForMissing(): void { $mockDb = $this->createMock(\medoo::class); $mockDb->expects($this->once()) ->method('get') ->with('pp_newsletter', 'hash', ['email' => 'none@test.pl']) ->willReturn(null); $repository = new NewsletterRepository($mockDb, $this->createMock(SettingsRepository::class)); $this->assertNull($repository->getHashByEmail('none@test.pl')); } public function testRemoveByEmailDeletesSubscriber(): void { $mockDb = $this->createMock(\medoo::class); $mockDb->expects($this->once()) ->method('get') ->with('pp_newsletter', 'id', ['email' => 'test@test.pl']) ->willReturn(5); $mockDb->expects($this->once()) ->method('delete') ->with('pp_newsletter', ['email' => 'test@test.pl']) ->willReturn(true); $repository = new NewsletterRepository($mockDb, $this->createMock(SettingsRepository::class)); $this->assertTrue($repository->removeByEmail('test@test.pl')); } public function testRemoveByEmailReturnsFalseForMissing(): void { $mockDb = $this->createMock(\medoo::class); $mockDb->expects($this->once()) ->method('get') ->with('pp_newsletter', 'id', ['email' => 'none@test.pl']) ->willReturn(null); $repository = new NewsletterRepository($mockDb, $this->createMock(SettingsRepository::class)); $this->assertFalse($repository->removeByEmail('none@test.pl')); } public function testSignupReturnsFalseForExistingEmail(): void { $mockDb = $this->createMock(\medoo::class); $mockDb->expects($this->once()) ->method('get') ->with('pp_newsletter', 'id', ['email' => 'exists@test.pl']) ->willReturn(1); $repository = new NewsletterRepository($mockDb, $this->createMock(SettingsRepository::class)); $this->assertFalse($repository->signup('exists@test.pl', 'example.com', false, [])); } public function testConstructorAcceptsOptionalDependencies(): void { $mockDb = $this->createMock(\medoo::class); $settingsRepo = $this->createMock(SettingsRepository::class); $articleRepo = $this->createMock(\Domain\Article\ArticleRepository::class); $renderer = $this->createMock(\Domain\Newsletter\NewsletterPreviewRenderer::class); $repository = new NewsletterRepository($mockDb, $settingsRepo, $articleRepo, $renderer); $this->assertInstanceOf(NewsletterRepository::class, $repository); } }