ShopServiceTest.php 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Tests\Unit\Service\Shop;
  4. use App\ApiResources\Shop\NewStructureArtistPremiumTrialRequest;
  5. use App\Entity\Organization\Organization;
  6. use App\Entity\Organization\Settings;
  7. use App\Entity\Shop\ShopRequest;
  8. use App\Enum\Organization\LegalEnum;
  9. use App\Enum\Organization\PrincipalTypeEnum;
  10. use App\Enum\Organization\SettingsProductEnum;
  11. use App\Enum\Shop\ShopRequestStatus;
  12. use App\Enum\Shop\ShopRequestType;
  13. use App\Message\Message\Shop\NewStructureArtistPremiumTrial;
  14. use App\Service\Dolibarr\DolibarrApiService;
  15. use App\Service\Dolibarr\DolibarrUtils;
  16. use App\Service\Mailer\Mailer;
  17. use App\Service\Organization\OrganizationFactory;
  18. use App\Service\Shop\ShopService;
  19. use App\Service\Utils\DatesUtils;
  20. use Doctrine\ORM\EntityManagerInterface;
  21. use libphonenumber\PhoneNumberUtil;
  22. use PHPUnit\Framework\MockObject\MockObject;
  23. use PHPUnit\Framework\TestCase;
  24. use Psr\Log\LoggerInterface;
  25. use Symfony\Component\Messenger\Envelope;
  26. use Symfony\Component\Messenger\MessageBusInterface;
  27. use Symfony\Component\Serializer\SerializerInterface;
  28. class TestableShopService extends ShopService
  29. {
  30. public PhoneNumberUtil $phoneNumberUtil;
  31. public function controlShopRequestData(ShopRequestType $type, array $data): void
  32. {
  33. parent::controlShopRequestData($type, $data);
  34. }
  35. public function createRequest(ShopRequestType $type, array $data): ShopRequest
  36. {
  37. return parent::createRequest($type, $data);
  38. }
  39. public function sendRequestValidationLink(ShopRequest $shopRequest): void
  40. {
  41. parent::sendRequestValidationLink($shopRequest);
  42. }
  43. public function startArtistPremiumTrial(Organization $organization, NewStructureArtistPremiumTrialRequest $request): void
  44. {
  45. parent::startArtistPremiumTrial($organization, $request);
  46. }
  47. public function handleNewStructureArtistPremiumTrialRequest(string $token): void
  48. {
  49. parent::handleNewStructureArtistPremiumTrialRequest($token);
  50. }
  51. public function createOrganization(NewStructureArtistPremiumTrialRequest $trialRequest): Organization
  52. {
  53. return parent::createOrganization($trialRequest);
  54. }
  55. public function generateSubdomain(string $name): string
  56. {
  57. return parent::generateSubdomain($name);
  58. }
  59. public function validateNewStructureArtistPremiumTrialRequest($request): void
  60. {
  61. parent::validateNewStructureArtistPremiumTrialRequest($request);
  62. }
  63. }
  64. /**
  65. * Unit tests for ShopService
  66. */
  67. class ShopServiceTest extends TestCase
  68. {
  69. private readonly MockObject|EntityManagerInterface $entityManager;
  70. private readonly MockObject|Mailer $mailer;
  71. private string $publicBaseUrl;
  72. private readonly MockObject|OrganizationFactory $organizationFactory;
  73. private readonly MockObject|SerializerInterface $serializer;
  74. private readonly MockObject|LoggerInterface $logger;
  75. private readonly MockObject|DolibarrApiService $dolibarrApiService;
  76. private readonly MockObject|DolibarrUtils $dolibarrUtils;
  77. private readonly MockObject|MessageBusInterface $messageBus;
  78. public function setUp(): void
  79. {
  80. $this->entityManager = $this->getMockBuilder(EntityManagerInterface::class)->disableOriginalConstructor()->getMock();
  81. $this->mailer = $this->getMockBuilder(Mailer::class)->disableOriginalConstructor()->getMock();
  82. $this->publicBaseUrl = 'https://example.com';
  83. $this->organizationFactory = $this->getMockBuilder(OrganizationFactory::class)->disableOriginalConstructor()->getMock();
  84. $this->serializer = $this->getMockBuilder(SerializerInterface::class)->disableOriginalConstructor()->getMock();
  85. $this->logger = $this->getMockBuilder(LoggerInterface::class)->disableOriginalConstructor()->getMock();
  86. $this->dolibarrApiService = $this->getMockBuilder(DolibarrApiService::class)->disableOriginalConstructor()->getMock();
  87. $this->dolibarrUtils = $this->getMockBuilder(DolibarrUtils::class)->disableOriginalConstructor()->getMock();
  88. $this->messageBus = $this->getMockBuilder(MessageBusInterface::class)->disableOriginalConstructor()->getMock();
  89. }
  90. private function getShopServiceMockFor(string $methodName): TestableShopService|MockObject
  91. {
  92. $shopService = $this
  93. ->getMockBuilder(TestableShopService::class)
  94. ->setConstructorArgs(
  95. [
  96. $this->entityManager,
  97. $this->mailer,
  98. $this->publicBaseUrl,
  99. $this->organizationFactory,
  100. $this->serializer,
  101. $this->logger,
  102. $this->dolibarrApiService,
  103. $this->dolibarrUtils,
  104. $this->messageBus,
  105. ]
  106. )
  107. ->setMethodsExcept([$methodName])
  108. ->getMock();
  109. return $shopService;
  110. }
  111. public function tearDown(): void
  112. {
  113. DatesUtils::clearFakeDatetime();
  114. }
  115. /**
  116. * Test registerNewShopRequest method
  117. */
  118. public function testRegisterNewShopRequest(): void
  119. {
  120. $shopService = $this->getShopServiceMockFor('registerNewShopRequest');
  121. $type = ShopRequestType::NEW_STRUCTURE_ARTIST_PREMIUM_TRIAL;
  122. $data = [
  123. 'representativeEmail' => 'test@example.com',
  124. 'representativeFirstName' => 'John',
  125. 'representativeLastName' => 'Doe',
  126. 'structureName' => 'Test Structure',
  127. ];
  128. $shopRequest = $this->getMockBuilder(ShopRequest::class)->getMock();
  129. $shopService->expects(self::once())
  130. ->method('controlShopRequestData')
  131. ->with($type, $data);
  132. $shopService->expects(self::once())
  133. ->method('createRequest')
  134. ->with($type, $data)
  135. ->willReturn($shopRequest);
  136. $shopService->expects(self::once())
  137. ->method('sendRequestValidationLink')
  138. ->with($shopRequest);
  139. $result = $shopService->registerNewShopRequest($type, $data);
  140. $this->assertSame($shopRequest, $result);
  141. }
  142. /**
  143. * Test controlShopRequestData method for NEW_STRUCTURE_ARTIST_PREMIUM_TRIAL type
  144. */
  145. public function testControlShopRequestDataForNewStructureArtistPremiumTrial(): void
  146. {
  147. $shopService = $this->getShopServiceMockFor('controlShopRequestData');
  148. $type = ShopRequestType::NEW_STRUCTURE_ARTIST_PREMIUM_TRIAL;
  149. $data = [
  150. 'representativeEmail' => 'test@example.com',
  151. 'representativeFirstName' => 'John',
  152. 'representativeLastName' => 'Doe',
  153. 'structureName' => 'Test Structure',
  154. ];
  155. $shopService->expects(self::once())
  156. ->method('validateNewStructureArtistPremiumTrialRequest')
  157. ->with($data);
  158. $shopService->controlShopRequestData($type, $data);
  159. }
  160. /**
  161. * Test processShopRequest method for NEW_STRUCTURE_ARTIST_PREMIUM_TRIAL type
  162. */
  163. public function testProcessShopRequest(): void
  164. {
  165. $shopService = $this->getShopServiceMockFor('processShopRequest');
  166. $shopRequest = $this->getMockBuilder(ShopRequest::class)->getMock();
  167. $shopRequest->method('getType')->willReturn(ShopRequestType::NEW_STRUCTURE_ARTIST_PREMIUM_TRIAL);
  168. $shopRequest->method('getToken')->willReturn('test-token');
  169. $this->messageBus
  170. ->expects(self::once())
  171. ->method('dispatch')
  172. ->with(self::callback(function ($message) {
  173. return $message instanceof NewStructureArtistPremiumTrial
  174. && $message->getToken() === 'test-token';
  175. }))
  176. ->willReturn(new Envelope(new NewStructureArtistPremiumTrial('azerty')));
  177. $shopRequest
  178. ->expects(self::once())
  179. ->method('setStatus')
  180. ->with(ShopRequestStatus::VALIDATED);
  181. $this->entityManager->expects(self::once())
  182. ->method('persist')
  183. ->with($shopRequest);
  184. $this->entityManager->expects(self::once())
  185. ->method('flush');
  186. $shopService->processShopRequest($shopRequest);
  187. }
  188. /**
  189. * Test createRequest method
  190. */
  191. public function testCreateRequest(): void
  192. {
  193. $shopService = $this->getShopServiceMockFor('createRequest');
  194. $uuidRx = "/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i";
  195. $type = ShopRequestType::NEW_STRUCTURE_ARTIST_PREMIUM_TRIAL;
  196. $data = [
  197. 'representativeEmail' => 'test@example.com',
  198. 'representativeFirstName' => 'John',
  199. 'representativeLastName' => 'Doe',
  200. 'structureName' => 'Test Structure',
  201. ];
  202. $this->entityManager->expects(self::once())
  203. ->method('persist')
  204. ->with(self::callback(function ($shopRequest) use ($type, $data, $uuidRx) {
  205. return $shopRequest instanceof ShopRequest
  206. && $shopRequest->getType() === $type
  207. && $shopRequest->getData() === $data
  208. && preg_match($uuidRx, $shopRequest->getToken());
  209. }));
  210. $this->entityManager->expects(self::once())
  211. ->method('flush');
  212. $result = $shopService->createRequest($type, $data);
  213. $this->assertInstanceOf(ShopRequest::class, $result);
  214. $this->assertSame($type, $result->getType());
  215. $this->assertSame($data, $result->getData());
  216. $this->assertMatchesRegularExpression($uuidRx, $result->getToken());
  217. }
  218. /**
  219. * Test sendRequestValidationLink method
  220. */
  221. public function testSendRequestValidationLink(): void
  222. {
  223. $shopService = $this->getShopServiceMockFor('sendRequestValidationLink');
  224. $token = 'test-token';
  225. $data = [
  226. 'representativeEmail' => 'test@example.com',
  227. 'representativeFirstName' => 'John',
  228. 'representativeLastName' => 'Doe',
  229. 'structureName' => 'Test Structure',
  230. ];
  231. $shopRequest = $this->getMockBuilder(ShopRequest::class)->getMock();
  232. $shopRequest->method('getToken')->willReturn($token);
  233. $shopRequest->method('getData')->willReturn($data);
  234. $this->mailer
  235. ->expects(self::once())
  236. ->method('main')
  237. ->with(self::callback(function ($model) use ($token, $data) {
  238. var_dump($model);
  239. return $model->getToken() === $token
  240. && $model->getRepresentativeEmail() === $data['representativeEmail']
  241. && $model->getRepresentativeFirstName() === $data['representativeFirstName']
  242. && $model->getRepresentativeLastName() === $data['representativeLastName']
  243. && $model->getStructureName() === $data['structureName']
  244. && $model->getValidationUrl() === 'https://example.com/api/public/shop/validate/' . $token;
  245. }));
  246. $shopRequest->expects(self::once())
  247. ->method('setStatus')
  248. ->with(ShopRequestStatus::ACTIVATION_LINK_SENT);
  249. $this->entityManager->expects(self::once())
  250. ->method('persist')
  251. ->with($shopRequest);
  252. $this->entityManager->expects(self::once())
  253. ->method('flush');
  254. $shopService->sendRequestValidationLink($shopRequest);
  255. }
  256. /**
  257. * Test startArtistPremiumTrial method
  258. */
  259. public function testStartArtistPremiumTrial(): void
  260. {
  261. $shopService = $this->getShopServiceMockFor('startArtistPremiumTrial');
  262. DatesUtils::setFakeDatetime('2025-01-01 12:00:00');
  263. $organization = $this->getMockBuilder(Organization::class)->getMock();
  264. $settings = $this->getMockBuilder(Settings::class)->getMock();
  265. $settings->method('getProduct')->willReturn(SettingsProductEnum::FREEMIUM);
  266. $organization->method('getSettings')->willReturn($settings);
  267. $organization->method('getId')->willReturn(123);
  268. $request = $this->getMockBuilder(NewStructureArtistPremiumTrialRequest::class)->getMock();
  269. $request->method('getRepresentativeFirstName')->willReturn('John');
  270. $request->method('getRepresentativeLastName')->willReturn('Doe');
  271. $request->method('getRepresentativeFunction')->willReturn('Manager');
  272. $request->method('getRepresentativeEmail')->willReturn('test@example.com');
  273. $request->method('getRepresentativePhone')->willReturn('+33123456789');
  274. $settings
  275. ->expects(self::once())
  276. ->method('setProductBeforeTrial')
  277. ->with(SettingsProductEnum::FREEMIUM);
  278. $settings
  279. ->expects(self::once())
  280. ->method('setTrialActive')
  281. ->with(true);
  282. $settings
  283. ->expects(self::once())
  284. ->method('setLastTrialStartDate')
  285. ->with(self::callback(function ($dateTime) {
  286. return $dateTime instanceof \DateTime && $dateTime->format('Y-m-d H:i:s') === '2025-01-01 12:00:00';
  287. }));
  288. $settings->expects(self::once())
  289. ->method('setProduct')
  290. ->with(SettingsProductEnum::ARTIST_PREMIUM);
  291. $this->entityManager->expects(self::once())
  292. ->method('persist')
  293. ->with($settings);
  294. $this->entityManager->expects(self::once())
  295. ->method('flush');
  296. $this->dolibarrApiService->expects(self::once())
  297. ->method('getSocietyId')
  298. ->with(123)
  299. ->willReturn(456);
  300. $this->dolibarrUtils->expects(self::once())
  301. ->method('getProductId')
  302. ->with(SettingsProductEnum::ARTIST_PREMIUM, true)
  303. ->willReturn(789);
  304. $this->dolibarrApiService->expects(self::once())
  305. ->method('createContract')
  306. ->with(456, 789, true, 1)
  307. ->willReturn(101112);
  308. $this->dolibarrApiService->expects(self::once())
  309. ->method('createContractLine')
  310. ->with(101112, 789, 1);
  311. $this->dolibarrUtils->expects(self::once())
  312. ->method('updateSocietyCommercialsWithApi')
  313. ->with(456);
  314. $this->dolibarrUtils->expects(self::once())
  315. ->method('getDolibarrProductName')
  316. ->with(SettingsProductEnum::ARTIST_PREMIUM, true)
  317. ->willReturn('Artist Premium (essai)');
  318. $this->dolibarrApiService->expects(self::once())
  319. ->method('updateSocietyProduct')
  320. ->with(456, 'Artist Premium (essai)');
  321. $this->dolibarrUtils->expects(self::once())
  322. ->method('addActionComm')
  323. ->with(456, "Ouverture de la période d'essai", self::callback(function ($message) {
  324. return strpos($message, 'John') !== false
  325. && strpos($message, 'Doe') !== false
  326. && strpos($message, 'Manager') !== false
  327. && strpos($message, 'test@example.com') !== false
  328. && strpos($message, '+33123456789') !== false;
  329. }));
  330. $shopService->startArtistPremiumTrial($organization, $request);
  331. // Clear the fake date time after the test
  332. DatesUtils::clearFakeDatetime();
  333. }
  334. /**
  335. * Test handleNewStructureArtistPremiumTrialRequest method
  336. */
  337. public function testHandleNewStructureArtistPremiumTrialRequest(): void
  338. {
  339. $shopService = $this->getShopServiceMockFor('handleNewStructureArtistPremiumTrialRequest');
  340. $token = 'test-token';
  341. $data = [
  342. 'representativeEmail' => 'test@example.com',
  343. 'representativeFirstName' => 'John',
  344. 'representativeLastName' => 'Doe',
  345. 'structureName' => 'Test Structure',
  346. ];
  347. $shopRequest = $this->getMockBuilder(ShopRequest::class)->getMock();
  348. $shopRequest->method('getToken')->willReturn($token);
  349. $shopRequest->method('getData')->willReturn($data);
  350. $this->entityManager
  351. ->expects(self::once())
  352. ->method('find')
  353. ->with(ShopRequest::class, $token)
  354. ->willReturn($shopRequest);
  355. $trialRequest = $this->getMockBuilder(\App\ApiResources\Shop\NewStructureArtistPremiumTrialRequest::class)
  356. ->getMock();
  357. $this->serializer
  358. ->expects(self::once())
  359. ->method('deserialize')
  360. ->with(json_encode($data), NewStructureArtistPremiumTrialRequest::class, 'json')
  361. ->willReturn($trialRequest);
  362. $organization = $this->getMockBuilder(Organization::class)->getMock();
  363. $shopService
  364. ->expects(self::once())
  365. ->method('createOrganization')
  366. ->with($trialRequest)
  367. ->willReturn($organization);
  368. $shopService
  369. ->expects(self::once())
  370. ->method('startArtistPremiumTrial')
  371. ->with($organization, $trialRequest);
  372. $this->logger->expects(self::once())
  373. ->method('info')
  374. ->with('Successfully processed NewStructureArtistPremiumTrial for token: ' . $token);
  375. $shopService->handleNewStructureArtistPremiumTrialRequest($token);
  376. }
  377. /**
  378. * Test handleNewStructureArtistPremiumTrialRequest method with non-existent token
  379. */
  380. public function testHandleNewStructureArtistPremiumTrialRequestWithNonExistentToken(): void
  381. {
  382. $shopService = $this->getShopServiceMockFor('handleNewStructureArtistPremiumTrialRequest');
  383. $this->entityManager->expects(self::once())
  384. ->method('find')
  385. ->with(ShopRequest::class, 'non-existent-token')
  386. ->willReturn(null);
  387. $this->logger->expects(self::once())
  388. ->method('error')
  389. ->with('Cannot find ShopRequest with token: non-existent-token');
  390. $shopService->handleNewStructureArtistPremiumTrialRequest('non-existent-token');
  391. }
  392. /**
  393. * Test createOrganization method
  394. */
  395. public function testCreateOrganization(): void
  396. {
  397. $shopService = $this->getShopServiceMockFor('createOrganization');
  398. $trialRequest = $this
  399. ->getMockBuilder(NewStructureArtistPremiumTrialRequest::class)
  400. ->getMock();
  401. $trialRequest->method('getStructureName')->willReturn('Test Structure');
  402. $trialRequest->method('getAddress')->willReturn('123 Main St');
  403. $trialRequest->method('getAddressComplement')->willReturn('Suite 456');
  404. $trialRequest->method('getPostalCode')->willReturn('75000');
  405. $trialRequest->method('getCity')->willReturn('Paris');
  406. $trialRequest->method('getStructureEmail')->willReturn('structure@example.com');
  407. $trialRequest->method('getStructureType')->willReturn(PrincipalTypeEnum::ARTISTIC_EDUCATION_ONLY);
  408. $trialRequest->method('getLegalStatus')->willReturn(LegalEnum::ASSOCIATION_LAW_1901);
  409. $trialRequest->method('getSiren')->willReturn('123456789');
  410. $trialRequest->method('getRepresentativePhone')->willReturn('+33123456789');
  411. $shopService
  412. ->expects(self::once())
  413. ->method('generateSubdomain')
  414. ->with('Test Structure')
  415. ->willReturn('test-structure');
  416. $organization = $this->getMockBuilder(Organization::class)->getMock();
  417. // Mock the organizationFactory.create method to return the mock Organization
  418. $this->organizationFactory
  419. ->expects(self::once())
  420. ->method('create')
  421. ->with(self::callback(function ($organizationCreationRequest) {
  422. return $organizationCreationRequest->getName() === 'Test Structure'
  423. && $organizationCreationRequest->getStreetAddress1() === '123 Main St'
  424. && $organizationCreationRequest->getStreetAddress2() === 'Suite 456'
  425. && $organizationCreationRequest->getPostalCode() === '75000'
  426. && $organizationCreationRequest->getCity() === 'Paris'
  427. && $organizationCreationRequest->getEmail() === 'structure@example.com'
  428. && $organizationCreationRequest->getPrincipalType() === PrincipalTypeEnum::ARTISTIC_EDUCATION_ONLY
  429. && $organizationCreationRequest->getLegalStatus() === LegalEnum::ASSOCIATION_LAW_1901
  430. && $organizationCreationRequest->getSiretNumber() === '123456789'
  431. && $organizationCreationRequest->getPhoneNumber() === '+33123456789'
  432. && $organizationCreationRequest->getSubdomain() === 'test-structure'
  433. && $organizationCreationRequest->getProduct()->value === SettingsProductEnum::FREEMIUM->value
  434. && $organizationCreationRequest->getCreateWebsite() === false
  435. && $organizationCreationRequest->isClient() === false;
  436. }))
  437. ->willReturn($organization);
  438. $result = $shopService->createOrganization($trialRequest);
  439. $this->assertSame($organization, $result);
  440. }
  441. /**
  442. * Test generateSubdomain method
  443. */
  444. public function testGenerateSubdomain(): void
  445. {
  446. $shopService = $this->getShopServiceMockFor('generateSubdomain');
  447. // Test with a simple name
  448. $this->assertEquals('test-structure', $shopService->generateSubdomain('Test Structure'));
  449. // Test with accents and special characters
  450. $this->assertEquals('ecole-de-musique', $shopService->generateSubdomain('École de Musique'));
  451. // Test with multiple spaces and special characters
  452. $this->assertEquals('conservatoire-regional', $shopService->generateSubdomain('Conservatoire Régional!@#'));
  453. // Test with a very long name (should be truncated to 30 characters)
  454. $longName = 'This is a very long name that should be truncated';
  455. $this->assertEquals('this-is-a-very-long-name-that', $shopService->generateSubdomain($longName));
  456. // Test with leading and trailing hyphens (should be trimmed)
  457. $this->assertEquals('trimmed', $shopService->generateSubdomain('--Trimmed--'));
  458. // Test with consecutive special characters (should be replaced with a single hyphen)
  459. $this->assertEquals('multiple-hyphens', $shopService->generateSubdomain('Multiple!!!Hyphens'));
  460. }
  461. /**
  462. * Test validateNewStructureArtistPremiumTrialRequest method with valid data
  463. */
  464. public function testValidateNewStructureArtistPremiumTrialRequest(): void
  465. {
  466. $shopService = $this->getShopServiceMockFor('validateNewStructureArtistPremiumTrialRequest');
  467. $phoneNumberUtil = $this
  468. ->getMockBuilder(PhoneNumberUtil::class)
  469. ->disableOriginalConstructor()
  470. ->getMock();
  471. $shopService->phoneNumberUtil = $phoneNumberUtil;
  472. $request = new NewStructureArtistPremiumTrialRequest();
  473. $request->setStructureName('Test Structure');
  474. $request->setCity('Test City');
  475. $request->setPostalCode('12345');
  476. $request->setAddress('Test Address');
  477. $request->setAddressComplement('Test Address Complement');
  478. $request->setRepresentativePhone('+33123456789');
  479. $phoneNumberUtil->expects(self::once())
  480. ->method('isPossibleNumber')
  481. ->with('+33123456789')
  482. ->willReturn(true);
  483. $this->organizationFactory->expects(self::once())
  484. ->method('interruptIfOrganizationExists')
  485. ->with(self::callback(function ($organizationCreationRequest) {
  486. return $organizationCreationRequest->getName() === 'Test Structure'
  487. && $organizationCreationRequest->getCity() === 'Test City'
  488. && $organizationCreationRequest->getPostalCode() === '12345'
  489. && $organizationCreationRequest->getStreetAddress1() === 'Test Address'
  490. && $organizationCreationRequest->getStreetAddress2() === 'Test Address Complement'
  491. && $organizationCreationRequest->getStreetAddress3() === '';
  492. }));
  493. $shopService->validateNewStructureArtistPremiumTrialRequest($request);
  494. }
  495. /**
  496. * Test validateNewStructureArtistPremiumTrialRequest method with invalid phone number
  497. */
  498. public function testValidateNewStructureArtistPremiumTrialRequestWithInvalidPhoneNumber(): void
  499. {
  500. $shopService = $this->getShopServiceMockFor('validateNewStructureArtistPremiumTrialRequest');
  501. $phoneNumberUtil = $this->getMockBuilder(PhoneNumberUtil::class)
  502. ->disableOriginalConstructor()
  503. ->getMock();
  504. $shopService->phoneNumberUtil = $phoneNumberUtil;
  505. $request = new NewStructureArtistPremiumTrialRequest();
  506. $request->setRepresentativePhone('invalid-phone');
  507. // Mock the phoneNumberUtil to return false for isPossibleNumber
  508. $phoneNumberUtil->expects(self::once())
  509. ->method('isPossibleNumber')
  510. ->with('invalid-phone')
  511. ->willReturn(false);
  512. $this->expectException(\RuntimeException::class);
  513. $this->expectExceptionMessage('Invalid phone number');
  514. $shopService->validateNewStructureArtistPremiumTrialRequest($request);
  515. }
  516. }