Skip to content

Commit

Permalink
Added unit tests for services.
Browse files Browse the repository at this point in the history
  • Loading branch information
laurentmuller committed Jun 24, 2024
1 parent d380d74 commit a02fcb3
Show file tree
Hide file tree
Showing 18 changed files with 949 additions and 22 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/php_unit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist

- name: Run PHPUnit
run: vendor/bin/phpunit --display-skipped --no-progress --exclude-group legacy --coverage-clover ./clover.xml
run: vendor/bin/phpunit --display-skipped --no-progress --coverage-clover ./clover.xml

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4.0.1
Expand Down
2 changes: 1 addition & 1 deletion all_batch.bat
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ ECHO ----- PHP-RECTOR ------------------------------------------------- && ^
ECHO ----- PHP-TWIG-CS-FIXER ------------------------------------------ && ^
.\vendor\bin\twig-cs-fixer.bat lint --config=.twig-cs-fixer.php && ^
ECHO ----- PHP-UNIT --------------------------------------------------- && ^
.\vendor\bin\phpunit.bat --exclude-group legacy
.\vendor\bin\phpunit.bat
SET STA__TIME=%TIME: =0%
ECHO ----- END BATCH %STA__TIME% --------------------------------------
12 changes: 6 additions & 6 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 10 additions & 6 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<server name="SHELL_VERBOSITY" value="-1"/>
<server name="SYMFONY_PHPUNIT_REMOVE" value=""/>
<server name="SYMFONY_PHPUNIT_VERSION" value="10.1"/>
<env name="SYMFONY_PHPUNIT_LOCALE" value="fr_CH"/>
</php>

<testsuites>
Expand All @@ -22,14 +23,17 @@
</testsuite>
</testsuites>

<source>
<source restrictDeprecations="true" restrictWarnings="true" restrictNotices="true">
<include>
<directory suffix=".php">./src</directory>
<directory>./src</directory>
</include>
</source>

<groups>
<exclude>
<file>.php-cs-fixer.dist.php</file>
<file>rector.php</file>
<group>legacy</group>
</exclude>
</source>
<coverage />
</groups>

<coverage/>
</phpunit>
4 changes: 4 additions & 0 deletions src/Controller/AbstractEntityController.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
use Doctrine\Common\Collections\Criteria;
use Psr\Log\LoggerInterface;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\FormTypeInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
Expand Down Expand Up @@ -180,9 +181,12 @@ protected function getDefaultRoute(): string

/**
* Gets the form type class name used to edit an entity.
*
* @psalm-return class-string<FormTypeInterface>
*/
protected function getEditFormType(): string
{
/** @psalm-var class-string<FormTypeInterface> */
return \sprintf('App\\Form\\%1$s\\%1$sType', $this->shortName);
}

