|
@@ -0,0 +1,684 @@
|
|
|
|
|
+<?php
|
|
|
|
|
+
|
|
|
|
|
+declare(strict_types=1);
|
|
|
|
|
+
|
|
|
|
|
+namespace App\Tests\Unit\Service\Shop;
|
|
|
|
|
+
|
|
|
|
|
+use App\ApiResources\Organization\OrganizationCreationRequest;
|
|
|
|
|
+use App\ApiResources\Shop\NewStructureArtistPremiumTrialRequest;
|
|
|
|
|
+use App\Entity\Organization\Organization;
|
|
|
|
|
+use App\Entity\Shop\ShopRequest;
|
|
|
|
|
+use App\Enum\Organization\LegalEnum;
|
|
|
|
|
+use App\Enum\Organization\PrincipalTypeEnum;
|
|
|
|
|
+use App\Enum\Organization\SettingsProductEnum;
|
|
|
|
|
+use App\Enum\Shop\ShopRequestStatus;
|
|
|
|
|
+use App\Enum\Shop\ShopRequestType;
|
|
|
|
|
+use App\Message\Message\Shop\NewStructureArtistPremiumTrial;
|
|
|
|
|
+use App\Service\Mailer\Mailer;
|
|
|
|
|
+use App\Service\Organization\OrganizationFactory;
|
|
|
|
|
+use App\Service\Shop\ShopService;
|
|
|
|
|
+use App\Service\Shop\Trial;
|
|
|
|
|
+use App\Service\Utils\DatesUtils;
|
|
|
|
|
+use Doctrine\ORM\EntityManagerInterface;
|
|
|
|
|
+use libphonenumber\PhoneNumberUtil;
|
|
|
|
|
+use PHPUnit\Framework\MockObject\MockObject;
|
|
|
|
|
+use PHPUnit\Framework\TestCase;
|
|
|
|
|
+use Psr\Log\LoggerInterface;
|
|
|
|
|
+use Symfony\Component\Messenger\Envelope;
|
|
|
|
|
+use Symfony\Component\Messenger\MessageBusInterface;
|
|
|
|
|
+use Symfony\Component\Serializer\SerializerInterface;
|
|
|
|
|
+
|
|
|
|
|
+class TestableShopService extends ShopService
|
|
|
|
|
+{
|
|
|
|
|
+ public PhoneNumberUtil $phoneNumberUtil;
|
|
|
|
|
+
|
|
|
|
|
+ public function controlShopRequestData(ShopRequestType $type, array $data): void
|
|
|
|
|
+ {
|
|
|
|
|
+ parent::controlShopRequestData($type, $data);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function createRequest(ShopRequestType $type, array $data): ShopRequest
|
|
|
|
|
+ {
|
|
|
|
|
+ return parent::createRequest($type, $data);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function sendRequestValidationLink(ShopRequest $shopRequest): void
|
|
|
|
|
+ {
|
|
|
|
|
+ parent::sendRequestValidationLink($shopRequest);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function handleNewStructureArtistPremiumTrialRequest(string $token): void
|
|
|
|
|
+ {
|
|
|
|
|
+ parent::handleNewStructureArtistPremiumTrialRequest($token);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function createOrganization(NewStructureArtistPremiumTrialRequest $trialRequest): Organization
|
|
|
|
|
+ {
|
|
|
|
|
+ return parent::createOrganization($trialRequest);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function generateSubdomain(string $name): string
|
|
|
|
|
+ {
|
|
|
|
|
+ return parent::generateSubdomain($name);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function validateNewStructureArtistPremiumTrialRequest(array $data): void
|
|
|
|
|
+ {
|
|
|
|
|
+ parent::validateNewStructureArtistPremiumTrialRequest($data);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function createOrganizationCreationRequestFromTrialRequest(
|
|
|
|
|
+ NewStructureArtistPremiumTrialRequest $trialRequest,
|
|
|
|
|
+ ): OrganizationCreationRequest {
|
|
|
|
|
+ return parent::createOrganizationCreationRequestFromTrialRequest($trialRequest);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function sendMailToSalesAdministration(NewStructureArtistPremiumTrialRequest $trialRequest): void
|
|
|
|
|
+ {
|
|
|
|
|
+ parent::sendMailToSalesAdministration($trialRequest);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function sendConfirmationMailToRepresentative(NewStructureArtistPremiumTrialRequest $trialRequest): void
|
|
|
|
|
+ {
|
|
|
|
|
+ parent::sendConfirmationMailToRepresentative($trialRequest);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/**
|
|
|
|
|
+ * Unit tests for ShopService.
|
|
|
|
|
+ */
|
|
|
|
|
+class ShopServiceTest extends TestCase
|
|
|
|
|
+{
|
|
|
|
|
+ private readonly MockObject|EntityManagerInterface $entityManager;
|
|
|
|
|
+ private readonly MockObject|Mailer $mailer;
|
|
|
|
|
+ private string $publicBaseUrl;
|
|
|
|
|
+ private string $adminBaseUrl;
|
|
|
|
|
+ private readonly MockObject|OrganizationFactory $organizationFactory;
|
|
|
|
|
+ private readonly MockObject|SerializerInterface $serializer;
|
|
|
|
|
+ private readonly MockObject|LoggerInterface $logger;
|
|
|
|
|
+ private readonly MockObject|MessageBusInterface $messageBus;
|
|
|
|
|
+ private readonly MockObject|Trial $trial;
|
|
|
|
|
+ private string $faqUrl;
|
|
|
|
|
+ private string $softwareWebsiteUrl;
|
|
|
|
|
+
|
|
|
|
|
+ public function setUp(): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $this->entityManager = $this->getMockBuilder(EntityManagerInterface::class)->disableOriginalConstructor()->getMock();
|
|
|
|
|
+ $this->mailer = $this->getMockBuilder(Mailer::class)->disableOriginalConstructor()->getMock();
|
|
|
|
|
+ $this->publicBaseUrl = 'https://example.com';
|
|
|
|
|
+ $this->adminBaseUrl = 'https://admin.example.com';
|
|
|
|
|
+ $this->organizationFactory = $this->getMockBuilder(OrganizationFactory::class)->disableOriginalConstructor()->getMock();
|
|
|
|
|
+ $this->serializer = $this->getMockBuilder(SerializerInterface::class)->disableOriginalConstructor()->getMock();
|
|
|
|
|
+ $this->logger = $this->getMockBuilder(LoggerInterface::class)->disableOriginalConstructor()->getMock();
|
|
|
|
|
+ $this->messageBus = $this->getMockBuilder(MessageBusInterface::class)->disableOriginalConstructor()->getMock();
|
|
|
|
|
+ $this->trial = $this->getMockBuilder(Trial::class)->disableOriginalConstructor()->getMock();
|
|
|
|
|
+ $this->faqUrl = 'https://faq.example.com';
|
|
|
|
|
+ $this->softwareWebsiteUrl = 'https://software.example.com';
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private function getShopServiceMockFor(string $methodName): TestableShopService|MockObject
|
|
|
|
|
+ {
|
|
|
|
|
+ $shopService = $this
|
|
|
|
|
+ ->getMockBuilder(TestableShopService::class)
|
|
|
|
|
+ ->setConstructorArgs(
|
|
|
|
|
+ [
|
|
|
|
|
+ $this->entityManager,
|
|
|
|
|
+ $this->mailer,
|
|
|
|
|
+ $this->publicBaseUrl,
|
|
|
|
|
+ $this->adminBaseUrl,
|
|
|
|
|
+ $this->organizationFactory,
|
|
|
|
|
+ $this->serializer,
|
|
|
|
|
+ $this->logger,
|
|
|
|
|
+ $this->messageBus,
|
|
|
|
|
+ $this->trial,
|
|
|
|
|
+ $this->faqUrl,
|
|
|
|
|
+ $this->softwareWebsiteUrl,
|
|
|
|
|
+ ]
|
|
|
|
|
+ )
|
|
|
|
|
+ ->setMethodsExcept([$methodName])
|
|
|
|
|
+ ->getMock();
|
|
|
|
|
+
|
|
|
|
|
+ return $shopService;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public function tearDown(): void
|
|
|
|
|
+ {
|
|
|
|
|
+ DatesUtils::clearFakeDatetime();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Test registerNewShopRequest method.
|
|
|
|
|
+ */
|
|
|
|
|
+ public function testRegisterNewShopRequest(): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $shopService = $this->getShopServiceMockFor('registerNewShopRequest');
|
|
|
|
|
+
|
|
|
|
|
+ $type = ShopRequestType::NEW_STRUCTURE_ARTIST_PREMIUM_TRIAL;
|
|
|
|
|
+ $data = [
|
|
|
|
|
+ 'representativeEmail' => 'test@example.com',
|
|
|
|
|
+ 'representativeFirstName' => 'John',
|
|
|
|
|
+ 'representativeLastName' => 'Doe',
|
|
|
|
|
+ 'structureName' => 'Test Structure',
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ $shopRequest = $this->getMockBuilder(ShopRequest::class)->getMock();
|
|
|
|
|
+
|
|
|
|
|
+ $shopService->expects(self::once())
|
|
|
|
|
+ ->method('controlShopRequestData')
|
|
|
|
|
+ ->with($type, $data);
|
|
|
|
|
+
|
|
|
|
|
+ $shopService->expects(self::once())
|
|
|
|
|
+ ->method('createRequest')
|
|
|
|
|
+ ->with($type, $data)
|
|
|
|
|
+ ->willReturn($shopRequest);
|
|
|
|
|
+
|
|
|
|
|
+ $shopService->expects(self::once())
|
|
|
|
|
+ ->method('sendRequestValidationLink')
|
|
|
|
|
+ ->with($shopRequest);
|
|
|
|
|
+
|
|
|
|
|
+ $result = $shopService->registerNewShopRequest($type, $data);
|
|
|
|
|
+
|
|
|
|
|
+ $this->assertSame($shopRequest, $result);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Test controlShopRequestData method for NEW_STRUCTURE_ARTIST_PREMIUM_TRIAL type.
|
|
|
|
|
+ */
|
|
|
|
|
+ public function testControlShopRequestDataForNewStructureArtistPremiumTrial(): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $shopService = $this->getShopServiceMockFor('controlShopRequestData');
|
|
|
|
|
+
|
|
|
|
|
+ $type = ShopRequestType::NEW_STRUCTURE_ARTIST_PREMIUM_TRIAL;
|
|
|
|
|
+ $data = [
|
|
|
|
|
+ 'representativeEmail' => 'test@example.com',
|
|
|
|
|
+ 'representativeFirstName' => 'John',
|
|
|
|
|
+ 'representativeLastName' => 'Doe',
|
|
|
|
|
+ 'structureName' => 'Test Structure',
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ $shopService->expects(self::once())
|
|
|
|
|
+ ->method('validateNewStructureArtistPremiumTrialRequest')
|
|
|
|
|
+ ->with($data);
|
|
|
|
|
+
|
|
|
|
|
+ $shopService->controlShopRequestData($type, $data);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Test processShopRequest method for NEW_STRUCTURE_ARTIST_PREMIUM_TRIAL type.
|
|
|
|
|
+ */
|
|
|
|
|
+ public function testProcessShopRequest(): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $shopService = $this->getShopServiceMockFor('processShopRequest');
|
|
|
|
|
+
|
|
|
|
|
+ $shopRequest = $this->getMockBuilder(ShopRequest::class)->getMock();
|
|
|
|
|
+ $shopRequest->method('getType')->willReturn(ShopRequestType::NEW_STRUCTURE_ARTIST_PREMIUM_TRIAL);
|
|
|
|
|
+ $shopRequest->method('getToken')->willReturn('test-token');
|
|
|
|
|
+
|
|
|
|
|
+ $this->messageBus
|
|
|
|
|
+ ->expects(self::once())
|
|
|
|
|
+ ->method('dispatch')
|
|
|
|
|
+ ->with(self::callback(function ($message) {
|
|
|
|
|
+ return $message instanceof NewStructureArtistPremiumTrial
|
|
|
|
|
+ && $message->getToken() === 'test-token';
|
|
|
|
|
+ }))
|
|
|
|
|
+ ->willReturn(new Envelope(new NewStructureArtistPremiumTrial('azerty')));
|
|
|
|
|
+
|
|
|
|
|
+ $shopRequest
|
|
|
|
|
+ ->expects(self::once())
|
|
|
|
|
+ ->method('setStatus')
|
|
|
|
|
+ ->with(ShopRequestStatus::VALIDATED);
|
|
|
|
|
+
|
|
|
|
|
+ $this->entityManager->expects(self::once())
|
|
|
|
|
+ ->method('persist')
|
|
|
|
|
+ ->with($shopRequest);
|
|
|
|
|
+
|
|
|
|
|
+ $this->entityManager->expects(self::once())
|
|
|
|
|
+ ->method('flush');
|
|
|
|
|
+
|
|
|
|
|
+ $shopService->processShopRequest($shopRequest);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Test createRequest method.
|
|
|
|
|
+ */
|
|
|
|
|
+ public function testCreateRequest(): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $shopService = $this->getShopServiceMockFor('createRequest');
|
|
|
|
|
+
|
|
|
|
|
+ $uuidRx = '/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i';
|
|
|
|
|
+
|
|
|
|
|
+ $type = ShopRequestType::NEW_STRUCTURE_ARTIST_PREMIUM_TRIAL;
|
|
|
|
|
+ $data = [
|
|
|
|
|
+ 'representativeEmail' => 'test@example.com',
|
|
|
|
|
+ 'representativeFirstName' => 'John',
|
|
|
|
|
+ 'representativeLastName' => 'Doe',
|
|
|
|
|
+ 'structureName' => 'Test Structure',
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ $this->entityManager->expects(self::once())
|
|
|
|
|
+ ->method('persist')
|
|
|
|
|
+ ->with(self::callback(function ($shopRequest) use ($type, $data, $uuidRx) {
|
|
|
|
|
+ return $shopRequest instanceof ShopRequest
|
|
|
|
|
+ && $shopRequest->getType() === $type
|
|
|
|
|
+ && $shopRequest->getData() === $data
|
|
|
|
|
+ && preg_match($uuidRx, $shopRequest->getToken());
|
|
|
|
|
+ }));
|
|
|
|
|
+
|
|
|
|
|
+ $this->entityManager->expects(self::once())
|
|
|
|
|
+ ->method('flush');
|
|
|
|
|
+
|
|
|
|
|
+ $result = $shopService->createRequest($type, $data);
|
|
|
|
|
+
|
|
|
|
|
+ $this->assertInstanceOf(ShopRequest::class, $result);
|
|
|
|
|
+ $this->assertSame($type, $result->getType());
|
|
|
|
|
+ $this->assertSame($data, $result->getData());
|
|
|
|
|
+ $this->assertMatchesRegularExpression($uuidRx, $result->getToken());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Test sendRequestValidationLink method.
|
|
|
|
|
+ */
|
|
|
|
|
+ public function testSendRequestValidationLink(): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $shopService = $this->getShopServiceMockFor('sendRequestValidationLink');
|
|
|
|
|
+
|
|
|
|
|
+ $token = 'test-token';
|
|
|
|
|
+ $data = [
|
|
|
|
|
+ 'representativeEmail' => 'test@example.com',
|
|
|
|
|
+ 'representativeFirstName' => 'John',
|
|
|
|
|
+ 'representativeLastName' => 'Doe',
|
|
|
|
|
+ 'structureName' => 'Test Structure',
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ $shopRequest = $this->getMockBuilder(ShopRequest::class)->getMock();
|
|
|
|
|
+ $shopRequest->method('getToken')->willReturn($token);
|
|
|
|
|
+ $shopRequest->method('getData')->willReturn($data);
|
|
|
|
|
+
|
|
|
|
|
+ $this->mailer
|
|
|
|
|
+ ->expects(self::once())
|
|
|
|
|
+ ->method('main')
|
|
|
|
|
+ ->with(self::callback(function ($model) use ($token, $data) {
|
|
|
|
|
+ return $model->getToken() === $token
|
|
|
|
|
+ && $model->getRepresentativeEmail() === $data['representativeEmail']
|
|
|
|
|
+ && $model->getRepresentativeFirstName() === $data['representativeFirstName']
|
|
|
|
|
+ && $model->getRepresentativeLastName() === $data['representativeLastName']
|
|
|
|
|
+ && $model->getStructureName() === $data['structureName']
|
|
|
|
|
+ && $model->getValidationUrl() === 'https://software.example.com/shop/try/validation?token='.$token;
|
|
|
|
|
+ }));
|
|
|
|
|
+
|
|
|
|
|
+ $shopRequest->expects(self::once())
|
|
|
|
|
+ ->method('setStatus')
|
|
|
|
|
+ ->with(ShopRequestStatus::ACTIVATION_LINK_SENT);
|
|
|
|
|
+
|
|
|
|
|
+ $this->entityManager->expects(self::once())
|
|
|
|
|
+ ->method('persist')
|
|
|
|
|
+ ->with($shopRequest);
|
|
|
|
|
+
|
|
|
|
|
+ $this->entityManager->expects(self::once())
|
|
|
|
|
+ ->method('flush');
|
|
|
|
|
+
|
|
|
|
|
+ $shopService->sendRequestValidationLink($shopRequest);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Test handleNewStructureArtistPremiumTrialRequest method.
|
|
|
|
|
+ */
|
|
|
|
|
+ public function testHandleNewStructureArtistPremiumTrialRequest(): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $shopService = $this->getShopServiceMockFor('handleNewStructureArtistPremiumTrialRequest');
|
|
|
|
|
+
|
|
|
|
|
+ $token = 'test-token';
|
|
|
|
|
+ $data = [
|
|
|
|
|
+ 'representativeEmail' => 'test@example.com',
|
|
|
|
|
+ 'representativeFirstName' => 'John',
|
|
|
|
|
+ 'representativeLastName' => 'Doe',
|
|
|
|
|
+ 'structureName' => 'Test Structure',
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ $shopRequest = $this->getMockBuilder(ShopRequest::class)->getMock();
|
|
|
|
|
+ $shopRequest->method('getToken')->willReturn($token);
|
|
|
|
|
+ $shopRequest->method('getData')->willReturn($data);
|
|
|
|
|
+
|
|
|
|
|
+ $this->entityManager
|
|
|
|
|
+ ->expects(self::once())
|
|
|
|
|
+ ->method('find')
|
|
|
|
|
+ ->with(ShopRequest::class, $token)
|
|
|
|
|
+ ->willReturn($shopRequest);
|
|
|
|
|
+
|
|
|
|
|
+ $trialRequest = $this->getMockBuilder(NewStructureArtistPremiumTrialRequest::class)
|
|
|
|
|
+ ->getMock();
|
|
|
|
|
+
|
|
|
|
|
+ $this->serializer
|
|
|
|
|
+ ->expects(self::once())
|
|
|
|
|
+ ->method('deserialize')
|
|
|
|
|
+ ->with(json_encode($data), NewStructureArtistPremiumTrialRequest::class, 'json')
|
|
|
|
|
+ ->willReturn($trialRequest);
|
|
|
|
|
+
|
|
|
|
|
+ $organization = $this->getMockBuilder(Organization::class)->getMock();
|
|
|
|
|
+
|
|
|
|
|
+ $shopService
|
|
|
|
|
+ ->expects(self::once())
|
|
|
|
|
+ ->method('createOrganization')
|
|
|
|
|
+ ->with($trialRequest)
|
|
|
|
|
+ ->willReturn($organization);
|
|
|
|
|
+
|
|
|
|
|
+ // Add expectation for password setting
|
|
|
|
|
+ $trialRequest->method('getPassword')->willReturn('Password123!');
|
|
|
|
|
+
|
|
|
|
|
+ $this->organizationFactory
|
|
|
|
|
+ ->expects(self::once())
|
|
|
|
|
+ ->method('setAdminAccountPassword')
|
|
|
|
|
+ ->with($organization, 'Password123!');
|
|
|
|
|
+
|
|
|
|
|
+ $this->trial
|
|
|
|
|
+ ->expects(self::once())
|
|
|
|
|
+ ->method('startArtistPremiumTrialForNewStructure')
|
|
|
|
|
+ ->with($organization, $trialRequest);
|
|
|
|
|
+
|
|
|
|
|
+ // Mock the sendMailToSalesAdministration and sendConfirmationMailToRepresentative methods
|
|
|
|
|
+ $shopService->expects(self::once())
|
|
|
|
|
+ ->method('sendMailToSalesAdministration')
|
|
|
|
|
+ ->with($trialRequest);
|
|
|
|
|
+
|
|
|
|
|
+ $shopService->expects(self::once())
|
|
|
|
|
+ ->method('sendConfirmationMailToRepresentative')
|
|
|
|
|
+ ->with($trialRequest);
|
|
|
|
|
+
|
|
|
|
|
+ $this->logger->expects(self::once())
|
|
|
|
|
+ ->method('info')
|
|
|
|
|
+ ->with('Successfully processed NewStructureArtistPremiumTrial for token: '.$token);
|
|
|
|
|
+
|
|
|
|
|
+ $shopService->handleNewStructureArtistPremiumTrialRequest($token);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Test handleNewStructureArtistPremiumTrialRequest method with non-existent token.
|
|
|
|
|
+ */
|
|
|
|
|
+ public function testHandleNewStructureArtistPremiumTrialRequestWithNonExistentToken(): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $shopService = $this->getShopServiceMockFor('handleNewStructureArtistPremiumTrialRequest');
|
|
|
|
|
+
|
|
|
|
|
+ $this->entityManager->expects(self::once())
|
|
|
|
|
+ ->method('find')
|
|
|
|
|
+ ->with(ShopRequest::class, 'non-existent-token')
|
|
|
|
|
+ ->willReturn(null);
|
|
|
|
|
+
|
|
|
|
|
+ $this->logger->expects(self::once())
|
|
|
|
|
+ ->method('error')
|
|
|
|
|
+ ->with('Cannot find ShopRequest with token: non-existent-token');
|
|
|
|
|
+
|
|
|
|
|
+ $shopService->handleNewStructureArtistPremiumTrialRequest('non-existent-token');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Test handleNewStructureArtistPremiumTrialRequest method when an exception occurs.
|
|
|
|
|
+ */
|
|
|
|
|
+ public function testHandleNewStructureArtistPremiumTrialRequestWithException(): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $shopService = $this->getShopServiceMockFor('handleNewStructureArtistPremiumTrialRequest');
|
|
|
|
|
+
|
|
|
|
|
+ $token = 'test-token';
|
|
|
|
|
+ $data = [
|
|
|
|
|
+ 'representativeEmail' => 'test@example.com',
|
|
|
|
|
+ 'representativeFirstName' => 'John',
|
|
|
|
|
+ 'representativeLastName' => 'Doe',
|
|
|
|
|
+ 'structureName' => 'Test Structure',
|
|
|
|
|
+ ];
|
|
|
|
|
+
|
|
|
|
|
+ $shopRequest = $this->getMockBuilder(ShopRequest::class)->getMock();
|
|
|
|
|
+ $shopRequest->method('getToken')->willReturn($token);
|
|
|
|
|
+ $shopRequest->method('getData')->willReturn($data);
|
|
|
|
|
+
|
|
|
|
|
+ // Expect setStatus to be called with ERROR
|
|
|
|
|
+ $shopRequest->expects(self::once())
|
|
|
|
|
+ ->method('setStatus')
|
|
|
|
|
+ ->with(ShopRequestStatus::ERROR);
|
|
|
|
|
+
|
|
|
|
|
+ $this->entityManager
|
|
|
|
|
+ ->expects(self::once())
|
|
|
|
|
+ ->method('find')
|
|
|
|
|
+ ->with(ShopRequest::class, $token)
|
|
|
|
|
+ ->willReturn($shopRequest);
|
|
|
|
|
+
|
|
|
|
|
+ // Simulate an exception during deserialization
|
|
|
|
|
+ $this->serializer
|
|
|
|
|
+ ->expects(self::once())
|
|
|
|
|
+ ->method('deserialize')
|
|
|
|
|
+ ->willThrowException(new \Exception('Test exception'));
|
|
|
|
|
+
|
|
|
|
|
+ // Expect persist and flush to be called to save the ERROR status
|
|
|
|
|
+ $this->entityManager
|
|
|
|
|
+ ->expects(self::once())
|
|
|
|
|
+ ->method('persist')
|
|
|
|
|
+ ->with($shopRequest);
|
|
|
|
|
+
|
|
|
|
|
+ $this->entityManager
|
|
|
|
|
+ ->expects(self::once())
|
|
|
|
|
+ ->method('flush');
|
|
|
|
|
+
|
|
|
|
|
+ // Expect error to be logged
|
|
|
|
|
+ $this->logger->expects(self::once())
|
|
|
|
|
+ ->method('error')
|
|
|
|
|
+ ->with(self::stringContains('Error processing NewStructureArtistPremiumTrial for token: '.$token));
|
|
|
|
|
+
|
|
|
|
|
+ // Expect the exception to be re-thrown
|
|
|
|
|
+ $this->expectException(\Exception::class);
|
|
|
|
|
+ $this->expectExceptionMessage('Test exception');
|
|
|
|
|
+
|
|
|
|
|
+ $shopService->handleNewStructureArtistPremiumTrialRequest($token);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Test createOrganization method.
|
|
|
|
|
+ */
|
|
|
|
|
+ public function testCreateOrganization(): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $shopService = $this->getShopServiceMockFor('createOrganization');
|
|
|
|
|
+
|
|
|
|
|
+ $trialRequest = $this
|
|
|
|
|
+ ->getMockBuilder(NewStructureArtistPremiumTrialRequest::class)
|
|
|
|
|
+ ->getMock();
|
|
|
|
|
+
|
|
|
|
|
+ $organizationCreationRequest = $this
|
|
|
|
|
+ ->getMockBuilder(OrganizationCreationRequest::class)
|
|
|
|
|
+ ->getMock();
|
|
|
|
|
+
|
|
|
|
|
+ $organization = $this->getMockBuilder(Organization::class)->getMock();
|
|
|
|
|
+
|
|
|
|
|
+ $shopService->expects(self::once())
|
|
|
|
|
+ ->method('createOrganizationCreationRequestFromTrialRequest')
|
|
|
|
|
+ ->with($trialRequest)
|
|
|
|
|
+ ->willReturn($organizationCreationRequest);
|
|
|
|
|
+
|
|
|
|
|
+ $this->organizationFactory
|
|
|
|
|
+ ->expects(self::once())
|
|
|
|
|
+ ->method('create')
|
|
|
|
|
+ ->with($organizationCreationRequest)
|
|
|
|
|
+ ->willReturn($organization);
|
|
|
|
|
+
|
|
|
|
|
+ $result = $shopService->createOrganization($trialRequest);
|
|
|
|
|
+
|
|
|
|
|
+ $this->assertSame($organization, $result);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Test validateNewStructureArtistPremiumTrialRequest method with valid data.
|
|
|
|
|
+ */
|
|
|
|
|
+ public function testValidateNewStructureArtistPremiumTrialRequest(): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $shopService = $this->getShopServiceMockFor('validateNewStructureArtistPremiumTrialRequest');
|
|
|
|
|
+
|
|
|
|
|
+ $phoneNumberUtil = $this
|
|
|
|
|
+ ->getMockBuilder(PhoneNumberUtil::class)
|
|
|
|
|
+ ->disableOriginalConstructor()
|
|
|
|
|
+ ->getMock();
|
|
|
|
|
+ $shopService->phoneNumberUtil = $phoneNumberUtil;
|
|
|
|
|
+
|
|
|
|
|
+ $trialRequest = $this
|
|
|
|
|
+ ->getMockBuilder(NewStructureArtistPremiumTrialRequest::class)
|
|
|
|
|
+ ->getMock();
|
|
|
|
|
+ $trialRequest->method('getRepresentativePhone')->willReturn('+33123456789');
|
|
|
|
|
+
|
|
|
|
|
+ $organizationCreationRequest = $this
|
|
|
|
|
+ ->getMockBuilder(OrganizationCreationRequest::class)
|
|
|
|
|
+ ->getMock();
|
|
|
|
|
+
|
|
|
|
|
+ $shopService->expects(self::once())
|
|
|
|
|
+ ->method('createOrganizationCreationRequestFromTrialRequest')
|
|
|
|
|
+ ->with($trialRequest)
|
|
|
|
|
+ ->willReturn($organizationCreationRequest);
|
|
|
|
|
+
|
|
|
|
|
+ $phoneNumberUtil->expects(self::once())
|
|
|
|
|
+ ->method('isPossibleNumber')
|
|
|
|
|
+ ->with('+33123456789')
|
|
|
|
|
+ ->willReturn(true);
|
|
|
|
|
+
|
|
|
|
|
+ $this->organizationFactory->expects(self::once())
|
|
|
|
|
+ ->method('interruptIfOrganizationExists')
|
|
|
|
|
+ ->with($organizationCreationRequest);
|
|
|
|
|
+
|
|
|
|
|
+ // Convert the trial request to an array for validation
|
|
|
|
|
+ $data = [
|
|
|
|
|
+ 'representativePhone' => '+33123456789',
|
|
|
|
|
+ ];
|
|
|
|
|
+ $this->serializer->expects(self::once())
|
|
|
|
|
+ ->method('deserialize')
|
|
|
|
|
+ ->with(json_encode($data), NewStructureArtistPremiumTrialRequest::class, 'json')
|
|
|
|
|
+ ->willReturn($trialRequest);
|
|
|
|
|
+
|
|
|
|
|
+ $shopService->validateNewStructureArtistPremiumTrialRequest($data);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Test validateNewStructureArtistPremiumTrialRequest method with invalid phone number.
|
|
|
|
|
+ */
|
|
|
|
|
+ public function testValidateNewStructureArtistPremiumTrialRequestWithInvalidPhoneNumber(): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $shopService = $this->getShopServiceMockFor('validateNewStructureArtistPremiumTrialRequest');
|
|
|
|
|
+
|
|
|
|
|
+ $phoneNumberUtil = $this->getMockBuilder(PhoneNumberUtil::class)
|
|
|
|
|
+ ->disableOriginalConstructor()
|
|
|
|
|
+ ->getMock();
|
|
|
|
|
+ $shopService->phoneNumberUtil = $phoneNumberUtil;
|
|
|
|
|
+
|
|
|
|
|
+ $trialRequest = $this
|
|
|
|
|
+ ->getMockBuilder(NewStructureArtistPremiumTrialRequest::class)
|
|
|
|
|
+ ->getMock();
|
|
|
|
|
+ $trialRequest->method('getRepresentativePhone')->willReturn('invalid-phone');
|
|
|
|
|
+
|
|
|
|
|
+ // Mock the phoneNumberUtil to return false for isPossibleNumber
|
|
|
|
|
+ $phoneNumberUtil->expects(self::once())
|
|
|
|
|
+ ->method('isPossibleNumber')
|
|
|
|
|
+ ->with('invalid-phone')
|
|
|
|
|
+ ->willReturn(false);
|
|
|
|
|
+
|
|
|
|
|
+ // Convert the trial request to an array for validation
|
|
|
|
|
+ $data = [
|
|
|
|
|
+ 'representativePhone' => 'invalid-phone',
|
|
|
|
|
+ ];
|
|
|
|
|
+ $this->serializer->expects(self::once())
|
|
|
|
|
+ ->method('deserialize')
|
|
|
|
|
+ ->with(json_encode($data), NewStructureArtistPremiumTrialRequest::class, 'json')
|
|
|
|
|
+ ->willReturn($trialRequest);
|
|
|
|
|
+
|
|
|
|
|
+ $this->expectException(\RuntimeException::class);
|
|
|
|
|
+ $this->expectExceptionMessage('Invalid phone number');
|
|
|
|
|
+
|
|
|
|
|
+ $shopService->validateNewStructureArtistPremiumTrialRequest($data);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Test createOrganizationCreationRequestFromTrialRequest method with forValidationOnly=false.
|
|
|
|
|
+ */
|
|
|
|
|
+ public function testCreateOrganizationCreationRequestFromTrialRequestComplete(): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $shopService = $this->getShopServiceMockFor('createOrganizationCreationRequestFromTrialRequest');
|
|
|
|
|
+
|
|
|
|
|
+ $trialRequest = $this->getMockBuilder(NewStructureArtistPremiumTrialRequest::class)
|
|
|
|
|
+ ->getMock();
|
|
|
|
|
+ $trialRequest->method('getStructureName')->willReturn('Test Structure');
|
|
|
|
|
+ $trialRequest->method('getCity')->willReturn('Test City');
|
|
|
|
|
+ $trialRequest->method('getPostalCode')->willReturn('12345');
|
|
|
|
|
+ $trialRequest->method('getAddress')->willReturn('Test Address');
|
|
|
|
|
+ $trialRequest->method('getAddressComplement')->willReturn('Test Address Complement');
|
|
|
|
|
+ $trialRequest->method('getRepresentativePhone')->willReturn('+33123456789');
|
|
|
|
|
+ $trialRequest->method('getStructureEmail')->willReturn('structure@example.com');
|
|
|
|
|
+ $trialRequest->method('getStructureType')->willReturn(PrincipalTypeEnum::ARTISTIC_EDUCATION_ONLY);
|
|
|
|
|
+ $trialRequest->method('getLegalStatus')->willReturn(LegalEnum::ASSOCIATION_LAW_1901);
|
|
|
|
|
+ $trialRequest->method('getSiren')->willReturn('123456789');
|
|
|
|
|
+ $trialRequest->method('getStructureIdentifier')->willReturn('test-structure');
|
|
|
|
|
+
|
|
|
|
|
+ // Set a fake date for testing
|
|
|
|
|
+ $fakeDate = '2023-05-15 10:30:00';
|
|
|
|
|
+ DatesUtils::setFakeDatetime($fakeDate);
|
|
|
|
|
+
|
|
|
|
|
+ // Create the organization creation request
|
|
|
|
|
+ $result = $shopService->createOrganizationCreationRequestFromTrialRequest($trialRequest);
|
|
|
|
|
+
|
|
|
|
|
+ // Verify that all fields are set
|
|
|
|
|
+ $this->assertEquals('Test Structure', $result->getName());
|
|
|
|
|
+ $this->assertEquals('Test City', $result->getCity());
|
|
|
|
|
+ $this->assertEquals('12345', $result->getPostalCode());
|
|
|
|
|
+ $this->assertEquals('Test Address', $result->getStreetAddress1());
|
|
|
|
|
+ $this->assertEquals('Test Address Complement', $result->getStreetAddress2());
|
|
|
|
|
+ $this->assertEquals('structure@example.com', $result->getEmail());
|
|
|
|
|
+ $this->assertEquals(PrincipalTypeEnum::ARTISTIC_EDUCATION_ONLY, $result->getPrincipalType());
|
|
|
|
|
+ $this->assertEquals(LegalEnum::ASSOCIATION_LAW_1901, $result->getLegalStatus());
|
|
|
|
|
+ $this->assertEquals('123456789', $result->getSiretNumber());
|
|
|
|
|
+ $this->assertEquals('+33123456789', $result->getPhoneNumber());
|
|
|
|
|
+ $this->assertEquals('test-structure', $result->getSubdomain());
|
|
|
|
|
+ $this->assertEquals(SettingsProductEnum::FREEMIUM, $result->getProduct());
|
|
|
|
|
+ $this->assertFalse($result->getCreateWebsite());
|
|
|
|
|
+ $this->assertFalse($result->isClient());
|
|
|
|
|
+ $this->assertEquals(new \DateTime($fakeDate), $result->getCreationDate());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Test sendMailToSalesAdministration method.
|
|
|
|
|
+ */
|
|
|
|
|
+ public function testSendMailToSalesAdministration(): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $shopService = $this->getShopServiceMockFor('sendMailToSalesAdministration');
|
|
|
|
|
+
|
|
|
|
|
+ $trialRequest = $this->getMockBuilder(NewStructureArtistPremiumTrialRequest::class)
|
|
|
|
|
+ ->getMock();
|
|
|
|
|
+
|
|
|
|
|
+ $this->mailer
|
|
|
|
|
+ ->expects(self::once())
|
|
|
|
|
+ ->method('main')
|
|
|
|
|
+ ->with(self::callback(function ($model) use ($trialRequest) {
|
|
|
|
|
+ return $model instanceof \App\Service\Mailer\Model\Shop\NewStructureArtistPremium\NotificationToSalesAdminModel
|
|
|
|
|
+ && $model->getTrialRequest() === $trialRequest
|
|
|
|
|
+ && $model->getSenderId() === \App\Enum\Access\AccessIdsEnum::ADMIN_2IOPENSERVICE->value;
|
|
|
|
|
+ }));
|
|
|
|
|
+
|
|
|
|
|
+ $shopService->sendMailToSalesAdministration($trialRequest);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * Test sendConfirmationMailToRepresentative method.
|
|
|
|
|
+ */
|
|
|
|
|
+ public function testSendConfirmationMailToRepresentative(): void
|
|
|
|
|
+ {
|
|
|
|
|
+ $shopService = $this->getShopServiceMockFor('sendConfirmationMailToRepresentative');
|
|
|
|
|
+
|
|
|
|
|
+ $trialRequest = $this->getMockBuilder(NewStructureArtistPremiumTrialRequest::class)
|
|
|
|
|
+ ->getMock();
|
|
|
|
|
+ $trialRequest->method('getStructureIdentifier')->willReturn('test-structure');
|
|
|
|
|
+
|
|
|
|
|
+ $this->mailer
|
|
|
|
|
+ ->expects(self::once())
|
|
|
|
|
+ ->method('main')
|
|
|
|
|
+ ->with(self::callback(function ($model) use ($trialRequest) {
|
|
|
|
|
+ return $model instanceof \App\Service\Mailer\Model\Shop\NewStructureArtistPremium\ConfirmationToRepresentativeModel
|
|
|
|
|
+ && $model->getTrialRequest() === $trialRequest
|
|
|
|
|
+ && $model->getSenderId() === \App\Enum\Access\AccessIdsEnum::ADMIN_2IOPENSERVICE->value
|
|
|
|
|
+ && $model->getAccountCreationUrl() === 'https://example.com/account/create'
|
|
|
|
|
+ && $model->getFaqUrl() === 'https://faq.example.com'
|
|
|
|
|
+ && $model->getAdminUsername() === 'admintest-structure'
|
|
|
|
|
+ && $model->getAdminLoginUrl() === 'https://admin.example.com/#/login/';
|
|
|
|
|
+ }));
|
|
|
|
|
+
|
|
|
|
|
+ $shopService->sendConfirmationMailToRepresentative($trialRequest);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|