diff --git a/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/Country.xml b/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/Country.xml index 10882ec6aa..0c7bf30130 100644 --- a/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/Country.xml +++ b/src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/Country.xml @@ -41,6 +41,9 @@ admin:country:create + + admin:country:read + @@ -66,6 +69,9 @@ admin:country:update + + admin:country:read + diff --git a/src/Sylius/Bundle/ApiBundle/Resources/config/serialization/Country.xml b/src/Sylius/Bundle/ApiBundle/Resources/config/serialization/Country.xml index 6cadf331e3..e15ef10b3c 100644 --- a/src/Sylius/Bundle/ApiBundle/Resources/config/serialization/Country.xml +++ b/src/Sylius/Bundle/ApiBundle/Resources/config/serialization/Country.xml @@ -16,9 +16,6 @@ xsi:schemaLocation="http://symfony.com/schema/dic/serializer-mapping https://symfony.com/schema/dic/serializer-mapping/serializer-mapping-1.0.xsd" > - - admin:country:read - admin:country:read admin:country:create diff --git a/tests/Api/Admin/CountriesTest.php b/tests/Api/Admin/CountriesTest.php new file mode 100644 index 0000000000..04a2785dab --- /dev/null +++ b/tests/Api/Admin/CountriesTest.php @@ -0,0 +1,136 @@ +loadFixturesFromFiles(['authentication/api_administrator.yaml', 'country.yaml']); + $header = $this->getLoggedHeader(); + + /** @var CountryInterface $country */ + $country = $fixtures['country_DE']; + + $this->client->request( + 'GET', + sprintf('/api/v2/admin/countries/%s', $country->getCode()), + [], + [], + $header, + ); + + $this->assertResponse( + $this->client->getResponse(), + 'admin/country/get_country_response', + Response::HTTP_OK, + ); + } + + /** @test */ + public function it_gets_countries(): void + { + $this->loadFixturesFromFiles(['authentication/api_administrator.yaml', 'country.yaml']); + $header = $this->getLoggedHeader(); + + $this->client->request( + 'GET', + '/api/v2/admin/countries', + [], + [], + $header, + ); + + $this->assertResponse( + $this->client->getResponse(), + 'admin/country/get_countries_response', + Response::HTTP_OK, + ); + } + + /** @test */ + public function it_creates_a_country(): void + { + $this->loadFixturesFromFiles(['authentication/api_administrator.yaml']); + $header = $this->getLoggedHeader(); + + $this->client->request( + 'POST', + '/api/v2/admin/countries', + [], + [], + $header, + json_encode([ + 'code' => 'IE', + 'enabled' => true, + ], JSON_THROW_ON_ERROR), + ); + + $this->assertResponse( + $this->client->getResponse(), + 'admin/country/post_country_response', + Response::HTTP_CREATED, + ); + } + + /** @test */ + public function it_updates_an_existing_country(): void + { + $fixtures = $this->loadFixturesFromFiles(['authentication/api_administrator.yaml', 'country.yaml']); + + /** @var CountryInterface $country */ + $country = $fixtures['country_US']; + + $header = $this->getLoggedHeader(); + + $this->client->request( + 'PUT', + '/api/v2/admin/countries/' . $country->getCode(), + [], + [], + $header, + json_encode([ + 'enabled' => false, + 'provinces' => [[ + 'code' => 'US-WA', + 'name' => 'Washington', + 'country' => $country->getCode(), + ]] + ], JSON_THROW_ON_ERROR), + ); + + $this->assertResponse( + $this->client->getResponse(), + 'admin/country/put_country_response', + Response::HTTP_OK, + ); + } + + private function getLoggedHeader(): array + { + $token = $this->logInAdminUser('api@example.com'); + $authorizationHeader = self::$kernel->getContainer()->getParameter('sylius.api.authorization_header'); + $header['HTTP_' . $authorizationHeader] = 'Bearer ' . $token; + + return array_merge($header, self::CONTENT_TYPE_HEADER); + } +} diff --git a/tests/Api/DataFixtures/ORM/country.yaml b/tests/Api/DataFixtures/ORM/country.yaml index 989a1c4acc..91f59e4464 100644 --- a/tests/Api/DataFixtures/ORM/country.yaml +++ b/tests/Api/DataFixtures/ORM/country.yaml @@ -5,3 +5,13 @@ Sylius\Component\Addressing\Model\Country: code: 'FR' country_DE: code: 'DE' + +Sylius\Component\Addressing\Model\Province: + province_US_WY: + code: US-WY + name: Wyoming + country: "@country_US" + province_US_MI: + code: US-MI + name: Minnesota + country: "@country_US" diff --git a/tests/Api/Responses/Expected/admin/country/get_countries_response.json b/tests/Api/Responses/Expected/admin/country/get_countries_response.json new file mode 100644 index 0000000000..c0d5fbadda --- /dev/null +++ b/tests/Api/Responses/Expected/admin/country/get_countries_response.json @@ -0,0 +1,35 @@ +{ + "@context": "\/api\/v2\/contexts\/Country", + "@id": "\/api\/v2\/admin\/countries", + "@type": "hydra:Collection", + "hydra:member": [ + { + "@id": "\/api\/v2\/admin\/countries\/US", + "@type": "Country", + "code": "US", + "name": "United States", + "enabled": true, + "provinces": [ + "\/api\/v2\/admin\/provinces\/US-MI", + "\/api\/v2\/admin\/provinces\/US-WY" + ] + }, + { + "@id": "\/api\/v2\/admin\/countries\/FR", + "@type": "Country", + "code": "FR", + "name": "France", + "enabled": true, + "provinces": [] + }, + { + "@id": "\/api\/v2\/admin\/countries\/DE", + "@type": "Country", + "code": "DE", + "name": "Germany", + "enabled": true, + "provinces": [] + } + ], + "hydra:totalItems": 3 +} diff --git a/tests/Api/Responses/Expected/admin/country/get_country_response.json b/tests/Api/Responses/Expected/admin/country/get_country_response.json new file mode 100644 index 0000000000..4f2318cd20 --- /dev/null +++ b/tests/Api/Responses/Expected/admin/country/get_country_response.json @@ -0,0 +1,9 @@ +{ + "@context": "\/api\/v2\/contexts\/Country", + "@id": "\/api\/v2\/admin\/countries\/DE", + "@type": "Country", + "code": "DE", + "enabled": true, + "name": "Germany", + "provinces": [] +} diff --git a/tests/Api/Responses/Expected/admin/country/post_country_response.json b/tests/Api/Responses/Expected/admin/country/post_country_response.json new file mode 100644 index 0000000000..d2877da7c5 --- /dev/null +++ b/tests/Api/Responses/Expected/admin/country/post_country_response.json @@ -0,0 +1,9 @@ +{ + "@context": "\/api\/v2\/contexts\/Country", + "@id": "\/api\/v2\/admin\/countries\/IE", + "@type": "Country", + "code": "IE", + "enabled": true, + "name": "Ireland", + "provinces": [] +} diff --git a/tests/Api/Responses/Expected/admin/country/put_country_response.json b/tests/Api/Responses/Expected/admin/country/put_country_response.json new file mode 100644 index 0000000000..5ec999bcd6 --- /dev/null +++ b/tests/Api/Responses/Expected/admin/country/put_country_response.json @@ -0,0 +1,11 @@ +{ + "@context": "\/api\/v2\/contexts\/Country", + "@id": "\/api\/v2\/admin\/countries\/US", + "@type": "Country", + "code": "US", + "enabled": false, + "name": "United States", + "provinces": [ + "\/api\/v2\/admin\/provinces\/US-WA" + ] +} diff --git a/tests/Api/Responses/Expected/shop/address/create_address_with_province_code_response.json b/tests/Api/Responses/Expected/shop/address/create_address_with_province_code_response.json new file mode 100644 index 0000000000..0f583883dd --- /dev/null +++ b/tests/Api/Responses/Expected/shop/address/create_address_with_province_code_response.json @@ -0,0 +1,16 @@ +{ + "@context": "\/api\/v2\/contexts\/Address", + "@id": "\/api\/v2\/shop\/addresses\/@integer@", + "@type": "Address", + "id": "@integer@", + "firstName":"TEST", + "lastName":"TEST", + "phoneNumber":"666111333", + "company":"Potato Corp.", + "countryCode":"US", + "provinceCode":"US-MI", + "provinceName":null, + "street":"Top secret", + "city":"Nebraska", + "postcode":"12343" +} diff --git a/tests/Api/Responses/Expected/shop/address/create_address_with_province_name_response.json b/tests/Api/Responses/Expected/shop/address/create_address_with_province_name_response.json new file mode 100644 index 0000000000..d8db771595 --- /dev/null +++ b/tests/Api/Responses/Expected/shop/address/create_address_with_province_name_response.json @@ -0,0 +1,16 @@ +{ + "@context": "\/api\/v2\/contexts\/Address", + "@id": "\/api\/v2\/shop\/addresses\/@integer@", + "@type": "Address", + "id": "@integer@", + "firstName":"TEST", + "lastName":"TEST", + "phoneNumber":"666111333", + "company":"Potato Corp.", + "countryCode":"DE", + "provinceCode":null, + "provinceName":"Munich", + "street":"Top secret", + "city":"Nebraska", + "postcode":"12343" +} diff --git a/tests/Api/Responses/Expected/shop/create_address_response.json b/tests/Api/Responses/Expected/shop/address/create_address_without_province_response.json similarity index 94% rename from tests/Api/Responses/Expected/shop/create_address_response.json rename to tests/Api/Responses/Expected/shop/address/create_address_without_province_response.json index 53af1fd623..ec06ec02e9 100644 --- a/tests/Api/Responses/Expected/shop/create_address_response.json +++ b/tests/Api/Responses/Expected/shop/address/create_address_without_province_response.json @@ -7,7 +7,7 @@ "lastName":"TEST", "phoneNumber":"666111333", "company":"Potato Corp.", - "countryCode":"US", + "countryCode":"DE", "provinceCode":null, "provinceName":null, "street":"Top secret", diff --git a/tests/Api/Responses/Expected/shop/get_addresses_response.json b/tests/Api/Responses/Expected/shop/address/get_addresses_response.json similarity index 100% rename from tests/Api/Responses/Expected/shop/get_addresses_response.json rename to tests/Api/Responses/Expected/shop/address/get_addresses_response.json diff --git a/tests/Api/Responses/Expected/shop/get_an_address_response.json b/tests/Api/Responses/Expected/shop/address/get_an_address_response.json similarity index 100% rename from tests/Api/Responses/Expected/shop/get_an_address_response.json rename to tests/Api/Responses/Expected/shop/address/get_an_address_response.json diff --git a/tests/Api/Responses/Expected/shop/get_countries_response.json b/tests/Api/Responses/Expected/shop/get_countries_response.json index bd4563a6e2..30a07e4159 100644 --- a/tests/Api/Responses/Expected/shop/get_countries_response.json +++ b/tests/Api/Responses/Expected/shop/get_countries_response.json @@ -8,7 +8,20 @@ "@type": "Country", "code": "US", "name": "United States", - "provinces": [] + "provinces": [ + { + "@id": "\/api\/v2\/admin\/provinces\/US-MI", + "@type": "Province", + "code": "US-MI", + "name": "Minnesota" + }, + { + "@id": "\/api\/v2\/admin\/provinces\/US-WY", + "@type": "Province", + "code": "US-WY", + "name": "Wyoming" + } + ] }, { "@id": "\/api\/v2\/shop\/countries\/FR", diff --git a/tests/Api/Shop/AddressesGetTest.php b/tests/Api/Shop/AddressesGetTest.php index a92b2d2da9..415125a737 100644 --- a/tests/Api/Shop/AddressesGetTest.php +++ b/tests/Api/Shop/AddressesGetTest.php @@ -48,7 +48,7 @@ final class AddressesGetTest extends JsonApiTestCase array_merge($authorizationHeader, self::CONTENT_TYPE_HEADER) ); - $this->assertResponse($this->client->getResponse(), 'shop/get_addresses_response'); + $this->assertResponse($this->client->getResponse(), 'shop/address/get_addresses_response'); } /** @test */ @@ -70,6 +70,6 @@ final class AddressesGetTest extends JsonApiTestCase array_merge($authorizationHeader, self::CONTENT_TYPE_HEADER) ); - $this->assertResponse($this->client->getResponse(), 'shop/get_an_address_response'); + $this->assertResponse($this->client->getResponse(), 'shop/address/get_an_address_response'); } } diff --git a/tests/Api/Shop/AddressesPostTest.php b/tests/Api/Shop/AddressesPostTest.php index 61cf147a62..5cbc6180b7 100644 --- a/tests/Api/Shop/AddressesPostTest.php +++ b/tests/Api/Shop/AddressesPostTest.php @@ -14,6 +14,7 @@ declare(strict_types=1); namespace Sylius\Tests\Api\Shop; use Sylius\Component\Addressing\Model\CountryInterface; +use Sylius\Component\Addressing\Model\ProvinceInterface; use Sylius\Component\Core\Model\CustomerInterface; use Sylius\Tests\Api\JsonApiTestCase; use Symfony\Component\HttpFoundation\Response; @@ -25,7 +26,7 @@ final class AddressesPostTest extends JsonApiTestCase { $fixtures = $this->loadFixturesFromFiles(['authentication/customer.yaml', 'country.yaml']); /** @var CountryInterface $country */ - $country = $fixtures['country_US']; + $country = $fixtures['country_DE']; $bodyRequest = $this->createBodyRequest($country->getCode()); @@ -43,13 +44,69 @@ final class AddressesPostTest extends JsonApiTestCase } /** @test */ - public function it_creates_new_address_for_logged_customer(): void + public function it_creates_new_address_for_logged_customer_with_country_with_provinces(): void { $fixtures = $this->loadFixturesFromFiles(['authentication/customer.yaml', 'country.yaml']); /** @var CustomerInterface $customer */ $customer = $fixtures['customer_oliver']; /** @var CountryInterface $country */ $country = $fixtures['country_US']; + /** @var ProvinceInterface $province */ + $province = $fixtures['province_US_MI']; + + $authorizationHeader = $this->getAuthorizationHeaderAsCustomer($customer->getEmailCanonical(), 'sylius'); + + $bodyRequest = $this->createBodyRequest($country->getCode(), $province->getCode()); + + $this->client->request( + 'POST', + '/api/v2/shop/addresses', + [], + [], + array_merge($authorizationHeader, self::CONTENT_TYPE_HEADER), + json_encode($bodyRequest) + ); + + $response = $this->client->getResponse(); + + $this->assertResponse($response, 'shop/address/create_address_with_province_code_response', Response::HTTP_CREATED); + } + + /** @test */ + public function it_creates_new_address_for_logged_customer_without_province(): void + { + $fixtures = $this->loadFixturesFromFiles(['authentication/customer.yaml', 'country.yaml']); + /** @var CustomerInterface $customer */ + $customer = $fixtures['customer_oliver']; + /** @var CountryInterface $country */ + $country = $fixtures['country_DE']; + + $authorizationHeader = $this->getAuthorizationHeaderAsCustomer($customer->getEmailCanonical(), 'sylius'); + + $bodyRequest = $this->createBodyRequest($country->getCode(), provinceName: 'Munich'); + + $this->client->request( + 'POST', + '/api/v2/shop/addresses', + [], + [], + array_merge($authorizationHeader, self::CONTENT_TYPE_HEADER), + json_encode($bodyRequest) + ); + + $response = $this->client->getResponse(); + + $this->assertResponse($response, 'shop/address/create_address_with_province_name_response', Response::HTTP_CREATED); + } + + /** @test */ + public function it_creates_new_address_for_logged_customer_with_country_with_custom_provinces(): void + { + $fixtures = $this->loadFixturesFromFiles(['authentication/customer.yaml', 'country.yaml']); + /** @var CustomerInterface $customer */ + $customer = $fixtures['customer_oliver']; + /** @var CountryInterface $country */ + $country = $fixtures['country_DE']; $authorizationHeader = $this->getAuthorizationHeaderAsCustomer($customer->getEmailCanonical(), 'sylius'); @@ -66,22 +123,25 @@ final class AddressesPostTest extends JsonApiTestCase $response = $this->client->getResponse(); - $this->assertResponse($response, 'shop/create_address_response', Response::HTTP_CREATED); + $this->assertResponse($response, 'shop/address/create_address_without_province_response', Response::HTTP_CREATED); } - private function createBodyRequest(string $countryCode): array - { + private function createBodyRequest( + string $countryCode, + ?string $provinceCode = null, + ?string $provinceName = null + ): array { return [ - 'firstName'=> 'TEST', - 'lastName'=> 'TEST', - 'phoneNumber'=> '666111333', - 'company'=> 'Potato Corp.', - 'countryCode'=> $countryCode, - 'provinceCode'=> null, - 'provinceName'=> null, - 'street'=> 'Top secret', - 'city'=> 'Nebraska', - 'postcode'=> '12343' + 'firstName' => 'TEST', + 'lastName' => 'TEST', + 'phoneNumber' => '666111333', + 'company' => 'Potato Corp.', + 'countryCode' => $countryCode, + 'provinceCode' => $provinceCode, + 'provinceName' => $provinceName, + 'street' => 'Top secret', + 'city' => 'Nebraska', + 'postcode' => '12343', ]; } }