Expand Down
9 changes: 7 additions & 2 deletions src/Service/MailerService.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,13 @@ public function sendComment(Comment $comment): void
*
* @throws TransportExceptionInterface if an exception occurs while sending the notification
*/
public function sendNotification(string $fromEmail, User $toUser, string $message, Importance $importance = Importance::LOW, array $attachments = []): void
{
public function sendNotification(
string $fromEmail,
User $toUser,
string $message,
Importance $importance = Importance::LOW,
array $attachments = []
): void {
$notification = $this->createNotification($importance)
->from($fromEmail)
->to($toUser->getEmailAddress())
Expand Down
10 changes: 6 additions & 4 deletions src/Service/OpenWeatherCityUpdater.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,16 +80,18 @@ public function import(UploadedFile $file): array
$db = null;

try {
$temp_name = FileUtils::tempFile('sql');
if (null === $temp_name) {
return $this->falseResult('swisspost.error.temp_file');
}
$cities = $this->getFileContent($file);
if (false === $cities) {
return $this->falseResult('swisspost.error.open_archive', [
'%name%' => $file->getClientOriginalName(),
]);
}

$temp_name = FileUtils::tempFile('sql');
if (null === $temp_name) {
return $this->falseResult('swisspost.error.temp_file');
}

$db = new OpenWeatherDatabase($temp_name);
[$valid, $error] = $this->insertCities($db, $cities);
$db->close();
Expand Down
4 changes: 3 additions & 1 deletion src/Service/ResetPasswordService.php
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,9 @@ public function sendEmail(Request $request, User|string $user): ResetPasswordTok

return $token;
} catch (TransportExceptionInterface $e) {
$this->helper->removeResetRequest($token->getToken());
if ('' !== $token->getToken()) {
$this->helper->removeResetRequest($token->getToken());
}
$this->handleException($request, $e);

return null;
Expand Down
1 change: 1 addition & 0 deletions tests/Data/city.list.empty.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
Binary file added tests/Data/city.list.empty.json.gz
Binary file not shown.
2 changes: 1 addition & 1 deletion tests/Listener/SwitchUserListenerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,9 @@ private function createListener(): SwitchUserListener
*/
private function createRequest(string $action = ''): MockObject&Request
{
/** @psalm-var InputBag<string> $query */
$query = new InputBag(['_switch_user' => $action]);
$request = $this->createMock(Request::class);
// @phpstan-ignore assign.propertyType
$request->query = $query;

return $request;
Expand Down
128 changes: 128 additions & 0 deletions tests/Service/EmailVerifierTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<?php
/*
* This file is part of the Calculation package.
*
* (c) bibi.nu <bibi@bibi.nu>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace App\Tests\Service;

use App\Entity\User;
use App\Mime\RegistrationEmail;
use App\Repository\UserRepository;
use App\Service\EmailVerifier;
use App\Tests\Entity\IdTrait;
use App\Tests\TranslatorMockTrait;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\MockObject\Exception;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\UriSigner;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use SymfonyCasts\Bundle\VerifyEmail\Exception\VerifyEmailExceptionInterface;
use SymfonyCasts\Bundle\VerifyEmail\Generator\VerifyEmailTokenGenerator;
use SymfonyCasts\Bundle\VerifyEmail\Model\VerifyEmailSignatureComponents;
use SymfonyCasts\Bundle\VerifyEmail\Util\VerifyEmailQueryUtility;
use SymfonyCasts\Bundle\VerifyEmail\VerifyEmailHelper;
use SymfonyCasts\Bundle\VerifyEmail\VerifyEmailHelperInterface;

#[CoversClass(EmailVerifier::class)]
class EmailVerifierTest extends TestCase
{
use IdTrait;
use TranslatorMockTrait;

/**
* @throws Exception
* @throws VerifyEmailExceptionInterface
* @throws \ReflectionException
*/
public function testHandleEmail(): void
{
$helper = $this->createVerifyEmailHelper();
$mailer = $this->createMock(MailerInterface::class);
$repository = $this->createMock(UserRepository::class);
$translator = $this->createMockTranslator();
$service = new EmailVerifier($helper, $mailer, $repository, $translator);

$user = $this->createUser();
$request = new Request(['expires' => \time() + 3600]);
$service->handleEmail($request, $user);
self::assertTrue($user->isVerified());
}

/**
* @throws Exception
* @throws TransportExceptionInterface
* @throws \ReflectionException
*/
public function testSendEmail(): void
{
$helper = $this->createMockVerifyEmailHelper();
$mailer = $this->createMock(MailerInterface::class);
$repository = $this->createMock(UserRepository::class);
$translator = $this->createMockTranslator();
$service = new EmailVerifier($helper, $mailer, $repository, $translator);

$user = $this->createUser();
$email = new RegistrationEmail();
$service->sendEmail('route', $user, $email);
self::assertFalse($user->isVerified());
}

/**
* @throws Exception
*/
private function createMockVerifyEmailHelper(): MockObject&VerifyEmailHelperInterface
{
$date = new \DateTime();
$component = new VerifyEmailSignatureComponents($date, 'uri', $date->getTimestamp());
$helper = $this->createMock(VerifyEmailHelperInterface::class);
$helper->method('generateSignature')
->willReturn($component);

return $helper;
}

/**
* @throws \ReflectionException
*/
private function createUser(): User
{
$user = new User();
$user->setUsername('username')
->setEmail('email@example.com');

return self::setId($user);
}

/**
* @throws Exception
*/
private function createVerifyEmailHelper(): VerifyEmailHelper
{
$router = $this->createMock(UrlGeneratorInterface::class);
$uriSigner = $this->createMock(UriSigner::class);
$uriSigner->method('checkRequest')
->willReturn(true);

$queryUtility = $this->createMock(VerifyEmailQueryUtility::class);
$generator = $this->createMock(VerifyEmailTokenGenerator::class);

return new VerifyEmailHelper(
$router,
$uriSigner,
$queryUtility,
$generator,
3600
);
}
}
94 changes: 94 additions & 0 deletions tests/Service/MailerServiceTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php
/*
* This file is part of the Calculation package.
*
* (c) bibi.nu <bibi@bibi.nu>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace App\Tests\Service;

use App\Entity\User;
use App\Enums\Importance;
use App\Model\Comment;
use App\Service\MailerService;
use App\Tests\TranslatorMockTrait;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\MockObject\Exception;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Twig\Extra\Markdown\MarkdownInterface;

#[CoversClass(MailerService::class)]
class MailerServiceTest extends TestCase
{
use TranslatorMockTrait;

/**
* @throws Exception
* @throws TransportExceptionInterface
*/
public function testSendComment(): void
{
$comment = new Comment();
$comment->setFromAddress('from@example.com')
->setToAddress('to@example.com')
->setSubject('subject')
->setMessage('message')
->setAttachments([$this->createAttachement()]);

$service = $this->createService();
$service->sendComment($comment);
self::assertTrue(true);
}

/**
* @throws Exception
* @throws TransportExceptionInterface
*/
public function testSendNotification(): void
{
$toUser = new User();
$toUser->setUsername('username')
->setEmail('to@example.com');
$service = $this->createService();
$service->sendNotification(
'from@example.com',
$toUser,
'message',
Importance::LOW,
[$this->createAttachement()]
);
self::assertTrue(true);
}

private function createAttachement(): UploadedFile
{
return new UploadedFile(__FILE__, \basename(__FILE__), test: true);
}

/**
* @throws Exception
*/
private function createService(): MailerService
{
$generator = $this->createMock(UrlGeneratorInterface::class);
$markdown = $this->createMock(MarkdownInterface::class);
$mailer = $this->createMock(MailerInterface::class);
$translator = $this->createMockTranslator();

return new MailerService(
$generator,
$markdown,
$mailer,
$translator
);
}
}
Loading

0 comments on commit a02fcb3

Please sign in to comment.