diff --git a/app/Place/PlaceControllerProvider.php b/app/Place/PlaceControllerProvider.php index 15133367ca..39187b7770 100644 --- a/app/Place/PlaceControllerProvider.php +++ b/app/Place/PlaceControllerProvider.php @@ -10,6 +10,7 @@ use CultuurNet\UDB3\Http\Import\RemoveEmptyArraysRequestBodyParser; use CultuurNet\UDB3\Http\Place\ImportPlaceRequestHandler; use CultuurNet\UDB3\Http\Place\LegacyPlaceRequestBodyParser; +use CultuurNet\UDB3\Http\Place\UpdateAddressRequestHandler; use CultuurNet\UDB3\Http\Place\UpdateMajorInfoRequestHandler; use CultuurNet\UDB3\Http\Place\EditPlaceRestController; use CultuurNet\UDB3\Http\Request\Body\CombinedRequestBodyParser; @@ -31,7 +32,7 @@ public function connect(Application $app): ControllerCollection $controllers->post('/', ImportPlaceRequestHandler::class); $controllers->put('/{placeId}', ImportPlaceRequestHandler::class); - $controllers->put('/{cdbid}/address/{lang}/', 'place_editing_controller:updateAddress'); + $controllers->put('/{placeId}/address/{language}/', UpdateAddressRequestHandler::class); $controllers->put('/{cdbid}/booking-info/', 'place_editing_controller:updateBookingInfo'); $controllers->put('/{cdbid}/contact-point/', 'place_editing_controller:updateContactPoint'); $controllers->put('/{placeId}/major-info/', UpdateMajorInfoRequestHandler::class); @@ -51,7 +52,7 @@ public function connect(Application $app): ControllerCollection $controllers->get('/{cdbid}/events/', 'place_editing_controller:getEvents'); $controllers->post('/{itemId}/images/main/', 'place_editing_controller:selectMainImage'); $controllers->post('/{itemId}/images/{mediaObjectId}/', 'place_editing_controller:updateImage'); - $controllers->post('/{cdbid}/address/{lang}/', 'place_editing_controller:updateAddress'); + $controllers->post('/{placeId}/address/{language}/', UpdateAddressRequestHandler::class); $controllers->post('/{cdbid}/typical-age-range/', 'place_editing_controller:updateTypicalAgeRange'); $controllers->post('/{placeId}/major-info/', UpdateMajorInfoRequestHandler::class); $controllers->post('/{cdbid}/booking-info/', 'place_editing_controller:updateBookingInfo'); @@ -73,6 +74,12 @@ function (Application $app) { } ); + $app[UpdateAddressRequestHandler::class] = $app->share( + fn (Application $app) => new UpdateAddressRequestHandler( + $app['event_command_bus'] + ) + ); + $app[ImportPlaceRequestHandler::class] = $app->share( fn (Application $application) => new ImportPlaceRequestHandler( $app['place_repository'], diff --git a/app/Place/PlaceEditingServiceProvider.php b/app/Place/PlaceEditingServiceProvider.php index 46a6be2bc9..4e21e6ed85 100644 --- a/app/Place/PlaceEditingServiceProvider.php +++ b/app/Place/PlaceEditingServiceProvider.php @@ -5,8 +5,8 @@ namespace CultuurNet\UDB3\Silex\Place; use Broadway\UuidGenerator\Rfc4122\Version4Generator; +use CultuurNet\UDB3\Offer\DefaultOfferEditingService; use CultuurNet\UDB3\Place\Commands\PlaceCommandFactory; -use CultuurNet\UDB3\Place\DefaultPlaceEditingService; use CultuurNet\UDB3\Place\PlaceOrganizerRelationService; use CultuurNet\UDB3\Place\ReadModel\Relations\PlaceRelationsRepository; use Silex\Application; @@ -21,7 +21,7 @@ public function register(Application $app) { $app['place_editing_service'] = $app->share( function ($app) { - return new DefaultPlaceEditingService( + return new DefaultOfferEditingService( $app['event_command_bus'], new Version4Generator(), $app['place_jsonld_repository'], diff --git a/src/Http/Place/EditPlaceRestController.php b/src/Http/Place/EditPlaceRestController.php index b2833010b7..553bbd7ada 100644 --- a/src/Http/Place/EditPlaceRestController.php +++ b/src/Http/Place/EditPlaceRestController.php @@ -5,17 +5,10 @@ namespace CultuurNet\UDB3\Http\Place; use CultuurNet\UDB3\Event\ReadModel\Relations\EventRelationsRepository; -use CultuurNet\UDB3\Language; use CultuurNet\UDB3\Media\MediaManagerInterface; use CultuurNet\UDB3\Place\PlaceEditingServiceInterface; -use CultuurNet\UDB3\Http\Deserializer\Address\AddressJSONDeserializer; -use CultuurNet\UDB3\HttpFoundation\Response\NoContent; use CultuurNet\UDB3\Http\OfferRestBaseController; -use Symfony\Component\HttpFoundation\BinaryFileResponse; use Symfony\Component\HttpFoundation\JsonResponse; -use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; -use CultuurNet\UDB3\StringLiteral; class EditPlaceRestController extends OfferRestBaseController { @@ -26,11 +19,6 @@ class EditPlaceRestController extends OfferRestBaseController */ private $eventRelationsRepository; - /** - * @var AddressJSONDeserializer - */ - private $addressDeserializer; - /** * Constructs a RestController. * @@ -42,31 +30,6 @@ public function __construct( ) { parent::__construct($placeEditor, $mediaManager); $this->eventRelationsRepository = $eventRelationsRepository; - - - $this->addressDeserializer = new AddressJSONDeserializer(); - } - - public function placeContext(): BinaryFileResponse - { - $response = new BinaryFileResponse('/udb3/api/1.0/place.jsonld'); - $response->headers->set('Content-Type', 'application/ld+json'); - return $response; - } - - public function updateAddress(Request $request, string $cdbid, string $lang): Response - { - $address = $this->addressDeserializer->deserialize( - new StringLiteral($request->getContent()) - ); - - $this->editor->updateAddress( - $cdbid, - $address, - new Language($lang) - ); - - return new NoContent(); } public function getEvents(string $cdbid): JsonResponse diff --git a/src/Http/Place/UpdateAddressRequestHandler.php b/src/Http/Place/UpdateAddressRequestHandler.php new file mode 100644 index 0000000000..8fe430c34a --- /dev/null +++ b/src/Http/Place/UpdateAddressRequestHandler.php @@ -0,0 +1,43 @@ +commandBus = $commandBus; + } + + public function handle(ServerRequestInterface $request): ResponseInterface + { + $routeParameters = new RouteParameters($request); + $placeId = $routeParameters->getPlaceId(); + $language = $routeParameters->getLanguage(); + + $address = (new AddressJSONDeserializer())->deserialize( + new StringLiteral($request->getBody()->getContents()) + ); + + $this->commandBus->dispatch( + new UpdateAddress($placeId, $address, Language::fromUdb3ModelLanguage($language)) + ); + + return new NoContentResponse(); + } +} diff --git a/src/Place/DefaultPlaceEditingService.php b/src/Place/DefaultPlaceEditingService.php deleted file mode 100644 index 2435cadad4..0000000000 --- a/src/Place/DefaultPlaceEditingService.php +++ /dev/null @@ -1,22 +0,0 @@ -guardId($id); - - $this->commandBus->dispatch( - new UpdateAddress($id, $address, $language) - ); - } -} diff --git a/src/Place/PlaceEditingServiceInterface.php b/src/Place/PlaceEditingServiceInterface.php index 2b62260183..1e5ec84580 100644 --- a/src/Place/PlaceEditingServiceInterface.php +++ b/src/Place/PlaceEditingServiceInterface.php @@ -4,7 +4,6 @@ namespace CultuurNet\UDB3\Place; -use CultuurNet\UDB3\Address\Address; use CultuurNet\UDB3\ContactPoint; use CultuurNet\UDB3\Description; use CultuurNet\UDB3\Language; @@ -14,7 +13,6 @@ interface PlaceEditingServiceInterface { - public function updateAddress(string $id, Address $address, Language $language): void; public function updateDescription(string $id, Language $language, Description $description): void; public function updateTypicalAgeRange(string $id, AgeRange $ageRange): void; public function deleteTypicalAgeRange(string $id): void; diff --git a/src/Place/PlaceOrganizerRelationService.php b/src/Place/PlaceOrganizerRelationService.php index 9d9d6f022c..eadc1bc5ce 100644 --- a/src/Place/PlaceOrganizerRelationService.php +++ b/src/Place/PlaceOrganizerRelationService.php @@ -4,15 +4,13 @@ namespace CultuurNet\UDB3\Place; +use CultuurNet\UDB3\Offer\OfferEditingServiceInterface; use CultuurNet\UDB3\Organizer\OrganizerRelationServiceInterface; use CultuurNet\UDB3\Place\ReadModel\Relations\PlaceRelationsRepository; class PlaceOrganizerRelationService implements OrganizerRelationServiceInterface { - /** - * @var PlaceEditingServiceInterface - */ - private $editingService; + private OfferEditingServiceInterface $editingService; /** * @var PlaceRelationsRepository @@ -21,7 +19,7 @@ class PlaceOrganizerRelationService implements OrganizerRelationServiceInterface public function __construct( - PlaceEditingServiceInterface $editingService, + OfferEditingServiceInterface $editingService, PlaceRelationsRepository $relationsRepository ) { $this->editingService = $editingService; diff --git a/tests/Http/Place/EditPlaceRestControllerTest.php b/tests/Http/Place/EditPlaceRestControllerTest.php deleted file mode 100644 index 177bc4fcc9..0000000000 --- a/tests/Http/Place/EditPlaceRestControllerTest.php +++ /dev/null @@ -1,142 +0,0 @@ -placeEditingService = $this->createMock(PlaceEditingServiceInterface::class); - $this->relationsRepository = $this->createMock(EventRelationsRepository::class); - $this->mediaManager = $this->createMock(MediaManagerInterface::class); - $this->iriGenerator = $this->createMock(IriGeneratorInterface::class); - $this->consumerRepository = new InMemoryConsumerRepository(); - $this->shouldApprove = $this->createMock(ConsumerSpecification::class); - - $this->apiKey = new ApiKey('f5278146-3133-48b8-ace4-7e3f0a49328a'); - $this->consumer = $this->createMock(Consumer::class); - $this->consumerRepository->setConsumer($this->apiKey, $this->consumer); - - $this->shouldApprove->expects($this->any()) - ->method('satisfiedBy') - ->with($this->consumer) - ->willReturn(true); - - $this->placeRestController = new EditPlaceRestController( - $this->placeEditingService, - $this->relationsRepository, - $this->mediaManager - ); - - $this->iriGenerator - ->expects($this->any()) - ->method('iri') - ->willReturnCallback( - function ($placeId) { - return 'http://du.de/place/' . $placeId; - } - ); - } - - /** - * @test - */ - public function it_should_update_the_address_of_a_place_for_a_given_language() - { - $json = json_encode( - [ - 'streetAddress' => 'Eenmeilaan 35', - 'postalCode' => '3010', - 'addressLocality' => 'Kessel-Lo', - 'addressCountry' => 'BE', - ] - ); - - $request = new Request([], [], [], [], [], [], $json); - - $placeId = '6645274f-d969-4d70-865e-3ec799db9624'; - $lang = 'nl'; - - $this->placeEditingService->expects($this->once()) - ->method('updateAddress') - ->with( - $placeId, - new Address( - new Street('Eenmeilaan 35'), - new PostalCode('3010'), - new Locality('Kessel-Lo'), - new CountryCode('BE') - ), - new Language($lang) - ); - - $response = $this->placeRestController->updateAddress($request, $placeId, $lang); - - $this->assertEquals(204, $response->getStatusCode()); - } -} diff --git a/tests/Http/Place/UpdateAddressRequestHandlerTest.php b/tests/Http/Place/UpdateAddressRequestHandlerTest.php new file mode 100644 index 0000000000..409464cdd5 --- /dev/null +++ b/tests/Http/Place/UpdateAddressRequestHandlerTest.php @@ -0,0 +1,294 @@ +commandBus = new TraceableCommandBus(); + + $this->updateAddressRequestHandler = new UpdateAddressRequestHandler( + $this->commandBus + ); + + $this->psr7RequestBuilder = new Psr7RequestBuilder(); + + $this->commandBus->record(); + } + + /** + * @test + */ + public function it_handles_updating_the_address(): void + { + $updateAddressRequest = $this->psr7RequestBuilder + ->withRouteParameter('placeId', self::PLACE_ID) + ->withRouteParameter('language', 'nl') + ->withBodyFromString( + '{ + "streetAddress": "Veldstraat 11", + "postalCode": "9000", + "addressLocality": "Gent", + "addressCountry": "BE" + }' + ) + ->build('PUT'); + + $response = $this->updateAddressRequestHandler->handle($updateAddressRequest); + + $this->assertEquals( + [ + new UpdateAddress( + self::PLACE_ID, + new Address( + new Street('Veldstraat 11'), + new PostalCode('9000'), + new Locality('Gent'), + new CountryCode('BE') + ), + new Language('nl') + ), + ], + $this->commandBus->getRecordedCommands() + ); + + $this->assertJsonResponse( + new NoContentResponse(), + $response + ); + } + + /** + * @test + */ + public function it_handles_changing_the_address(): void + { + $updateAddressRequest = $this->psr7RequestBuilder + ->withRouteParameter('placeId', self::PLACE_ID) + ->withRouteParameter('language', 'nl') + ->withBodyFromString( + '{ + "streetAddress": "Veldstraat 11", + "postalCode": "9000", + "addressLocality": "Gent", + "addressCountry": "BE" + }' + ) + ->build('PUT'); + + $updateAddressRequest2 = $this->psr7RequestBuilder + ->withRouteParameter('placeId', self::PLACE_ID) + ->withRouteParameter('language', 'nl') + ->withBodyFromString( + '{ + "streetAddress": "Meir 12", + "postalCode": "2000", + "addressLocality": "Antwerpen", + "addressCountry": "BE" + }' + ) + ->build('PUT'); + + $this->updateAddressRequestHandler->handle($updateAddressRequest); + $this->updateAddressRequestHandler->handle($updateAddressRequest2); + + $this->assertEquals( + [ + new UpdateAddress( + self::PLACE_ID, + new Address( + new Street('Veldstraat 11'), + new PostalCode('9000'), + new Locality('Gent'), + new CountryCode('BE') + ), + new Language('nl') + ), + new UpdateAddress( + self::PLACE_ID, + new Address( + new Street('Meir 12'), + new PostalCode('2000'), + new Locality('Antwerpen'), + new CountryCode('BE') + ), + new Language('nl') + ), + ], + $this->commandBus->getRecordedCommands() + ); + } + + /** + * @test + */ + public function it_supports_multiple_languages(): void + { + $updateAddressRequestInDutch = $this->psr7RequestBuilder + ->withRouteParameter('placeId', self::PLACE_ID) + ->withRouteParameter('language', 'nl') + ->withBodyFromString( + '{ + "streetAddress": "Veldstraat 11", + "postalCode": "9000", + "addressLocality": "Gent", + "addressCountry": "BE" + }' + ) + ->build('PUT'); + + $updateAddressRequestInFrench = $this->psr7RequestBuilder + ->withRouteParameter('placeId', self::PLACE_ID) + ->withRouteParameter('language', 'fr') + ->withBodyFromString( + '{ + "streetAddress": "Rue du champ 11", + "postalCode": "9000", + "addressLocality": "Gand", + "addressCountry": "BE" + }' + ) + ->build('PUT'); + + $this->updateAddressRequestHandler->handle($updateAddressRequestInDutch); + $this->updateAddressRequestHandler->handle($updateAddressRequestInFrench); + + $this->assertEquals( + [ + new UpdateAddress( + self::PLACE_ID, + new Address( + new Street('Veldstraat 11'), + new PostalCode('9000'), + new Locality('Gent'), + new CountryCode('BE') + ), + new Language('nl') + ), + new UpdateAddress( + self::PLACE_ID, + new Address( + new Street('Rue du champ 11'), + new PostalCode('9000'), + new Locality('Gand'), + new CountryCode('BE') + ), + new Language('fr') + ), + ], + $this->commandBus->getRecordedCommands() + ); + } + + /** + * @test + */ + public function it_throws_on_invalid_country(): void + { + $updateAddressRequest = $this->psr7RequestBuilder + ->withRouteParameter('placeId', self::PLACE_ID) + ->withRouteParameter('language', 'nl') + ->withBodyFromString( + '{ + "streetAddress": "Veldstraat 11", + "postalCode": "9000", + "addressLocality": "Gent", + "addressCountry": "BEL" + }' + ) + ->build('PUT'); + + $this->expectException(InvalidArgumentException::class); + + $this->updateAddressRequestHandler->handle($updateAddressRequest); + } + + /** + * @test + * @dataProvider emptyValueDataProvider + */ + public function it_throws_on_empty_values(array $emptyValueAddress): void + { + $updateAddressRequest = $this->psr7RequestBuilder + ->withRouteParameter('placeId', self::PLACE_ID) + ->withRouteParameter('language', 'nl') + ->withBodyFromString( + Json::encode($emptyValueAddress) + ) + ->build('PUT'); + + $this->expectException(DataValidationException::class); + + $this->updateAddressRequestHandler->handle($updateAddressRequest); + } + + + public function emptyValueDataProvider(): array + { + return [ + [ + [ + 'streetAddress' => '', + 'postalCode' => '9000', + 'addressLocality' => 'Gent', + 'addressCountry' => 'BE', + ], + ], + [ + [ + 'streetAddress' => 'Veldstraat 11', + 'postalCode' => '', + 'addressLocality' => 'Gent', + 'addressCountry' => 'BE', + ], + ], + [ + [ + 'streetAddress' => 'Veldstraat 11', + 'postalCode' => '9000', + 'addressLocality' => '', + 'addressCountry' => 'BE', + ], + ], + [ + [ + 'streetAddress' => 'Veldstraat 11', + 'postalCode' => '9000', + 'addressLocality' => 'Gent', + 'addressCountry' => '', + ], + ], + ]; + } +} diff --git a/tests/Place/DefaultPlaceEditingServiceTest.php b/tests/Place/DefaultPlaceEditingServiceTest.php deleted file mode 100644 index e58b2e5611..0000000000 --- a/tests/Place/DefaultPlaceEditingServiceTest.php +++ /dev/null @@ -1,102 +0,0 @@ -commandBus = $this->createMock(CommandBus::class); - - $this->uuidGenerator = $this->createMock( - UuidGeneratorInterface::class - ); - - $this->commandFactory = $this->createMock(OfferCommandFactoryInterface::class); - - $this->readRepository = $this->createMock(DocumentRepository::class); - - $organizerDocumentRepository = $this->createMock(DocumentRepository::class); - - $this->eventStore = new TraceableEventStore( - new InMemoryEventStore() - ); - - $this->readRepository->expects($this->any()) - ->method('fetch') - ->with('ad93103d-1395-4af7-a52a-2829d466c232') - ->willReturn(new JsonDocument('ad93103d-1395-4af7-a52a-2829d466c232')); - - $this->placeEditingService = new DefaultPlaceEditingService( - $this->commandBus, - $this->uuidGenerator, - $this->readRepository, - $organizerDocumentRepository, - $this->commandFactory - ); - } - - /** - * @test - */ - public function it_should_update_the_address_of_a_place_by_dispatching_a_relevant_command(): void - { - $id = 'ad93103d-1395-4af7-a52a-2829d466c232'; - $address = new Address( - new Street('Eenmeilaan 35'), - new PostalCode('3010'), - new Locality('Kessel-Lo'), - new CountryCode('BE') - ); - $language = new Language('nl'); - - $this->commandBus->expects($this->once()) - ->method('dispatch') - ->with(new UpdateAddress($id, $address, $language)); - - $this->placeEditingService->updateAddress($id, $address, $language); - } -} diff --git a/tests/Place/PlaceOrganizerRelationServiceTest.php b/tests/Place/PlaceOrganizerRelationServiceTest.php index a938585fc0..4b071c9d8a 100644 --- a/tests/Place/PlaceOrganizerRelationServiceTest.php +++ b/tests/Place/PlaceOrganizerRelationServiceTest.php @@ -4,6 +4,8 @@ namespace CultuurNet\UDB3\Place; +use CultuurNet\UDB3\Offer\DefaultOfferEditingService; +use CultuurNet\UDB3\Offer\OfferEditingServiceInterface; use CultuurNet\UDB3\Place\ReadModel\Relations\PlaceRelationsRepository; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; @@ -11,7 +13,7 @@ class PlaceOrganizerRelationServiceTest extends TestCase { /** - * @var PlaceEditingServiceInterface|MockObject + * @var OfferEditingServiceInterface|MockObject */ private $editService; @@ -27,7 +29,7 @@ class PlaceOrganizerRelationServiceTest extends TestCase public function setUp() { - $this->editService = $this->createMock(PlaceEditingServiceInterface::class); + $this->editService = $this->createMock(DefaultOfferEditingService::class); $this->relationRepository = $this->createMock(PlaceRelationsRepository::class); $this->organizerRelationService = new PlaceOrganizerRelationService(