ver. 0.279: Newsletter frontend migration, Languages facade elimination, bug fix newsletter_unsubscribe

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-16 15:11:38 +01:00
parent 59b36f48b1
commit 3b32ea0b9b
54 changed files with 579 additions and 294 deletions

View File

@@ -75,4 +75,145 @@ class NewsletterRepositoryTest extends TestCase
$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);
}
}

View File

@@ -5,23 +5,26 @@ use PHPUnit\Framework\TestCase;
use admin\Controllers\ShopProductController;
use Domain\Product\ProductRepository;
use Domain\Integrations\IntegrationsRepository;
use Domain\Languages\LanguagesRepository;
class ShopProductControllerTest extends TestCase
{
private $repository;
private $integrationsRepository;
private $languagesRepository;
private $controller;
protected function setUp(): void
{
$this->repository = $this->createMock(ProductRepository::class);
$this->integrationsRepository = $this->createMock(IntegrationsRepository::class);
$this->controller = new ShopProductController($this->repository, $this->integrationsRepository);
$this->languagesRepository = $this->createMock(LanguagesRepository::class);
$this->controller = new ShopProductController($this->repository, $this->integrationsRepository, $this->languagesRepository);
}
public function testConstructorAcceptsRepositories(): void
{
$controller = new ShopProductController($this->repository, $this->integrationsRepository);
$controller = new ShopProductController($this->repository, $this->integrationsRepository, $this->languagesRepository);
$this->assertInstanceOf(ShopProductController::class, $controller);
}
@@ -105,9 +108,10 @@ class ShopProductControllerTest extends TestCase
$constructor = $reflection->getConstructor();
$params = $constructor->getParameters();
$this->assertCount(2, $params);
$this->assertCount(3, $params);
$this->assertEquals('Domain\Product\ProductRepository', $params[0]->getType()->getName());
$this->assertEquals('Domain\Integrations\IntegrationsRepository', $params[1]->getType()->getName());
$this->assertEquals('Domain\Languages\LanguagesRepository', $params[2]->getType()->getName());
}
public function testHasFormBuildingHelpers(): void