├── .editorconfig ├── .github └── CODEOWNERS ├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── README.md ├── UPGRADE.md ├── bin └── .gitkeep ├── composer.json ├── doc └── swagger.yml ├── easy-coding-standard.yml ├── phpspec.yml.dist ├── phpstan.neon ├── phpunit.xml.dist ├── spec ├── Checker │ ├── ChannelExistenceCheckerSpec.php │ └── PromotionCouponEligibilityCheckerSpec.php ├── Command │ ├── AddressBook │ │ ├── CreateAddressSpec.php │ │ ├── RemoveAddressSpec.php │ │ ├── SetDefaultAddressSpec.php │ │ └── UpdateAddressSpec.php │ ├── Cart │ │ ├── AddCouponSpec.php │ │ ├── AddressOrderSpec.php │ │ ├── ChangeItemQuantitySpec.php │ │ ├── ChoosePaymentMethodSpec.php │ │ ├── ChooseShippingMethodSpec.php │ │ ├── CompleteOrderSpec.php │ │ ├── DropCartSpec.php │ │ ├── PickupCartSpec.php │ │ ├── PutOptionBasedConfigurableItemToCartSpec.php │ │ ├── PutSimpleItemToCartSpec.php │ │ └── PutVariantBasedConfigurableItemToCartSpec.php │ ├── Customer │ │ ├── GenerateResetPasswordTokenSpec.php │ │ ├── GenerateVerificationTokenSpec.php │ │ ├── SendResetPasswordTokenSpec.php │ │ ├── SendVerificationTokenSpec.php │ │ ├── UpdateCustomerSpec.php │ │ └── VerifyAccountSpec.php │ └── Product │ │ ├── AddProductReviewByCodeSpec.php │ │ └── AddProductReviewBySlugSpec.php ├── EventListener │ ├── RequestLocaleSetterSpec.php │ └── UserRegistrationListenerSpec.php ├── Factory │ ├── AddressBook │ │ ├── AddressBookViewFactorySpec.php │ │ └── AddressViewFactorySpec.php │ ├── Cart │ │ ├── AdjustmentViewFactorySpec.php │ │ ├── CartItemViewFactorySpec.php │ │ ├── CartViewFactorySpec.php │ │ └── TotalViewFactorySpec.php │ ├── Checkout │ │ ├── PaymentMethodViewFactorySpec.php │ │ ├── PaymentViewFactorySpec.php │ │ ├── ShipmentViewFactorySpec.php │ │ └── ShippingMethodViewFactorySpec.php │ ├── Customer │ │ └── CustomerViewFactorySpec.php │ ├── Order │ │ └── PlacedOrderViewFactorySpec.php │ ├── PriceViewFactorySpec.php │ ├── Product │ │ ├── DetailedProductViewFactorySpec.php │ │ ├── LimitedProductAttributeValuesViewFactorySpec.php │ │ ├── ListProductViewFactorySpec.php │ │ ├── ProductAttributeValueViewFactorySpec.php │ │ ├── ProductReviewViewFactorySpec.php │ │ ├── ProductVariantViewFactorySpec.php │ │ └── ProductViewFactorySpec.php │ └── Taxon │ │ ├── ImageViewFactorySpec.php │ │ ├── TaxonDetailsViewFactorySpec.php │ │ └── TaxonViewFactorySpec.php ├── Generator │ └── ProductBreadcrumbGeneratorSpec.php ├── Handler │ ├── AddressBook │ │ ├── CreateAddressHandlerSpec.php │ │ ├── RemoveAddressHandlerSpec.php │ │ ├── SetDefaultAddressHandlerSpec.php │ │ └── UpdateAddressBookAddressHandlerSpec.php │ ├── Cart │ │ ├── AddCouponHandlerSpec.php │ │ ├── AddressOrderHandlerSpec.php │ │ ├── ChangeItemQuantityHandlerSpec.php │ │ ├── ChoosePaymentMethodHandlerSpec.php │ │ ├── ChooseShippingMethodHandlerSpec.php │ │ ├── CompleteOrderHandlerSpec.php │ │ ├── DropCartHandlerSpec.php │ │ ├── PickupCartHandlerSpec.php │ │ ├── PutOptionBasedConfigurableItemToCartHandlerSpec.php │ │ ├── PutSimpleItemToCartHandlerSpec.php │ │ └── PutVariantBasedConfigurableItemToCartHandlerSpec.php │ ├── Customer │ │ ├── GenerateResetPasswordTokenHandlerSpec.php │ │ ├── GenerateVerificationTokenHandlerSpec.php │ │ ├── SendResetPasswordTokenHandlerSpec.php │ │ ├── SendVerificationTokenHandlerSpec.php │ │ ├── UpdateCustomerHandlerSpec.php │ │ └── VerifyAccountHandlerSpec.php │ └── Product │ │ ├── AddProductReviewByCodeHandlerSpec.php │ │ └── AddProductReviewBySlugHandlerSpec.php ├── Http │ ├── RequestBasedLocaleProviderSpec.php │ └── RequestChannelEnsurerSpec.php ├── Mapper │ └── AddressMapperSpec.php ├── Model │ └── AddressSpec.php ├── Modifier │ └── OrderModifierSpec.php ├── Normalizer │ └── RequestCartTokenNormalizerSpec.php ├── Provider │ ├── LoggedInShopUserProviderSpec.php │ ├── ProductReviewerProviderSpec.php │ ├── ShopUserAwareCustomerProviderSpec.php │ └── SupportedLocaleProviderSpec.php ├── Shipping │ └── ShippingCostEstimatorSpec.php ├── Validator │ ├── Address │ │ ├── AddressExistsValidatorSpec.php │ │ └── CountryExistsValidatorSpec.php │ ├── Cart │ │ ├── CartExistsValidatorSpec.php │ │ ├── CartItemExistsValidatorSpec.php │ │ ├── TokenIsNotUsedValidatorSpec.php │ │ └── ValidPromotionCouponCodeValidatorSpec.php │ ├── ChannelExistsValidatorSpec.php │ ├── Customer │ │ ├── ShopUserDoesNotExistValidatorSpec.php │ │ └── ShopUserExistsValidatorSpec.php │ └── Product │ │ ├── ConfigurableProductValidatorSpec.php │ │ ├── ProductExistsValidatorSpec.php │ │ ├── ProductVariantExistsValidatorSpec.php │ │ └── SimpleProductValidatorSpec.php └── ViewRepository │ ├── Cart │ └── CartViewRepositorySpec.php │ ├── Order │ └── PlacedOrderViewRepositorySpec.php │ └── Product │ └── ProductDetailsViewRepositorySpec.php ├── src ├── Checker │ ├── ChannelExistenceChecker.php │ ├── ChannelExistenceCheckerInterface.php │ └── PromotionCouponEligibilityChecker.php ├── Command │ ├── AddressBook │ │ ├── CreateAddress.php │ │ ├── RemoveAddress.php │ │ ├── SetDefaultAddress.php │ │ └── UpdateAddress.php │ ├── Cart │ │ ├── AddCoupon.php │ │ ├── AddressOrder.php │ │ ├── ChangeItemQuantity.php │ │ ├── ChoosePaymentMethod.php │ │ ├── ChooseShippingMethod.php │ │ ├── CompleteOrder.php │ │ ├── DropCart.php │ │ ├── PickupCart.php │ │ ├── PutOptionBasedConfigurableItemToCart.php │ │ ├── PutSimpleItemToCart.php │ │ ├── PutVariantBasedConfigurableItemToCart.php │ │ ├── RemoveCoupon.php │ │ └── RemoveItemFromCart.php │ ├── Customer │ │ ├── GenerateResetPasswordToken.php │ │ ├── GenerateVerificationToken.php │ │ ├── RegisterCustomer.php │ │ ├── SendResetPasswordToken.php │ │ ├── SendVerificationToken.php │ │ ├── UpdateCustomer.php │ │ └── VerifyAccount.php │ └── Product │ │ ├── AddProductReviewByCode.php │ │ └── AddProductReviewBySlug.php ├── Controller │ ├── AddressBook │ │ ├── CreateAddressAction.php │ │ ├── RemoveAddressAction.php │ │ ├── SetDefaultAddressAction.php │ │ ├── ShowAddressBookAction.php │ │ └── UpdateAddressAction.php │ ├── Cart │ │ ├── AddCouponAction.php │ │ ├── ChangeItemQuantityAction.php │ │ ├── DropCartAction.php │ │ ├── EstimateShippingCostAction.php │ │ ├── PickupCartAction.php │ │ ├── PutItemToCartAction.php │ │ ├── PutItemsToCartAction.php │ │ ├── RemoveCouponAction.php │ │ ├── RemoveItemFromCartAction.php │ │ └── SummarizeAction.php │ ├── Checkout │ │ ├── AddressAction.php │ │ ├── ChoosePaymentMethodAction.php │ │ ├── ChooseShippingMethodAction.php │ │ ├── CompleteOrderAction.php │ │ ├── ShowAvailablePaymentMethodsAction.php │ │ └── ShowAvailableShippingMethodsAction.php │ ├── Customer │ │ ├── CustomerController.php │ │ ├── LoggedInCustomerDetailsAction.php │ │ ├── RegisterCustomerAction.php │ │ ├── RequestPasswordResettingAction.php │ │ ├── ResendVerificationTokenAction.php │ │ ├── UpdateCustomerAction.php │ │ └── VerifyAccountAction.php │ ├── Order │ │ ├── ShowOrderDetailsAction.php │ │ └── ShowOrdersListAction.php │ ├── Product │ │ ├── AddReviewByCodeAction.php │ │ ├── AddReviewBySlugAction.php │ │ ├── ShowLatestProductAction.php │ │ ├── ShowProductCatalogByTaxonCodeAction.php │ │ ├── ShowProductCatalogByTaxonSlugAction.php │ │ ├── ShowProductDetailsByCodeAction.php │ │ ├── ShowProductDetailsBySlugAction.php │ │ ├── ShowProductReviewsByCodeAction.php │ │ └── ShowProductReviewsBySlugAction.php │ └── Taxon │ │ ├── ShowTaxonDetailsAction.php │ │ └── ShowTaxonTreeAction.php ├── DependencyInjection │ ├── Configuration.php │ └── ShopApiExtension.php ├── Event │ └── CustomerRegistered.php ├── EventListener │ ├── RequestLocaleSetter.php │ └── UserRegistrationListener.php ├── Exception │ ├── ChannelNotFoundException.php │ ├── ViewCreationException.php │ └── WrongUserException.php ├── Factory │ ├── AddressBook │ │ ├── AddressBookViewFactory.php │ │ ├── AddressBookViewFactoryInterface.php │ │ ├── AddressViewFactory.php │ │ └── AddressViewFactoryInterface.php │ ├── Cart │ │ ├── AdjustmentViewFactory.php │ │ ├── AdjustmentViewFactoryInterface.php │ │ ├── CartItemViewFactory.php │ │ ├── CartItemViewFactoryInterface.php │ │ ├── CartViewFactory.php │ │ ├── CartViewFactoryInterface.php │ │ ├── EstimatedShippingCostViewFactory.php │ │ ├── EstimatedShippingCostViewFactoryInterface.php │ │ ├── TotalViewFactory.php │ │ └── TotalViewFactoryInterface.php │ ├── Checkout │ │ ├── PaymentMethodViewFactory.php │ │ ├── PaymentMethodViewFactoryInterface.php │ │ ├── PaymentViewFactory.php │ │ ├── PaymentViewFactoryInterface.php │ │ ├── ShipmentViewFactory.php │ │ ├── ShipmentViewFactoryInterface.php │ │ ├── ShippingMethodViewFactory.php │ │ └── ShippingMethodViewFactoryInterface.php │ ├── Customer │ │ ├── CustomerViewFactory.php │ │ └── CustomerViewFactoryInterface.php │ ├── Order │ │ ├── PlacedOrderViewFactory.php │ │ └── PlacedOrderViewFactoryInterface.php │ ├── PriceViewFactory.php │ ├── PriceViewFactoryInterface.php │ ├── Product │ │ ├── DetailedProductViewFactory.php │ │ ├── LimitedProductAttributeValuesViewFactory.php │ │ ├── ListProductViewFactory.php │ │ ├── PageViewFactory.php │ │ ├── PageViewFactoryInterface.php │ │ ├── ProductAttributeValueViewFactory.php │ │ ├── ProductAttributeValueViewFactoryInterface.php │ │ ├── ProductAttributeValuesViewFactoryInterface.php │ │ ├── ProductReviewViewFactory.php │ │ ├── ProductReviewViewFactoryInterface.php │ │ ├── ProductVariantViewFactory.php │ │ ├── ProductVariantViewFactoryInterface.php │ │ ├── ProductViewFactory.php │ │ └── ProductViewFactoryInterface.php │ ├── Taxon │ │ ├── ImageViewFactory.php │ │ ├── ImageViewFactoryInterface.php │ │ ├── TaxonDetailsViewFactory.php │ │ ├── TaxonDetailsViewFactoryInterface.php │ │ ├── TaxonViewFactory.php │ │ └── TaxonViewFactoryInterface.php │ ├── ValidationErrorViewFactory.php │ └── ValidationErrorViewFactoryInterface.php ├── Generator │ ├── ProductBreadcrumbGenerator.php │ └── ProductBreadcrumbGeneratorInterface.php ├── Handler │ ├── AddressBook │ │ ├── CreateAddressHandler.php │ │ ├── RemoveAddressHandler.php │ │ ├── SetDefaultAddressHandler.php │ │ └── UpdateAddressBookAddressHandler.php │ ├── Cart │ │ ├── AddCouponHandler.php │ │ ├── AddressOrderHandler.php │ │ ├── ChangeItemQuantityHandler.php │ │ ├── ChoosePaymentMethodHandler.php │ │ ├── ChooseShippingMethodHandler.php │ │ ├── CompleteOrderHandler.php │ │ ├── DropCartHandler.php │ │ ├── PickupCartHandler.php │ │ ├── PutOptionBasedConfigurableItemToCartHandler.php │ │ ├── PutSimpleItemToCartHandler.php │ │ ├── PutVariantBasedConfigurableItemToCartHandler.php │ │ ├── RemoveCouponHandler.php │ │ └── RemoveItemFromCartHandler.php │ ├── Customer │ │ ├── GenerateResetPasswordTokenHandler.php │ │ ├── GenerateVerificationTokenHandler.php │ │ ├── RegisterCustomerHandler.php │ │ ├── SendResetPasswordTokenHandler.php │ │ ├── SendVerificationTokenHandler.php │ │ ├── UpdateCustomerHandler.php │ │ └── VerifyAccountHandler.php │ └── Product │ │ ├── AddProductReviewByCodeHandler.php │ │ └── AddProductReviewBySlugHandler.php ├── Http │ ├── RequestBasedLocaleProvider.php │ ├── RequestBasedLocaleProviderInterface.php │ └── RequestChannelEnsurer.php ├── Mailer │ └── Emails.php ├── Mapper │ ├── AddressMapper.php │ └── AddressMapperInterface.php ├── Model │ ├── Address.php │ └── PaginatorDetails.php ├── Modifier │ ├── OrderModifier.php │ └── OrderModifierInterface.php ├── Normalizer │ ├── RequestCartTokenNormalizer.php │ └── RequestCartTokenNormalizerInterface.php ├── Provider │ ├── CustomerProviderInterface.php │ ├── LoggedInShopUserProvider.php │ ├── LoggedInShopUserProviderInterface.php │ ├── ProductReviewerProvider.php │ ├── ProductReviewerProviderInterface.php │ ├── ShopUserAwareCustomerProvider.php │ ├── SupportedLocaleProvider.php │ └── SupportedLocaleProviderInterface.php ├── Request │ ├── AddressBook │ │ ├── RemoveAddressRequest.php │ │ └── SetDefaultAddressRequest.php │ ├── Cart │ │ ├── AddCouponRequest.php │ │ ├── ChangeItemQuantityRequest.php │ │ ├── DropCartRequest.php │ │ ├── EstimateShippingCostRequest.php │ │ ├── PickupCartRequest.php │ │ ├── PutOptionBasedConfigurableItemToCartRequest.php │ │ ├── PutSimpleItemToCartRequest.php │ │ ├── PutVariantBasedConfigurableItemToCartRequest.php │ │ ├── RemoveCouponRequest.php │ │ └── RemoveItemFromCartRequest.php │ ├── Checkout │ │ └── AddressOrderRequest.php │ ├── Customer │ │ ├── RegisterCustomerRequest.php │ │ ├── ResendVerificationTokenRequest.php │ │ ├── UpdateCustomerRequest.php │ │ └── VerifyAccountRequest.php │ └── Product │ │ ├── AddProductReviewByCodeRequest.php │ │ └── AddProductReviewBySlugRequest.php ├── Resources │ ├── config │ │ ├── app │ │ │ ├── config.yml │ │ │ └── sylius_mailer.yml │ │ ├── routing.yml │ │ ├── routing │ │ │ ├── address_book.yml │ │ │ ├── cart.yml │ │ │ ├── checkout.yml │ │ │ ├── customer.yml │ │ │ ├── order.yml │ │ │ ├── productByCode.yml │ │ │ ├── productBySlug.yml │ │ │ ├── productList.yml │ │ │ ├── register.yml │ │ │ └── taxon.yml │ │ ├── serializer │ │ │ ├── Product │ │ │ │ ├── PageView.yml │ │ │ │ ├── ProductVariantView.yml │ │ │ │ └── ProductView.yml │ │ │ └── Taxon │ │ │ │ └── ImageView.yml │ │ ├── services.xml │ │ ├── services │ │ │ ├── actions │ │ │ │ ├── address_book.xml │ │ │ │ ├── cart.xml │ │ │ │ ├── checkout.xml │ │ │ │ ├── customer.xml │ │ │ │ ├── order.xml │ │ │ │ ├── product.xml │ │ │ │ └── taxon.xml │ │ │ ├── controllers.xml │ │ │ ├── factories.xml │ │ │ ├── factories │ │ │ │ ├── address_book.xml │ │ │ │ ├── cart.xml │ │ │ │ ├── checkout.xml │ │ │ │ ├── customer.xml │ │ │ │ ├── order.xml │ │ │ │ ├── product.xml │ │ │ │ └── taxon.xml │ │ │ ├── handler │ │ │ │ ├── address_book.xml │ │ │ │ ├── cart.xml │ │ │ │ ├── customer.xml │ │ │ │ └── product.xml │ │ │ ├── handlers.xml │ │ │ ├── http.xml │ │ │ ├── mapper.xml │ │ │ ├── providers.xml │ │ │ ├── queries.xml │ │ │ ├── repositories │ │ │ │ ├── cart.xml │ │ │ │ ├── order.xml │ │ │ │ └── product.xml │ │ │ ├── shipping.xml │ │ │ ├── validators.xml │ │ │ └── validators │ │ │ │ ├── address.xml │ │ │ │ ├── cart.xml │ │ │ │ ├── customer.xml │ │ │ │ └── product.xml │ │ └── validation │ │ │ ├── address_book │ │ │ ├── AddressModelRequest.xml │ │ │ ├── RemoveAddressRequest.xml │ │ │ └── SetDefaultAddressRequest.xml │ │ │ ├── cart │ │ │ ├── AddCouponRequest.xml │ │ │ ├── ChangeItemQuantityRequest.xml │ │ │ ├── DropCartRequest.xml │ │ │ ├── EstimateShippingCostRequest.xml │ │ │ ├── PickupCartRequest.xml │ │ │ ├── PutOptionBasedConfigutableItemToCartRequest.xml │ │ │ ├── PutSimpleItemToCartRequest.xml │ │ │ ├── PutVariantBasedConfigutableItemToCartRequest.xml │ │ │ ├── RemoveCouponRequest.xml │ │ │ └── RemoveItemFromCartRequest.xml │ │ │ ├── checkout │ │ │ └── AddressOrderRequest.xml │ │ │ ├── customer │ │ │ ├── CustomerRequest.xml │ │ │ ├── RegisterCustomerRequest.xml │ │ │ └── ResendVerificationTokenRequest.xml │ │ │ └── product │ │ │ ├── AddProductReviewByCodeRequest.xml │ │ │ └── AddProductReviewBySlugRequest.xml │ ├── translations │ │ ├── validators.de.yml │ │ └── validators.en.yml │ └── views │ │ └── Email │ │ ├── passwordReset.html.twig │ │ └── verification.html.twig ├── Shipping │ ├── ShippingCost.php │ ├── ShippingCostEstimator.php │ └── ShippingCostEstimatorInterface.php ├── ShopApiPlugin.php ├── Validator │ ├── Address │ │ ├── AddressExistsValidator.php │ │ └── CountryExistsValidator.php │ ├── Cart │ │ ├── CartExistsValidator.php │ │ ├── CartItemExistsValidator.php │ │ ├── TokenIsNotUsedValidator.php │ │ └── ValidPromotionCouponCodeValidator.php │ ├── ChannelExistsValidator.php │ ├── Constraints │ │ ├── AddressExists.php │ │ ├── CartExists.php │ │ ├── CartItemExists.php │ │ ├── ChannelExists.php │ │ ├── ConfigurableProduct.php │ │ ├── CountryExists.php │ │ ├── ProductExists.php │ │ ├── ProductVariantExists.php │ │ ├── ShopUserDoesNotExist.php │ │ ├── ShopUserExists.php │ │ ├── SimpleProduct.php │ │ ├── TokenIsNotUsed.php │ │ └── ValidPromotionCouponCode.php │ ├── Customer │ │ ├── ShopUserDoesNotExistValidator.php │ │ └── ShopUserExistsValidator.php │ └── Product │ │ ├── ConfigurableProductValidator.php │ │ ├── ProductExistsValidator.php │ │ ├── ProductVariantExistsValidator.php │ │ └── SimpleProductValidator.php ├── View │ ├── AddressBook │ │ ├── AddressBookView.php │ │ └── AddressView.php │ ├── Cart │ │ ├── AdjustmentView.php │ │ ├── CartSummaryView.php │ │ ├── EstimatedShippingCostView.php │ │ ├── PaymentMethodView.php │ │ ├── PaymentView.php │ │ ├── ShippingMethodView.php │ │ └── TotalsView.php │ ├── Checkout │ │ └── ShipmentView.php │ ├── Customer │ │ └── CustomerView.php │ ├── ItemView.php │ ├── Order │ │ └── PlacedOrderView.php │ ├── PriceView.php │ ├── Product │ │ ├── PageLinksView.php │ │ ├── PageView.php │ │ ├── ProductAttributeValueView.php │ │ ├── ProductListView.php │ │ ├── ProductReviewView.php │ │ ├── ProductTaxonView.php │ │ ├── ProductVariantView.php │ │ ├── ProductView.php │ │ ├── VariantOptionValueView.php │ │ └── VariantOptionView.php │ ├── Taxon │ │ ├── ImageView.php │ │ ├── TaxonDetailsView.php │ │ └── TaxonView.php │ └── ValidationErrorView.php └── ViewRepository │ ├── Cart │ ├── CartViewRepository.php │ └── CartViewRepositoryInterface.php │ ├── Order │ ├── PlacedOrderViewRepository.php │ └── PlacedOrderViewRepositoryInterface.php │ └── Product │ ├── ProductCatalogViewRepository.php │ ├── ProductCatalogViewRepositoryInterface.php │ ├── ProductDetailsViewRepository.php │ ├── ProductDetailsViewRepositoryInterface.php │ ├── ProductLatestViewRepository.php │ ├── ProductLatestViewRepositoryInterface.php │ ├── ProductReviewsViewRepository.php │ └── ProductReviewsViewRepositoryInterface.php └── tests ├── Application ├── .env.dist ├── .env.prod.dist ├── .env.test.dist ├── .gitignore ├── Kernel.php ├── bin │ └── console ├── composer.json ├── config │ ├── bundles.php │ ├── jwt │ │ ├── private-test.pem │ │ └── public-test.pem │ ├── packages │ │ ├── _sylius.yaml │ │ ├── dev │ │ │ ├── framework.yaml │ │ │ ├── jms_serializer.yaml │ │ │ ├── monolog.yaml │ │ │ ├── routing.yaml │ │ │ ├── swiftmailer.yaml │ │ │ └── web_profiler.yaml │ │ ├── doctrine.yaml │ │ ├── doctrine_migrations.yaml │ │ ├── fos_rest.yaml │ │ ├── framework.yaml │ │ ├── jms_serializer.yaml │ │ ├── lexik_jwt_authentication.yaml │ │ ├── liip_imagine.yaml │ │ ├── prod │ │ │ ├── doctrine.yaml │ │ │ ├── jms_serializer.yaml │ │ │ └── monolog.yaml │ │ ├── routing.yaml │ │ ├── security.yaml │ │ ├── security_checker.yaml │ │ ├── sonata_core.yaml │ │ ├── staging │ │ │ ├── monolog.yaml │ │ │ └── swiftmailer.yaml │ │ ├── stof_doctrine_extensions.yaml │ │ ├── swiftmailer.yaml │ │ ├── sylius_shop_api.yaml │ │ ├── test │ │ │ ├── framework.yaml │ │ │ ├── monolog.yaml │ │ │ ├── swiftmailer.yaml │ │ │ ├── sylius_theme.yaml │ │ │ └── web_profiler.yaml │ │ ├── test_cached │ │ │ ├── doctrine.yaml │ │ │ ├── fos_rest.yaml │ │ │ ├── framework.yaml │ │ │ ├── monolog.yaml │ │ │ ├── swiftmailer.yaml │ │ │ ├── sylius_channel.yaml │ │ │ ├── sylius_theme.yaml │ │ │ └── twig.yaml │ │ ├── translation.yaml │ │ ├── twig.yaml │ │ ├── twig_extensions.yaml │ │ └── validator.yaml │ ├── routes.yaml │ ├── routes │ │ ├── dev │ │ │ ├── twig.yaml │ │ │ └── web_profiler.yaml │ │ ├── liip_imagine.yaml │ │ ├── sylius_admin.yaml │ │ ├── sylius_admin_api.yaml │ │ └── sylius_shop.yaml │ └── services.yaml ├── public │ ├── .htaccess │ ├── favicon.ico │ ├── index.php │ ├── media │ │ └── image │ │ │ └── .gitignore │ └── robots.txt ├── templates │ └── .gitignore └── translations │ └── .gitignore ├── Controller ├── .gitkeep ├── AddressBook │ ├── AddressBookCreateAddressApiTest.php │ ├── AddressBookRemoveAddressApiTest.php │ ├── AddressBookSetDefaultAddressApiTest.php │ ├── AddressBookShowApiTest.php │ └── AddressBookUpdateAddressApiTest.php ├── Cart │ ├── CartAddCouponShopApiTest.php │ ├── CartChangeItemQuantityApiTest.php │ ├── CartDropCartApiTest.php │ ├── CartEstimateShippingTest.php │ ├── CartPickupApiTest.php │ ├── CartPutItemToCartApiTest.php │ ├── CartPutItemsToCartApiTest.php │ ├── CartRemoveCouponShopApiTest.php │ ├── CartRemoveItemFromCartApiTest.php │ └── CartSummarizeApiTest.php ├── Checkout │ ├── CheckoutAddressApiTest.php │ ├── CheckoutChoosePaymentMethodApiTest.php │ ├── CheckoutChooseShippingMethodApiTest.php │ ├── CheckoutCompleteOrderApiTest.php │ ├── CheckoutShowAvailablePaymentMethodsShopApiTest.php │ ├── CheckoutShowAvailableShippingMethodsShopApiTest.php │ └── CheckoutSummarizeApiTest.php ├── Customer │ ├── CustomerLoginApiTest.php │ ├── CustomerRegisterApiTest.php │ ├── CustomerRequestPasswordResettingApiTest.php │ ├── CustomerResendVerificationTokenApiTest.php │ ├── CustomerResetPasswordApiTest.php │ ├── CustomerUpdateCustomerApiTest.php │ ├── CustomerVerifyApiTest.php │ └── LoggedInCustomerDetailsActionTest.php ├── JsonApiTestCase.php ├── Order │ ├── OrderShowApiTest.php │ └── OrdersListApiTest.php ├── Product │ ├── ProductAddReviewByCodeApiTest.php │ ├── ProductAddReviewBySlugApiTest.php │ ├── ProductShowCatalogByCodeApiTest.php │ ├── ProductShowCatalogBySlugApiTest.php │ ├── ProductShowDetailsByCodeApiTest.php │ ├── ProductShowDetailsBySlugApiTest.php │ ├── ProductShowLatestApiTest.php │ ├── ProductShowReviewsByCodeApiTest.php │ └── ProductShowReviewsBySlugApiTest.php ├── Taxon │ ├── TaxonShowDetailsApiTest.php │ └── TaxonShowTreeApiTest.php └── Utils │ ├── OrderPlacerTrait.php │ ├── PurgeSpooledMessagesTrait.php │ └── ShopUserLoginTrait.php ├── DataFixtures ├── .gitkeep └── ORM │ ├── address.yml │ ├── channel.yml │ ├── country.yml │ ├── coupon_based_promotion.yml │ ├── customer.yml │ ├── mug_review.yml │ ├── payment.yml │ ├── promotion.yml │ ├── shipping.yml │ └── shop.yml ├── DependencyInjection ├── ConfigurationTest.php └── ShopApiExtensionTest.php ├── Request ├── AddCouponRequestTest.php ├── AddProductReviewByCodeRequestTest.php ├── AddProductReviewBySlugRequestTest.php ├── ChangeItemQuantityRequestTest.php ├── DropCartRequestTest.php ├── PickupCartRequestTest.php ├── PutOptionBasedConfigurableItemToCartRequestTest.php ├── PutSimpleItemToCartRequestTest.php ├── PutVariantBasedConfigurableItemToCartRequestTest.php ├── ResendVerificationTokenRequestTest.php ├── UpdateCustomerRequestTest.php └── VerifyAccountRequestTest.php └── Responses └── Expected ├── .gitkeep ├── address_book ├── add_address_response.json ├── show_address_book_response.json ├── update_address.json ├── validation_create_address_book_response.json ├── validation_create_address_book_with_wrong_country_response.json └── validation_create_address_book_with_wrong_province_response.json ├── cart ├── add_multiple_products_to_cart_response.json ├── add_multiple_products_to_cart_validation_error_response.json ├── add_multiple_products_to_new_cart_response.json ├── add_product_variant_based_on_options_multiple_times_to_cart_response.json ├── add_product_variant_based_on_options_to_cart_response.json ├── add_product_variant_multiple_times_to_cart_response.json ├── add_product_variant_to_cart_response.json ├── add_simple_product_multiple_times_to_cart_response.json ├── add_simple_product_to_cart_response.json ├── add_simple_product_to_new_cart_response.json ├── cart_after_deleting_an_item.json ├── cart_and_country_does_not_exist_response.json ├── cart_has_not_been_found_response.json ├── cart_item_has_not_been_found_response.json ├── cart_with_coupon_based_promotion_applied_response.json ├── deprecated_empty_response.json ├── empty_response.json ├── estimated_shipping_cost_bases_on_country_and_province_response.json ├── estimated_shipping_cost_bases_on_country_response.json ├── filled_cart_with_product_variant_summary_response.json ├── filled_cart_with_simple_product_summary_response.json ├── german_filled_cart_with_product_variant_summary_response.json ├── german_filled_cart_with_simple_product_summary_response.json ├── product_variant_has_not_been_found_response.json ├── reprocessed_cart_after_deleting_an_item.json ├── validation_cart_and_cart_item_not_exist_response.json ├── validation_cart_item_not_exists_response.json ├── validation_cart_not_exists_in_german_response.json ├── validation_cart_not_exists_response.json ├── validation_channel_not_exists_response.json ├── validation_channel_not_found_response.json ├── validation_coupon_not_found_response.json ├── validation_coupon_not_valid_response.json ├── validation_product_not_configurable_response.json ├── validation_product_not_defined_response.json ├── validation_product_not_exists_response.json ├── validation_product_not_simple_response.json ├── validation_product_variant_not_exists_response.json ├── validation_quantity_lower_than_one_response.json └── validation_token_already_used_response.json ├── channel_has_not_been_found_response.json ├── checkout ├── cart_addressed_response.json ├── cart_addressed_with_different_shipping_and_billing_address_response.json ├── cart_with_chosen_payment_response.json ├── cart_with_chosen_shipment_response.json ├── cart_with_chosen_shipment_with_per_item_rate_response.json ├── get_available_payment_methods.json ├── get_available_payment_methods_failed.json ├── get_available_shipping_methods.json ├── get_available_shipping_methods_failed.json └── modified_cart_with_chosen_shipment_with_per_item_rate_response.json ├── customer ├── bad_credentials_response.json ├── customer_log_in_response.json ├── logged_in_customer_details_response.json ├── update_customer.json ├── validation_email_not_defined_response.json ├── validation_email_not_found_response.json ├── validation_email_not_valid_response.json ├── validation_empty_data.json ├── validation_registration_data_response.json └── validation_registration_email_taken_response.json ├── order ├── order_details_response.json ├── order_not_found_response.json └── orders_list_response.json ├── product ├── channel_has_not_been_found_response.json ├── german_product_list_page_by_code_response.json ├── german_product_list_page_by_slug_response.json ├── german_product_with_options_details_page.json ├── german_simple_product_details_page.json ├── limited_product_list_page_by_code_response.json ├── limited_product_list_page_by_slug_response.json ├── product_has_not_been_found_for_given_code_response.json ├── product_has_not_been_found_for_given_slug_response.json ├── product_list_latest_2_response.json ├── product_list_latest_4_response.json ├── product_list_page_by_code_response.json ├── product_list_page_by_slug_response.json ├── product_review_list_page_by_code_response.json ├── product_review_list_page_by_slug_response.json ├── product_t_shirt_list_page_by_code_response.json ├── product_t_shirt_list_page_by_slug_response.json ├── product_with_options_details_page.json ├── product_with_variant_details_page.json ├── product_without_taxons_details_page.json └── simple_product_details_page.json ├── reviews ├── add_review_failed_email.json └── add_review_failed_rating.json └── taxon ├── all_taxons_response.json ├── german_all_taxons_response.json ├── german_one_of_taxons_response.json ├── one_of_taxons_response.json └── strange_taxon_code_response.json /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | # Change these settings to your own preference 9 | indent_style = space 10 | indent_size = 4 11 | 12 | # We recommend you to keep these unchanged 13 | end_of_line = lf 14 | charset = utf-8 15 | trim_trailing_whitespace = true 16 | insert_final_newline = true 17 | 18 | [*.json] 19 | indent_style = space 20 | indent_size = 2 21 | 22 | [*.md] 23 | indent_style = space 24 | indent_size = 4 25 | trim_trailing_whitespace = false 26 | 27 | [*.neon] 28 | indent_style = space 29 | indent_size = 4 30 | 31 | [*.php] 32 | indent_style = space 33 | indent_size = 4 34 | 35 | [*.{yaml,yml}] 36 | indent_style = space 37 | indent_size = 4 38 | trim_trailing_whitespace = false 39 | 40 | [.gitmodules] 41 | indent_style = tab 42 | indent_size = 4 43 | 44 | [composer.json] 45 | indent_style = space 46 | indent_size = 4 47 | 48 | [phpspec.yml{,.dist}] 49 | indent_style = space 50 | indent_size = 4 51 | 52 | [phpstan.neon{,.dist}] 53 | indent_style = space 54 | indent_size = 4 55 | 56 | [phpunit.xml{,.dist}] 57 | indent_style = space 58 | indent_size = 4 59 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @Sylius/core-team 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /composer.lock 2 | /vendor/ 3 | /bin/* 4 | !/bin/.gitkeep 5 | 6 | .phpunit.result.cache 7 | /phpunit.xml 8 | -------------------------------------------------------------------------------- /bin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dunglas/ShopApiPlugin/4e952c027532df71068af0b53946937fd16b2276/bin/.gitkeep -------------------------------------------------------------------------------- /easy-coding-standard.yml: -------------------------------------------------------------------------------- 1 | imports: 2 | - { resource: 'vendor/sylius-labs/coding-standard/easy-coding-standard.yml' } 3 | -------------------------------------------------------------------------------- /phpspec.yml.dist: -------------------------------------------------------------------------------- 1 | suites: 2 | default: 3 | namespace: Sylius\ShopApiPlugin 4 | psr4_prefix: Sylius\ShopApiPlugin 5 | -------------------------------------------------------------------------------- /phpstan.neon: -------------------------------------------------------------------------------- 1 | includes: 2 | - vendor/phpstan/phpstan-webmozart-assert/extension.neon 3 | 4 | parameters: 5 | excludes_analyse: 6 | # Makes PHPStan crash 7 | - src/DependencyInjection/Configuration.php 8 | 9 | ignoreErrors: 10 | - /^Access to an undefined property Symfony\\Component\\Validator\\Constraint::\$message\.$/ 11 | - '/^Method Symfony\\Contracts\\EventDispatcher\\EventDispatcherInterface::dispatch\(\) invoked with 2 parameters, 1 required\.$/' 12 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | ./tests 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | ./tests/Application 22 | ./tests/DataFixtures 23 | ./tests/Responses 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /spec/Command/AddressBook/CreateAddressSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith(Address::createFromArray([ 15 | 'firstName' => 'Sherlock', 16 | 'lastName' => 'Holmes', 17 | 'city' => 'London', 18 | 'street' => 'Baker Street 221b', 19 | 'countryCode' => 'GB', 20 | 'postcode' => 'NWB', 21 | 'provinceName' => 'Greater London', 22 | 'provinceCode' => 'GB-GL', 23 | 'phoneNumber' => '0912538092', 24 | 'company' => 'Sherlock ltd.', 25 | ]), 'user@email.com'); 26 | } 27 | 28 | function it_has_address(): void 29 | { 30 | $this->address()->shouldBeAnInstanceOf(Address::class); 31 | } 32 | 33 | function it_has_user_email(): void 34 | { 35 | $this->userEmail()->shouldReturn('user@email.com'); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /spec/Command/AddressBook/RemoveAddressSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('ADDRESS_ID', 'user@email.com'); 14 | } 15 | 16 | function it_has_id(): void 17 | { 18 | $this->id()->shouldReturn('ADDRESS_ID'); 19 | } 20 | 21 | function it_has_user_email(): void 22 | { 23 | $this->userEmail()->shouldReturn('user@email.com'); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /spec/Command/AddressBook/SetDefaultAddressSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('ADDRESS_ID', 'user@email.com'); 14 | } 15 | 16 | function it_has_id(): void 17 | { 18 | $this->id()->shouldReturn('ADDRESS_ID'); 19 | } 20 | 21 | function it_has_user_email(): void 22 | { 23 | $this->userEmail()->shouldReturn('user@email.com'); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /spec/Command/Cart/AddCouponSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('ORDERTOKEN', 'COUPON_CODE'); 14 | } 15 | 16 | public function it_has_order_token(): void 17 | { 18 | $this->orderToken()->shouldReturn('ORDERTOKEN'); 19 | } 20 | 21 | public function it_has_coupon_code(): void 22 | { 23 | $this->couponCode()->shouldReturn('COUPON_CODE'); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /spec/Command/Cart/ChangeItemQuantitySpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('ORDERTOKEN', 1, 5); 15 | } 16 | 17 | function it_has_order_token(): void 18 | { 19 | $this->orderToken()->shouldReturn('ORDERTOKEN'); 20 | } 21 | 22 | function it_has_product_code(): void 23 | { 24 | $this->itemIdentifier()->shouldReturn(1); 25 | } 26 | 27 | function it_has_quantity(): void 28 | { 29 | $this->quantity()->shouldReturn(5); 30 | } 31 | 32 | function it_throws_an_exception_if_quantity_is_not_less_then_1(): void 33 | { 34 | $this->beConstructedWith('ORDERTOKEN', 'T_SHIRT_CODE', 0); 35 | 36 | $this->shouldThrow(InvalidArgumentException::class)->duringInstantiation(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /spec/Command/Cart/ChoosePaymentMethodSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('ORDERTOKEN', 1, 'CASH_ON_DELIVERY_METHOD'); 14 | } 15 | 16 | function it_has_order_token(): void 17 | { 18 | $this->orderToken()->shouldReturn('ORDERTOKEN'); 19 | } 20 | 21 | function it_has_identifier_of_payment(): void 22 | { 23 | $this->paymentIdentifier()->shouldReturn(1); 24 | } 25 | 26 | function it_has_payment_method_defined(): void 27 | { 28 | $this->paymentMethod()->shouldReturn('CASH_ON_DELIVERY_METHOD'); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /spec/Command/Cart/ChooseShippingMethodSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('ORDERTOKEN', 1, 'DHL_SHIPPING_METHOD'); 14 | } 15 | 16 | function it_has_order_token(): void 17 | { 18 | $this->orderToken()->shouldReturn('ORDERTOKEN'); 19 | } 20 | 21 | function it_has_identifier_of_shipping(): void 22 | { 23 | $this->shipmentIdentifier()->shouldReturn(1); 24 | } 25 | 26 | function it_has_shipping_method_defined(): void 27 | { 28 | $this->shippingMethod()->shouldReturn('DHL_SHIPPING_METHOD'); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /spec/Command/Cart/CompleteOrderSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('ORDERTOKEN', 'example@customer.com'); 14 | } 15 | 16 | function it_has_order_token(): void 17 | { 18 | $this->orderToken()->shouldReturn('ORDERTOKEN'); 19 | } 20 | 21 | function it_has_email(): void 22 | { 23 | $this->email()->shouldReturn('example@customer.com'); 24 | } 25 | 26 | function it_can_have_a_note(): void 27 | { 28 | $this->beConstructedWith('ORDERTOKEN', 'example@customer.com', 'Some order notes'); 29 | 30 | $this->notes()->shouldReturn('Some order notes'); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /spec/Command/Cart/DropCartSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('ORDERTOKEN'); 14 | } 15 | 16 | function it_has_order_token(): void 17 | { 18 | $this->orderToken()->shouldReturn('ORDERTOKEN'); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /spec/Command/Cart/PickupCartSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('ORDERTOKEN', 'CHANNEL_CODE'); 14 | } 15 | 16 | function it_has_order_token(): void 17 | { 18 | $this->orderToken()->shouldReturn('ORDERTOKEN'); 19 | } 20 | 21 | function it_has_channel_code(): void 22 | { 23 | $this->channelCode()->shouldReturn('CHANNEL_CODE'); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /spec/Command/Cart/PutSimpleItemToCartSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('ORDERTOKEN', 'T_SHIRT_CODE', 5); 14 | } 15 | 16 | function it_has_order_token(): void 17 | { 18 | $this->orderToken()->shouldReturn('ORDERTOKEN'); 19 | } 20 | 21 | function it_has_product_code(): void 22 | { 23 | $this->product()->shouldReturn('T_SHIRT_CODE'); 24 | } 25 | 26 | function it_has_quantity(): void 27 | { 28 | $this->quantity()->shouldReturn(5); 29 | } 30 | 31 | function it_throws_an_exception_if_quantity_is_not_less_then_0(): void 32 | { 33 | $this->beConstructedWith('ORDERTOKEN', 'T_SHIRT_CODE', 0); 34 | 35 | $this->shouldThrow(\InvalidArgumentException::class)->duringInstantiation(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /spec/Command/Customer/GenerateResetPasswordTokenSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('example@customer.com'); 15 | } 16 | 17 | function it_is_initializable(): void 18 | { 19 | $this->shouldHaveType(GenerateResetPasswordToken::class); 20 | } 21 | 22 | function it_has_email(): void 23 | { 24 | $this->email()->shouldReturn('example@customer.com'); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /spec/Command/Customer/GenerateVerificationTokenSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('example@customer.com'); 15 | } 16 | 17 | function it_is_initializable(): void 18 | { 19 | $this->shouldHaveType(GenerateVerificationToken::class); 20 | } 21 | 22 | function it_has_email(): void 23 | { 24 | $this->email()->shouldReturn('example@customer.com'); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /spec/Command/Customer/SendResetPasswordTokenSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('example@customer.com', 'WEB_GB'); 15 | } 16 | 17 | function it_is_initializable(): void 18 | { 19 | $this->shouldHaveType(SendResetPasswordToken::class); 20 | } 21 | 22 | function it_has_email(): void 23 | { 24 | $this->email()->shouldReturn('example@customer.com'); 25 | } 26 | 27 | function it_has_channel_code(): void 28 | { 29 | $this->channelCode()->shouldReturn('WEB_GB'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /spec/Command/Customer/SendVerificationTokenSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('example@customer.com', 'WEB_GB'); 15 | } 16 | 17 | function it_is_initializable(): void 18 | { 19 | $this->shouldHaveType(SendVerificationToken::class); 20 | } 21 | 22 | function it_has_email(): void 23 | { 24 | $this->email()->shouldReturn('example@customer.com'); 25 | } 26 | 27 | function it_has_channel_code(): void 28 | { 29 | $this->channelCode()->shouldReturn('WEB_GB'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /spec/Command/Customer/VerifyAccountSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('RANDOMSTRINGAFNAKJFNAKNF'); 15 | } 16 | 17 | function it_is_initializable(): void 18 | { 19 | $this->shouldHaveType(VerifyAccount::class); 20 | } 21 | 22 | function it_has_email(): void 23 | { 24 | $this->token()->shouldReturn('RANDOMSTRINGAFNAKJFNAKNF'); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /spec/Factory/PriceViewFactorySpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith(PriceView::class); 16 | } 17 | 18 | function it_is_price_view_factory(): void 19 | { 20 | $this->shouldHaveType(PriceViewFactoryInterface::class); 21 | } 22 | 23 | function it_builds_price_view(): void 24 | { 25 | $priceView = new PriceView(); 26 | $priceView->current = 500; 27 | $priceView->currency = 'BTC'; 28 | 29 | $this->create(500, 'BTC')->shouldBeLike($priceView); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /spec/Factory/Taxon/ImageViewFactorySpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith(ImageView::class); 17 | } 18 | 19 | function it_is_image_view_factory(): void 20 | { 21 | $this->shouldHaveType(ImageViewFactoryInterface::class); 22 | } 23 | 24 | function it_creates_image_view(ImageInterface $image): void 25 | { 26 | $image->getType()->willReturn('thumbnail'); 27 | $image->getPath()->willReturn('/ou/some.jpg'); 28 | 29 | $imageView = new ImageView(); 30 | $imageView->code = 'thumbnail'; 31 | $imageView->path = '/ou/some.jpg'; 32 | 33 | $this->create($image)->shouldBeLike($imageView); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /spec/Handler/AddressBook/RemoveAddressHandlerSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith( 20 | $addressRepository, 21 | $orderRepository 22 | ); 23 | } 24 | 25 | function it_removes_address_from_address_book( 26 | AddressRepositoryInterface $addressRepository, 27 | AddressInterface $address 28 | ): void { 29 | $addressRepository->findOneBy(['id' => 'ADDRESS_ID'])->willReturn($address); 30 | 31 | $addressRepository->remove($address)->shouldBeCalled(); 32 | 33 | $this(new RemoveAddress('ADDRESS_ID', 'user@email.com')); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /spec/Provider/ProductReviewerProviderSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($customerProvider); 17 | } 18 | 19 | function it_is_reviewer_subject_provider(): void 20 | { 21 | $this->shouldImplement(ProductReviewerProviderInterface::class); 22 | } 23 | 24 | function it_provides_product_reviewer(Customer $reviewer, CustomerProviderInterface $customerProvider): void 25 | { 26 | $customerProvider->provide('example@customer.com')->willReturn($reviewer); 27 | 28 | $this->provide('example@customer.com')->shouldReturn($reviewer); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /spec/Validator/Cart/ValidPromotionCouponCodeValidatorSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith($orderRepository, $promotionCouponRepository, $couponEligibilityChecker); 22 | 23 | $this->initialize($executionContext); 24 | } 25 | 26 | // todo: add more tests ad this is the only test that works on the request itself 27 | } 28 | -------------------------------------------------------------------------------- /src/Checker/ChannelExistenceChecker.php: -------------------------------------------------------------------------------- 1 | channelRepository = $channelRepository; 18 | } 19 | 20 | public function withCode(string $channelCode): void 21 | { 22 | $channel = $this->channelRepository->findOneByCode($channelCode); 23 | 24 | if (null === $channel) { 25 | throw ChannelNotFoundException::withCode($channelCode); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Checker/ChannelExistenceCheckerInterface.php: -------------------------------------------------------------------------------- 1 | address = $address; 20 | $this->userEmail = $userEmail; 21 | } 22 | 23 | public function address(): Address 24 | { 25 | return $this->address; 26 | } 27 | 28 | public function userEmail(): string 29 | { 30 | return $this->userEmail; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Command/AddressBook/RemoveAddress.php: -------------------------------------------------------------------------------- 1 | id = $id; 18 | $this->userEmail = $userEmail; 19 | } 20 | 21 | public function id() 22 | { 23 | return $this->id; 24 | } 25 | 26 | public function userEmail(): string 27 | { 28 | return $this->userEmail; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Command/AddressBook/SetDefaultAddress.php: -------------------------------------------------------------------------------- 1 | id = $id; 18 | $this->userEmail = $userEmail; 19 | } 20 | 21 | public function id() 22 | { 23 | return $this->id; 24 | } 25 | 26 | public function userEmail(): string 27 | { 28 | return $this->userEmail; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Command/AddressBook/UpdateAddress.php: -------------------------------------------------------------------------------- 1 | address = $address; 23 | $this->userEmail = $userEmail; 24 | $this->addressId = $addressId; 25 | } 26 | 27 | public function id(): string 28 | { 29 | return $this->addressId; 30 | } 31 | 32 | public function address(): Address 33 | { 34 | return $this->address; 35 | } 36 | 37 | public function userEmail(): string 38 | { 39 | return $this->userEmail; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Command/Cart/AddCoupon.php: -------------------------------------------------------------------------------- 1 | orderToken = $orderToken; 18 | $this->couponCode = $couponCode; 19 | } 20 | 21 | public function orderToken(): string 22 | { 23 | return $this->orderToken; 24 | } 25 | 26 | public function couponCode(): string 27 | { 28 | return $this->couponCode; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Command/Cart/AddressOrder.php: -------------------------------------------------------------------------------- 1 | orderToken = $orderToken; 23 | $this->address = $shippingAddress; 24 | $this->billingAddress = $billingAddress; 25 | } 26 | 27 | public function orderToken(): string 28 | { 29 | return $this->orderToken; 30 | } 31 | 32 | public function shippingAddress(): Address 33 | { 34 | return $this->address; 35 | } 36 | 37 | public function billingAddress(): Address 38 | { 39 | return $this->billingAddress; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Command/Cart/ChangeItemQuantity.php: -------------------------------------------------------------------------------- 1 | orderToken = $orderToken; 25 | $this->itemIdentifier = $itemIdentifier; 26 | $this->quantity = $quantity; 27 | } 28 | 29 | public function orderToken(): string 30 | { 31 | return $this->orderToken; 32 | } 33 | 34 | public function itemIdentifier() 35 | { 36 | return $this->itemIdentifier; 37 | } 38 | 39 | public function quantity(): int 40 | { 41 | return $this->quantity; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Command/Cart/ChoosePaymentMethod.php: -------------------------------------------------------------------------------- 1 | orderToken = $orderToken; 21 | $this->paymentIdentifier = $paymentIdentifier; 22 | $this->paymentMethod = $paymentMethod; 23 | } 24 | 25 | public function orderToken(): string 26 | { 27 | return $this->orderToken; 28 | } 29 | 30 | public function paymentIdentifier() 31 | { 32 | return $this->paymentIdentifier; 33 | } 34 | 35 | public function paymentMethod(): string 36 | { 37 | return $this->paymentMethod; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Command/Cart/ChooseShippingMethod.php: -------------------------------------------------------------------------------- 1 | orderToken = $orderToken; 21 | $this->shipmentIdentifier = $shipmentIdentifier; 22 | $this->shippingMethod = $shippingMethod; 23 | } 24 | 25 | public function orderToken(): string 26 | { 27 | return $this->orderToken; 28 | } 29 | 30 | public function shipmentIdentifier() 31 | { 32 | return $this->shipmentIdentifier; 33 | } 34 | 35 | public function shippingMethod(): string 36 | { 37 | return $this->shippingMethod; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Command/Cart/CompleteOrder.php: -------------------------------------------------------------------------------- 1 | orderToken = $orderToken; 21 | $this->email = $email; 22 | $this->notes = $notes; 23 | } 24 | 25 | public function orderToken(): string 26 | { 27 | return $this->orderToken; 28 | } 29 | 30 | public function email(): string 31 | { 32 | return $this->email; 33 | } 34 | 35 | public function notes(): ?string 36 | { 37 | return $this->notes; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Command/Cart/DropCart.php: -------------------------------------------------------------------------------- 1 | orderToken = $orderToken; 15 | } 16 | 17 | public function orderToken(): string 18 | { 19 | return $this->orderToken; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Command/Cart/PickupCart.php: -------------------------------------------------------------------------------- 1 | orderToken = $orderToken; 18 | $this->channelCode = $channelCode; 19 | } 20 | 21 | public function orderToken(): string 22 | { 23 | return $this->orderToken; 24 | } 25 | 26 | public function channelCode(): string 27 | { 28 | return $this->channelCode; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Command/Cart/PutSimpleItemToCart.php: -------------------------------------------------------------------------------- 1 | orderToken = $orderToken; 25 | $this->product = $product; 26 | $this->quantity = $quantity; 27 | } 28 | 29 | public function orderToken(): string 30 | { 31 | return $this->orderToken; 32 | } 33 | 34 | public function product(): string 35 | { 36 | return $this->product; 37 | } 38 | 39 | public function quantity(): int 40 | { 41 | return $this->quantity; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Command/Cart/RemoveCoupon.php: -------------------------------------------------------------------------------- 1 | orderToken = $orderToken; 15 | } 16 | 17 | public function orderToken(): string 18 | { 19 | return $this->orderToken; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Command/Cart/RemoveItemFromCart.php: -------------------------------------------------------------------------------- 1 | orderToken = $orderToken; 18 | $this->itemIdentifier = $itemIdentifier; 19 | } 20 | 21 | public function orderToken(): string 22 | { 23 | return $this->orderToken; 24 | } 25 | 26 | public function itemIdentifier() 27 | { 28 | return $this->itemIdentifier; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Command/Customer/GenerateResetPasswordToken.php: -------------------------------------------------------------------------------- 1 | email = $email; 15 | } 16 | 17 | public function email(): string 18 | { 19 | return $this->email; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Command/Customer/GenerateVerificationToken.php: -------------------------------------------------------------------------------- 1 | email = $email; 15 | } 16 | 17 | public function email(): string 18 | { 19 | return $this->email; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Command/Customer/SendResetPasswordToken.php: -------------------------------------------------------------------------------- 1 | email = $email; 18 | $this->channelCode = $channelCode; 19 | } 20 | 21 | public function email(): string 22 | { 23 | return $this->email; 24 | } 25 | 26 | public function channelCode(): string 27 | { 28 | return $this->channelCode; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Command/Customer/SendVerificationToken.php: -------------------------------------------------------------------------------- 1 | email = $email; 18 | $this->channelCode = $channelCode; 19 | } 20 | 21 | public function email(): string 22 | { 23 | return $this->email; 24 | } 25 | 26 | public function channelCode(): string 27 | { 28 | return $this->channelCode; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Command/Customer/VerifyAccount.php: -------------------------------------------------------------------------------- 1 | token = $token; 15 | } 16 | 17 | public function token(): string 18 | { 19 | return $this->token; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/DependencyInjection/ShopApiExtension.php: -------------------------------------------------------------------------------- 1 | processConfiguration($this->getConfiguration([], $container), $config); 18 | $loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); 19 | 20 | foreach ($config['view_classes'] as $view => $class) { 21 | $container->setParameter(sprintf('sylius.shop_api.view.%s.class', $view), $class); 22 | } 23 | 24 | $container->setParameter('sylius.shop_api.included_attributes', $config['included_attributes']); 25 | 26 | $loader->load('services.xml'); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Event/CustomerRegistered.php: -------------------------------------------------------------------------------- 1 | email = $email; 26 | $this->firstName = $firstName; 27 | $this->lastName = $lastName; 28 | $this->channelCode = $channelCode; 29 | } 30 | 31 | public function email(): string 32 | { 33 | return $this->email; 34 | } 35 | 36 | public function firstName(): string 37 | { 38 | return $this->firstName; 39 | } 40 | 41 | public function lastName(): string 42 | { 43 | return $this->lastName; 44 | } 45 | 46 | public function channelCode(): string 47 | { 48 | return $this->channelCode; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/EventListener/RequestLocaleSetter.php: -------------------------------------------------------------------------------- 1 | localeProvider = $localeProvider; 18 | } 19 | 20 | public function onKernelRequest(GetResponseEvent $event) 21 | { 22 | $request = $event->getRequest(); 23 | 24 | $request->setDefaultLocale($this->localeProvider->getDefaultLocaleCode()); 25 | 26 | $localeCode = $request->get('locale'); 27 | if (null === $localeCode) { 28 | return; 29 | } 30 | 31 | $availableLocalesCodes = $this->localeProvider->getAvailableLocalesCodes(); 32 | if (in_array($localeCode, $availableLocalesCodes, true)) { 33 | $request->setLocale($localeCode); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Exception/ChannelNotFoundException.php: -------------------------------------------------------------------------------- 1 | totalsViewClass = $totalsViewClass; 18 | } 19 | 20 | /** {@inheritdoc} */ 21 | public function create(OrderInterface $cart): TotalsView 22 | { 23 | /** @var TotalsView $totalsView */ 24 | $totalsView = new $this->totalsViewClass(); 25 | 26 | $totalsView->promotion = $cart->getOrderPromotionTotal(); 27 | $totalsView->total = $cart->getTotal(); 28 | $totalsView->items = $cart->getItemsTotal(); 29 | $totalsView->shipping = $cart->getShippingTotal(); 30 | $totalsView->taxes = $cart->getTaxTotal(); 31 | 32 | return $totalsView; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Factory/Cart/TotalViewFactoryInterface.php: -------------------------------------------------------------------------------- 1 | priceViewClass = $priceViewClass; 17 | } 18 | 19 | /** {@inheritdoc} */ 20 | public function create(int $price, string $currency): PriceView 21 | { 22 | /** @var PriceView $priceView */ 23 | $priceView = new $this->priceViewClass(); 24 | $priceView->current = $price; 25 | $priceView->currency = $currency; 26 | 27 | return $priceView; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Factory/PriceViewFactoryInterface.php: -------------------------------------------------------------------------------- 1 | productReviewViewClass = $productReviewViewClass; 18 | } 19 | 20 | /** {@inheritdoc} */ 21 | public function create(ProductReview $productReview): ProductReviewView 22 | { 23 | /** @var ProductReviewView $productReviewView */ 24 | $productReviewView = new $this->productReviewViewClass(); 25 | 26 | $productReviewView->author = $productReview->getAuthor()->getEmail(); 27 | $productReviewView->comment = $productReview->getComment(); 28 | $productReviewView->rating = $productReview->getRating(); 29 | $productReviewView->title = $productReview->getTitle(); 30 | 31 | return $productReviewView; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Factory/Product/ProductReviewViewFactoryInterface.php: -------------------------------------------------------------------------------- 1 | imageViewClass = $imageViewClass; 18 | } 19 | 20 | public function create(ImageInterface $image): ImageView 21 | { 22 | /** @var ImageView $imageView */ 23 | $imageView = new $this->imageViewClass(); 24 | $imageView->code = $image->getType(); 25 | $imageView->path = $image->getPath(); 26 | 27 | return $imageView; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Factory/Taxon/ImageViewFactoryInterface.php: -------------------------------------------------------------------------------- 1 | getTranslation($locale)->getSlug(); 14 | 15 | $taxon = $product->getMainTaxon(); 16 | 17 | return $taxon ? sprintf('%s/%s', $taxon->getTranslation($locale)->getSlug(), $breadcrumb) : $breadcrumb; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Generator/ProductBreadcrumbGeneratorInterface.php: -------------------------------------------------------------------------------- 1 | addressRepository = $addressRepository; 23 | $this->orderRepository = $orderRepository; 24 | } 25 | 26 | public function __invoke(RemoveAddress $removeAddress): void 27 | { 28 | /** @var AddressInterface $address */ 29 | $address = $this->addressRepository->findOneBy(['id' => $removeAddress->id()]); 30 | 31 | $this->addressRepository->remove($address); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Handler/Cart/DropCartHandler.php: -------------------------------------------------------------------------------- 1 | cartRepository = $cartRepository; 20 | } 21 | 22 | public function __invoke(DropCart $dropCart): void 23 | { 24 | /** @var OrderInterface $cart */ 25 | $cart = $this->cartRepository->findOneBy(['tokenValue' => $dropCart->orderToken()]); 26 | 27 | Assert::notNull($cart, sprintf('Order with %s token has not been found.', $dropCart->orderToken())); 28 | Assert::same(OrderInterface::STATE_CART, $cart->getState()); 29 | 30 | $this->cartRepository->remove($cart); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Handler/Customer/VerifyAccountHandler.php: -------------------------------------------------------------------------------- 1 | userRepository = $userRepository; 20 | } 21 | 22 | public function __invoke(VerifyAccount $resendVerificationToken): void 23 | { 24 | /** @var ShopUserInterface $user */ 25 | $user = $this->userRepository->findOneBy(['emailVerificationToken' => $resendVerificationToken->token()]); 26 | 27 | Assert::notNull($user, sprintf('User has not been found.')); 28 | 29 | $user->setVerifiedAt(new \DateTime()); 30 | $user->setEmailVerificationToken(null); 31 | $user->enable(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Http/RequestBasedLocaleProviderInterface.php: -------------------------------------------------------------------------------- 1 | customerProvider = $customerProvider; 17 | } 18 | 19 | public function provide(string $email): ProductReviewerInterface 20 | { 21 | return $this->customerProvider->provide($email); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Provider/ProductReviewerProviderInterface.php: -------------------------------------------------------------------------------- 1 | id = $request->attributes->get('id'); 21 | $this->userEmail = $userEmail; 22 | } 23 | 24 | public function getCommand(): RemoveAddress 25 | { 26 | return new RemoveAddress($this->id, $this->userEmail); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Request/AddressBook/SetDefaultAddressRequest.php: -------------------------------------------------------------------------------- 1 | id = $request->attributes->get('id'); 21 | $this->userEmail = $userEmail; 22 | } 23 | 24 | public function getCommand(): SetDefaultAddress 25 | { 26 | return new SetDefaultAddress($this->id, $this->userEmail); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Request/Cart/AddCouponRequest.php: -------------------------------------------------------------------------------- 1 | token = $request->attributes->get('token'); 21 | $this->coupon = $request->request->get('coupon'); 22 | } 23 | 24 | public function getCommand(): AddCoupon 25 | { 26 | return new AddCoupon($this->token, $this->coupon); 27 | } 28 | 29 | public function getToken(): ?string 30 | { 31 | return $this->token; 32 | } 33 | 34 | public function getCoupon(): ?string 35 | { 36 | return $this->coupon; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Request/Cart/ChangeItemQuantityRequest.php: -------------------------------------------------------------------------------- 1 | token = $request->attributes->get('token'); 24 | $this->id = $request->attributes->get('id'); 25 | $this->quantity = $request->request->getInt('quantity'); 26 | } 27 | 28 | public function getCommand(): ChangeItemQuantity 29 | { 30 | return new ChangeItemQuantity($this->token, $this->id, $this->quantity); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Request/Cart/DropCartRequest.php: -------------------------------------------------------------------------------- 1 | token = $request->attributes->get('token'); 18 | } 19 | 20 | public function getCommand(): DropCart 21 | { 22 | return new DropCart($this->token); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Request/Cart/EstimateShippingCostRequest.php: -------------------------------------------------------------------------------- 1 | cartToken = $request->attributes->get('token'); 23 | $this->countryCode = $request->query->get('countryCode'); 24 | $this->provinceCode = $request->query->get('provinceCode'); 25 | } 26 | 27 | public function cartToken(): string 28 | { 29 | return $this->cartToken; 30 | } 31 | 32 | public function countryCode(): string 33 | { 34 | return $this->countryCode; 35 | } 36 | 37 | public function provinceCode(): ?string 38 | { 39 | return $this->provinceCode; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/Request/Cart/PickupCartRequest.php: -------------------------------------------------------------------------------- 1 | token = Uuid::uuid4()->toString(); 22 | $this->channel = $request->attributes->get('channelCode'); 23 | } 24 | 25 | public function getCommand(): PickupCart 26 | { 27 | return new PickupCart($this->token, $this->channel); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Request/Cart/RemoveCouponRequest.php: -------------------------------------------------------------------------------- 1 | token = $request->attributes->get('token'); 18 | } 19 | 20 | public function getCommand(): RemoveCoupon 21 | { 22 | return new RemoveCoupon($this->token); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Request/Cart/RemoveItemFromCartRequest.php: -------------------------------------------------------------------------------- 1 | token = $request->attributes->get('token'); 21 | $this->id = $request->attributes->get('id'); 22 | } 23 | 24 | public function getCommand(): RemoveItemFromCart 25 | { 26 | return new RemoveItemFromCart($this->token, $this->id); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Request/Customer/ResendVerificationTokenRequest.php: -------------------------------------------------------------------------------- 1 | email = $request->request->get('email'); 21 | $this->channelCode = $request->attributes->get('channelCode'); 22 | } 23 | 24 | public function getCommand(): SendVerificationToken 25 | { 26 | return new SendVerificationToken($this->email, $this->channelCode); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Request/Customer/VerifyAccountRequest.php: -------------------------------------------------------------------------------- 1 | token = $request->query->get('token'); 18 | } 19 | 20 | public function getCommand(): VerifyAccount 21 | { 22 | return new VerifyAccount($this->token); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Resources/config/app/config.yml: -------------------------------------------------------------------------------- 1 | jms_serializer: 2 | metadata: 3 | directories: 4 | sylius-shop-api-taxon: 5 | namespace_prefix: "Sylius\\ShopApiPlugin\\View\\Taxon" 6 | path: "@ShopApiPlugin/Resources/config/serializer/Taxon" 7 | sylius-shop-api-product: 8 | namespace_prefix: "Sylius\\ShopApiPlugin\\View\\Product" 9 | path: "@ShopApiPlugin/Resources/config/serializer/Product" 10 | 11 | framework: 12 | messenger: 13 | buses: 14 | sylius_shop_api_plugin.command_bus: 15 | middleware: 16 | - doctrine_transaction 17 | 18 | sylius_customer: 19 | resources: 20 | customer: 21 | classes: 22 | controller: Sylius\ShopApiPlugin\Controller\Customer\CustomerController 23 | -------------------------------------------------------------------------------- /src/Resources/config/app/sylius_mailer.yml: -------------------------------------------------------------------------------- 1 | # This file is part of the Sylius package. 2 | # (c) Paweł Jędrzejewski 3 | 4 | sylius_mailer: 5 | emails: 6 | api_verification_token: 7 | subject: sylius.emails.user.verification_token.subject 8 | template: "ShopApiPlugin:Email:verification.html.twig" 9 | api_reset_password_token: 10 | subject: sylius.emails.user.reset_password_token.subject 11 | template: "ShopApiPlugin:Email:passwordReset.html.twig" 12 | -------------------------------------------------------------------------------- /src/Resources/config/routing/address_book.yml: -------------------------------------------------------------------------------- 1 | sylius_shop_api_show_address_book: 2 | path: /address-book 3 | methods: [GET] 4 | defaults: 5 | _controller: sylius.shop_api_plugin.controller.address_book.show_address_book_action 6 | 7 | sylius_shop_api_create_address_book_entry: 8 | path: /address-book 9 | methods: [POST] 10 | defaults: 11 | _controller: sylius.shop_api_plugin.controller.address_book.create_address_action 12 | 13 | sylius_shop_api_remove_address_book_entry: 14 | path: /address-book/{id} 15 | methods: [DELETE] 16 | defaults: 17 | _controller: sylius.shop_api_plugin.controller.address_book.remove_address_action 18 | 19 | sylius_shop_api_set_default_address: 20 | path: /address-book/{id}/default 21 | methods: [PATCH] 22 | defaults: 23 | _controller: sylius.shop_api_plugin.controller.address_book.set_default_address_action 24 | 25 | sylius_shop_api_update_address_book_entry: 26 | path: /address-book/{id} 27 | methods: [PUT] 28 | defaults: 29 | _controller: sylius.shop_api_plugin.controller.address_book.update_address_action 30 | -------------------------------------------------------------------------------- /src/Resources/config/routing/customer.yml: -------------------------------------------------------------------------------- 1 | sylius_shop_api_me: 2 | path: /me 3 | methods: [GET] 4 | defaults: 5 | _controller: sylius.shop_api_plugin.controller.customer.logged_in_customer_details_action 6 | 7 | sylius_shop_api_update_customer: 8 | path: /me 9 | methods: [PUT] 10 | defaults: 11 | _controller: sylius.shop_api_plugin.controller.customer.update_customer_action 12 | -------------------------------------------------------------------------------- /src/Resources/config/routing/order.yml: -------------------------------------------------------------------------------- 1 | sylius_shop_api_orders_list: 2 | path: /orders 3 | methods: [GET] 4 | defaults: 5 | _controller: sylius.shop_api_plugin.controller.order.show_orders_list_action 6 | 7 | sylius_shop_api_order_details: 8 | path: /orders/{tokenValue} 9 | methods: [GET] 10 | defaults: 11 | _controller: sylius.shop_api_plugin.controller.order.show_order_details_action 12 | -------------------------------------------------------------------------------- /src/Resources/config/routing/productByCode.yml: -------------------------------------------------------------------------------- 1 | sylius_shop_api_product_show_reviews_by_code: 2 | path: /products/by-code/{code}/reviews 3 | methods: [GET] 4 | defaults: 5 | _controller: sylius.shop_api_plugin.controller.product.show_product_reviews_by_code_action 6 | 7 | sylius_shop_api_add_product_review_by_code: 8 | path: /products/by-code/{code}/reviews 9 | methods: [POST] 10 | defaults: 11 | _controller: sylius.shop_api_plugin.controller.product.add_review_by_code_action 12 | 13 | sylius_shop_api_product_show_details_by_code: 14 | path: /products/by-code/{code} 15 | methods: [GET] 16 | defaults: 17 | _controller: sylius.shop_api_plugin.controller.product.show_product_details_by_code_action 18 | 19 | sylius_shop_api_product_show_catalog_by_code: 20 | path: /taxon-products/by-code/{taxonCode} 21 | methods: [GET] 22 | defaults: 23 | _controller: sylius.shop_api_plugin.controller.product.show_product_catalog_by_taxon_code_action 24 | -------------------------------------------------------------------------------- /src/Resources/config/routing/productBySlug.yml: -------------------------------------------------------------------------------- 1 | sylius_shop_api_product_show_reviews_by_slug: 2 | path: /products/by-slug/{slug}/reviews 3 | methods: [GET] 4 | defaults: 5 | _controller: sylius.shop_api_plugin.controller.product.show_product_reviews_by_slug_action 6 | requirements: 7 | slug: .+ 8 | 9 | sylius_shop_api_add_product_review_by_slug: 10 | path: /products/by-slug/{slug}/reviews 11 | methods: [POST] 12 | defaults: 13 | _controller: sylius.shop_api_plugin.controller.product.add_review_by_slug_action 14 | requirements: 15 | slug: .+ 16 | 17 | sylius_shop_api_product_show_details_by_slug: 18 | path: /products/by-slug/{slug} 19 | methods: [GET] 20 | defaults: 21 | _controller: sylius.shop_api_plugin.controller.product.show_product_details_by_slug_action 22 | requirements: 23 | slug: .+ 24 | 25 | sylius_shop_api_product_show_catalog_by_slug: 26 | path: /taxon-products/by-slug/{taxonSlug} 27 | methods: [GET] 28 | defaults: 29 | _controller: sylius.shop_api_plugin.controller.product.show_product_catalog_by_taxon_slug_action 30 | requirements: 31 | taxonSlug: .+ 32 | -------------------------------------------------------------------------------- /src/Resources/config/routing/productList.yml: -------------------------------------------------------------------------------- 1 | sylius_shop_api_product_show_latest: 2 | path: /product-latest/ 3 | methods: [GET] 4 | defaults: 5 | _controller: sylius.shop_api_plugin.controller.product.show_latest_product_action 6 | -------------------------------------------------------------------------------- /src/Resources/config/routing/register.yml: -------------------------------------------------------------------------------- 1 | sylius_shop_api_register: 2 | path: /register 3 | methods: [POST] 4 | defaults: 5 | _controller: sylius.shop_api_plugin.controller.customer.register_customer_action 6 | 7 | sylius_shop_api_resend_verification_token: 8 | path: /resend-verification-link 9 | methods: [POST] 10 | defaults: 11 | _controller: sylius.shop_api_plugin.controller.customer.resend_verification_token_action 12 | 13 | sylius_shop_api_user_verification: 14 | path: /verify-account 15 | methods: [GET] 16 | defaults: 17 | _controller: sylius.shop_api_plugin.controller.customer.verify_account_action 18 | 19 | sylius_shop_api_reset_password: 20 | path: /request-password-reset 21 | methods: [PUT] 22 | defaults: 23 | _controller: sylius.shop_api_plugin.controller.customer.request_password_resetting_action 24 | 25 | sylius_shop_api_password_reset: 26 | path: /password-reset/{token} 27 | methods: [PUT] 28 | defaults: 29 | _controller: sylius.controller.shop_user:resetPasswordAction 30 | -------------------------------------------------------------------------------- /src/Resources/config/routing/taxon.yml: -------------------------------------------------------------------------------- 1 | sylius_shop_api_taxon_show_details: 2 | path: /taxons/{code} 3 | methods: [GET] 4 | defaults: 5 | _controller: sylius.shop_api_plugin.controller.taxon.show_taxon_details_action 6 | 7 | sylius_shop_api_taxon_show_tree: 8 | path: /taxons/ 9 | methods: [GET] 10 | defaults: 11 | _controller: sylius.shop_api_plugin.controller.taxon.show_taxon_tree_action 12 | -------------------------------------------------------------------------------- /src/Resources/config/serializer/Product/PageView.yml: -------------------------------------------------------------------------------- 1 | Sylius\ShopApiPlugin\View\Product\PageView: 2 | exclusion_policy: ALL 3 | xml_root_name: page_view 4 | properties: 5 | page: 6 | expose: true 7 | type: integer 8 | limit: 9 | expose: true 10 | type: integer 11 | pages: 12 | expose: true 13 | type: integer 14 | total: 15 | expose: true 16 | type: integer 17 | links: 18 | expose: true 19 | serialized_name: _links 20 | items: 21 | expose: true 22 | type: array 23 | -------------------------------------------------------------------------------- /src/Resources/config/serializer/Product/ProductVariantView.yml: -------------------------------------------------------------------------------- 1 | Sylius\ShopApiPlugin\View\Product\ProductVariantView: 2 | exclusion_policy: ALL 3 | xml_root_name: product_variant_view 4 | properties: 5 | code: 6 | expose: true 7 | type: string 8 | name: 9 | expose: true 10 | type: string 11 | axis: 12 | expose: true 13 | type: array 14 | nameAxis: 15 | expose: true 16 | type: array 17 | price: 18 | expose: true 19 | type: Sylius\ShopApiPlugin\View\PriceView 20 | images: 21 | expose: true 22 | type: array 23 | -------------------------------------------------------------------------------- /src/Resources/config/serializer/Taxon/ImageView.yml: -------------------------------------------------------------------------------- 1 | Sylius\ShopApiPlugin\View\Taxon\ImageView: 2 | exclusion_policy: ALL 3 | xml_root_name: image_view 4 | properties: 5 | code: 6 | expose: true 7 | type: string 8 | path: 9 | expose: true 10 | type: string 11 | -------------------------------------------------------------------------------- /src/Resources/config/services/controllers.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/Resources/config/services/factories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 | %sylius.shop_api.view.price.class% 15 | 16 | 17 | 19 | %sylius.shop_api.view.validation_error.class% 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/Resources/config/services/factories/address_book.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 11 | %sylius.shop_api.view.address_book.class% 12 | 13 | 14 | 16 | %sylius.shop_api.view.address.class% 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/Resources/config/services/factories/customer.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 9 | %sylius.shop_api.view.customer.class% 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/Resources/config/services/handlers.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/Resources/config/services/http.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/Resources/config/services/mapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/Resources/config/services/queries.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/Resources/config/services/repositories/cart.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/Resources/config/services/repositories/order.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/Resources/config/services/shipping.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/Resources/config/services/validators.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/Resources/config/services/validators/address.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/Resources/config/services/validators/customer.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/Resources/config/validation/address_book/RemoveAddressRequest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/Resources/config/validation/address_book/SetDefaultAddressRequest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/Resources/config/validation/cart/DropCartRequest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/Resources/config/validation/cart/RemoveCouponRequest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/Resources/config/validation/customer/ResendVerificationTokenRequest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/Resources/translations/validators.de.yml: -------------------------------------------------------------------------------- 1 | sylius: 2 | shop_api: 3 | cart: 4 | not_exists: Warenkorb existiert nicht. 5 | -------------------------------------------------------------------------------- /src/Resources/translations/validators.en.yml: -------------------------------------------------------------------------------- 1 | sylius: 2 | shop_api: 3 | cart: 4 | not_exists: Cart does not exists. 5 | email: 6 | not_blank: Please enter your email. 7 | invalid: This email is invalid. 8 | unique: This email is already used. 9 | password: 10 | not_blank: Please enter your password. 11 | first_name: 12 | not_blank: Please enter your first name. 13 | last_name: 14 | not_blank: Please enter your last name. 15 | address_id: 16 | not_null: Please provide address id 17 | address: 18 | not_exists: Address doesn't exist 19 | country: 20 | not_exists: The country does not exist 21 | -------------------------------------------------------------------------------- /src/Resources/views/Email/passwordReset.html.twig: -------------------------------------------------------------------------------- 1 | {% block subject %} 2 | Password reset 3 | {% endblock %} 4 | 5 | {% block body %} 6 | {% set url = url('sylius_shop_api_password_reset', {'channelCode': channelCode, 'token': user.passwordResetToken}) %} 7 | {% autoescape %} 8 |

Hello {{ user.username }}

9 | 10 | To reset your password - please visit {{ url|raw }} 11 |

12 | Regards, the Team. 13 | {% endautoescape %} 14 | {% endblock %} 15 | -------------------------------------------------------------------------------- /src/Resources/views/Email/verification.html.twig: -------------------------------------------------------------------------------- 1 | {% block subject %} 2 | Email address verification 3 | {% endblock %} 4 | 5 | {% block body %} 6 | {% set url = url('sylius_shop_api_user_verification', {'channelCode': channelCode, 'token': user.emailVerificationToken}) %} 7 | {% autoescape %} 8 | To verify your email address - please visit {{ url|raw }} 9 | {% endautoescape %} 10 | {% endblock %} 11 | -------------------------------------------------------------------------------- /src/Shipping/ShippingCost.php: -------------------------------------------------------------------------------- 1 | price = $price; 18 | $this->currency = $currency; 19 | } 20 | 21 | public function price(): int 22 | { 23 | return $this->price; 24 | } 25 | 26 | public function currency(): string 27 | { 28 | return $this->currency; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Shipping/ShippingCostEstimatorInterface.php: -------------------------------------------------------------------------------- 1 | countryRepository = $countryRepository; 19 | } 20 | 21 | public function validate($code, Constraint $constraint) 22 | { 23 | $country = $this->countryRepository->findOneBy(['code' => $code]); 24 | 25 | if ($country === null) { 26 | return $this->context->addViolation($constraint->message); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Validator/Cart/CartExistsValidator.php: -------------------------------------------------------------------------------- 1 | orderRepository = $orderRepository; 22 | } 23 | 24 | /** {@inheritdoc} */ 25 | public function validate($token, Constraint $constraint) 26 | { 27 | Assert::isInstanceOf($constraint, CartExists::class); 28 | 29 | if (null === $this->orderRepository->findOneBy(['tokenValue' => $token, 'state' => OrderInterface::STATE_CART])) { 30 | $this->context->addViolation($constraint->message); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Validator/Cart/CartItemExistsValidator.php: -------------------------------------------------------------------------------- 1 | orderItemRepository = $orderItemRepository; 19 | } 20 | 21 | /** {@inheritdoc} */ 22 | public function validate($id, Constraint $constraint) 23 | { 24 | if (null === $this->orderItemRepository->find($id)) { 25 | $this->context->addViolation($constraint->message); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Validator/Cart/TokenIsNotUsedValidator.php: -------------------------------------------------------------------------------- 1 | orderRepository = $orderRepository; 19 | } 20 | 21 | /** {@inheritdoc} */ 22 | public function validate($token, Constraint $constraint) 23 | { 24 | if (null !== $this->orderRepository->findOneBy(['tokenValue' => $token])) { 25 | $this->context->addViolation($constraint->message); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Validator/ChannelExistsValidator.php: -------------------------------------------------------------------------------- 1 | channelRepository = $channelRepository; 19 | } 20 | 21 | /** {@inheritdoc} */ 22 | public function validate($token, Constraint $constraint) 23 | { 24 | if (null === $token || null === $this->channelRepository->findOneByCode($token)) { 25 | $this->context->addViolation($constraint->message); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Validator/Constraints/AddressExists.php: -------------------------------------------------------------------------------- 1 | userRepository = $userRepository; 19 | } 20 | 21 | public function validate($email, Constraint $constraint) 22 | { 23 | if (null !== $email && null !== $this->userRepository->findOneByEmail($email)) { 24 | $this->context->addViolation($constraint->message); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Validator/Customer/ShopUserExistsValidator.php: -------------------------------------------------------------------------------- 1 | userRepository = $userRepository; 19 | } 20 | 21 | public function validate($email, Constraint $constraint) 22 | { 23 | if (null === $email || null === $this->userRepository->findOneByEmail($email)) { 24 | $this->context->addViolation($constraint->message); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Validator/Product/ConfigurableProductValidator.php: -------------------------------------------------------------------------------- 1 | productRepository = $productRepository; 19 | } 20 | 21 | /** {@inheritdoc} */ 22 | public function validate($productCode, Constraint $constraint) 23 | { 24 | if (null === $productCode) { 25 | return; 26 | } 27 | 28 | $product = $this->productRepository->findOneByCode($productCode); 29 | 30 | if (null === $product || $product->isConfigurable()) { 31 | return; 32 | } 33 | 34 | $this->context->addViolation($constraint->message); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Validator/Product/ProductExistsValidator.php: -------------------------------------------------------------------------------- 1 | productRepository = $productRepository; 19 | } 20 | 21 | /** {@inheritdoc} */ 22 | public function validate($productCode, Constraint $constraint) 23 | { 24 | if (null === $productCode || null === $this->productRepository->findOneByCode($productCode)) { 25 | $this->context->addViolation($constraint->message); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Validator/Product/ProductVariantExistsValidator.php: -------------------------------------------------------------------------------- 1 | productVariantRepository = $productVariantRepository; 19 | } 20 | 21 | /** {@inheritdoc} */ 22 | public function validate($productVariantCode, Constraint $constraint) 23 | { 24 | $product = $this->productVariantRepository->findOneBy(['code' => $productVariantCode]); 25 | 26 | if (null === $product) { 27 | $this->context->addViolation($constraint->message); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Validator/Product/SimpleProductValidator.php: -------------------------------------------------------------------------------- 1 | productRepository = $productRepository; 19 | } 20 | 21 | /** {@inheritdoc} */ 22 | public function validate($productCode, Constraint $constraint) 23 | { 24 | if (null === $productCode) { 25 | return; 26 | } 27 | 28 | $product = $this->productRepository->findOneByCode($productCode); 29 | 30 | if (null === $product || $product->isSimple()) { 31 | return; 32 | } 33 | 34 | $this->context->addViolation($constraint->message); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/View/AddressBook/AddressBookView.php: -------------------------------------------------------------------------------- 1 | amount = new PriceView(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/View/Cart/EstimatedShippingCostView.php: -------------------------------------------------------------------------------- 1 | method = new PaymentMethodView(); 23 | $this->price = new PriceView(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/View/Cart/ShippingMethodView.php: -------------------------------------------------------------------------------- 1 | price = new PriceView(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/View/Cart/TotalsView.php: -------------------------------------------------------------------------------- 1 | method = new ShippingMethodView(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/View/Customer/CustomerView.php: -------------------------------------------------------------------------------- 1 | product = new ProductView(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/View/PriceView.php: -------------------------------------------------------------------------------- 1 | links = new PageLinksView(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/View/Product/ProductAttributeValueView.php: -------------------------------------------------------------------------------- 1 | price = new PriceView(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/View/Product/ProductView.php: -------------------------------------------------------------------------------- 1 | taxons = new ProductTaxonView(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/View/Product/VariantOptionValueView.php: -------------------------------------------------------------------------------- 1 | value = new VariantOptionValueView(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/View/Taxon/ImageView.php: -------------------------------------------------------------------------------- 1 | 4 | RewriteEngine On 5 | 6 | RewriteCond %{HTTP:Authorization} ^(.*) 7 | RewriteRule .* - [e=HTTP_AUTHORIZATION:%1] 8 | 9 | RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$ 10 | RewriteRule ^(.*) - [E=BASE:%1] 11 | 12 | RewriteCond %{ENV:REDIRECT_STATUS} ^$ 13 | RewriteRule ^index\.php(/(.*)|$) %{ENV:BASE}/$2 [R=301,L] 14 | 15 | RewriteCond %{REQUEST_FILENAME} -f 16 | RewriteRule .? - [L] 17 | 18 | RewriteRule .? %{ENV:BASE}/index.php [L] 19 | 20 | 21 | 22 | 23 | RedirectMatch 302 ^/$ /index.php/ 24 | 25 | 26 | -------------------------------------------------------------------------------- /tests/Application/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dunglas/ShopApiPlugin/4e952c027532df71068af0b53946937fd16b2276/tests/Application/public/favicon.ico -------------------------------------------------------------------------------- /tests/Application/public/media/image/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dunglas/ShopApiPlugin/4e952c027532df71068af0b53946937fd16b2276/tests/Application/public/media/image/.gitignore -------------------------------------------------------------------------------- /tests/Application/public/robots.txt: -------------------------------------------------------------------------------- 1 | # www.robotstxt.org/ 2 | # www.google.com/support/webmasters/bin/answer.py?hl=en&answer=156449 3 | 4 | User-agent: * 5 | -------------------------------------------------------------------------------- /tests/Application/templates/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dunglas/ShopApiPlugin/4e952c027532df71068af0b53946937fd16b2276/tests/Application/templates/.gitignore -------------------------------------------------------------------------------- /tests/Application/translations/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dunglas/ShopApiPlugin/4e952c027532df71068af0b53946937fd16b2276/tests/Application/translations/.gitignore -------------------------------------------------------------------------------- /tests/Controller/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dunglas/ShopApiPlugin/4e952c027532df71068af0b53946937fd16b2276/tests/Controller/.gitkeep -------------------------------------------------------------------------------- /tests/Controller/JsonApiTestCase.php: -------------------------------------------------------------------------------- 1 | 'application/json', 'ACCEPT' => 'application/json']; 10 | 11 | public function __construct(?string $name = null, array $data = [], string $dataName = '') 12 | { 13 | parent::__construct($name, $data, $dataName); 14 | $this->dataFixturesPath = __DIR__ . '/../DataFixtures/ORM'; 15 | $this->expectedResponsesPath = __DIR__ . '/../Responses/Expected'; 16 | } 17 | 18 | protected function get($id) 19 | { 20 | if (property_exists(static::class, 'container')) { 21 | return static::$container->get($id); 22 | } 23 | 24 | return parent::get($id); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/Controller/Utils/PurgeSpooledMessagesTrait.php: -------------------------------------------------------------------------------- 1 | getContainer()->get('sylius.behat.email_checker'); 20 | 21 | /** @var Filesystem $filesystem */ 22 | $filesystem = $this->getContainer()->get('filesystem'); 23 | 24 | $filesystem->remove($emailChecker->getSpoolDirectory()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/Controller/Utils/ShopUserLoginTrait.php: -------------------------------------------------------------------------------- 1 | client->request('POST', '/shop-api/login_check', [], [], ['CONTENT_TYPE' => 'application/json', 'ACCEPT' => 'application/json'], $data); 27 | Assert::assertSame($this->client->getResponse()->getStatusCode(), Response::HTTP_OK); 28 | $response = json_decode($this->client->getResponse()->getContent(), true); 29 | $this->client->setServerParameter('HTTP_Authorization', sprintf('Bearer %s', $response['token'])); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tests/DataFixtures/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dunglas/ShopApiPlugin/4e952c027532df71068af0b53946937fd16b2276/tests/DataFixtures/.gitkeep -------------------------------------------------------------------------------- /tests/DataFixtures/ORM/channel.yml: -------------------------------------------------------------------------------- 1 | Sylius\Component\Core\Model\Channel: 2 | gb_web_channel: 3 | code: "WEB_GB" 4 | name: "Great Britain Channel" 5 | hostname: "localhost" 6 | description: "Lorem ipsum" 7 | baseCurrency: "@pound" 8 | defaultLocale: "@locale_en_gb" 9 | locales: ["@locale_en_gb", "@locale_de_de"] 10 | color: "black" 11 | enabled: true 12 | taxCalculationStrategy: "order_items_based" 13 | accountVerificationRequired: true 14 | de_web_channel: 15 | code: "WEB_DE" 16 | name: "Deutch Channel" 17 | hostname: "localhost" 18 | description: "Lorem ipsum" 19 | baseCurrency: "@euro" 20 | defaultLocale: "@locale_de_de" 21 | locales: ["@locale_de_de"] 22 | color: "blue" 23 | enabled: true 24 | taxCalculationStrategy: "order_items_based" 25 | accountVerificationRequired: false 26 | 27 | Sylius\Component\Currency\Model\Currency: 28 | pound: 29 | code: GBP 30 | euro: 31 | code: EUR 32 | 33 | Sylius\Component\Locale\Model\Locale: 34 | locale_en_gb: 35 | code: en_GB 36 | locale_de_de: 37 | code: de_DE 38 | -------------------------------------------------------------------------------- /tests/DataFixtures/ORM/country.yml: -------------------------------------------------------------------------------- 1 | Sylius\Component\Addressing\Model\Country: 2 | country_gb: 3 | code: GB 4 | 5 | Sylius\Component\Addressing\Model\Province: 6 | province_gb_scotland: 7 | name: Scotland 8 | code: GB-SCT 9 | country: '@country_gb' 10 | province_gb_wales: 11 | name: Wales 12 | code: GB-WLS 13 | country: '@country_gb' 14 | province_gb_northen_ireland: 15 | name: Northen Ireland 16 | code: GB-NIR 17 | country: '@country_gb' 18 | province_gb_england: 19 | name: England 20 | code: GB-ENG 21 | country: '@country_gb' 22 | -------------------------------------------------------------------------------- /tests/DataFixtures/ORM/customer.yml: -------------------------------------------------------------------------------- 1 | Sylius\Component\Core\Model\ShopUser: 2 | user_oliver: 3 | plainPassword: "123password" 4 | roles: ["ROLE_USER"] 5 | enabled: "true" 6 | customer: "@customer_oliver" 7 | username: "oliver@queen.com" 8 | usernameCanonical: "oliver@queen.com" 9 | 10 | user_hater: 11 | plainPassword: "123password" 12 | roles: ["ROLE_USER"] 13 | enabled: "true" 14 | customer: "@hater" 15 | username: "hater@queen.com" 16 | usernameCanonical: "hater@queen.com" 17 | 18 | Sylius\Component\Core\Model\Customer: 19 | customer_oliver: 20 | firstName: "Oliver" 21 | lastName: "Queen" 22 | email: "oliver@queen.com" 23 | emailCanonical: "oliver@queen.com" 24 | gender: "m" 25 | phoneNumber: "0212115512" 26 | 27 | hater: 28 | firstName: "Slade" 29 | lastName: "Wilson" 30 | email: "hater@queen.com" 31 | emailCanonical: "slade@queen.com" 32 | -------------------------------------------------------------------------------- /tests/DataFixtures/ORM/mug_review.yml: -------------------------------------------------------------------------------- 1 | Sylius\Component\Core\Model\ProductReview: 2 | reviews_{1..20}: 3 | title: "Nice mug" 4 | rating: "" 5 | author: "@customer_oliver" 6 | status: "accepted" 7 | comment: "" 8 | reviewSubject: "@mug" 9 | bad_reviews_{1..5}: 10 | title: "Nice mug" 11 | rating: "" 12 | author: "@hater" 13 | status: "accepted" 14 | comment: "" 15 | reviewSubject: "@mug" 16 | -------------------------------------------------------------------------------- /tests/DataFixtures/ORM/payment.yml: -------------------------------------------------------------------------------- 1 | Sylius\Component\Core\Model\PaymentMethod: 2 | cash_on_delivery: 3 | code: "COD" 4 | enabled: true 5 | gatewayConfig: '@offline' 6 | currentLocale: "en_GB" 7 | channels: ["@gb_web_channel"] 8 | pay_by_check: 9 | code: "PBC" 10 | enabled: true 11 | gatewayConfig: '@offline' 12 | currentLocale: "en_GB" 13 | channels: ["@gb_web_channel"] 14 | 15 | Sylius\Bundle\PayumBundle\Model\GatewayConfig: 16 | offline: 17 | gatewayName: 'Offline' 18 | factoryName: 'offline' 19 | config: [] 20 | 21 | Sylius\Component\Payment\Model\PaymentMethodTranslation: 22 | cash_on_delivery_translation: 23 | name: 'Cash on delivery' 24 | locale: 'en_GB' 25 | description: 26 | instructions: "Please put the money in the bag!" 27 | translatable: "@cash_on_delivery" 28 | pay_by_check_translation: 29 | name: 'Pay by check' 30 | locale: 'en_GB' 31 | description: 32 | instructions: "Please put the money in the bag!" 33 | translatable: "@pay_by_check" 34 | -------------------------------------------------------------------------------- /tests/DataFixtures/ORM/promotion.yml: -------------------------------------------------------------------------------- 1 | Sylius\Component\Core\Model\Promotion: 2 | holiday_promotion: 3 | code: "HOLIDAY_PROMOTION" 4 | name: "Holiday promotion" 5 | channels: ["@gb_web_channel", "@de_web_channel"] 6 | actions: ["@10_percent_order_discount"] 7 | rules: ["@over_50_amount_rule"] 8 | 9 | Sylius\Component\Promotion\Model\PromotionAction: 10 | 10_percent_order_discount: 11 | type: "order_percentage_discount" 12 | promotion: "@holiday_promotion" 13 | configuration: 14 | percentage: 0.1 15 | 16 | Sylius\Component\Promotion\Model\PromotionRule: 17 | over_50_amount_rule: 18 | type: "item_total" 19 | promotion: "@holiday_promotion" 20 | configuration: 21 | WEB_GB: 22 | amount: 5000 23 | WEB_DE: 24 | amount: 5000 25 | -------------------------------------------------------------------------------- /tests/Request/AddCouponRequestTest.php: -------------------------------------------------------------------------------- 1 | 'SUMMER_SALE'], ['token' => 'ORDERTOKEN'])); 20 | 21 | $this->assertEquals($pickupCartRequest->getCommand(), new AddCoupon('ORDERTOKEN', 'SUMMER_SALE')); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/Request/ChangeItemQuantityRequestTest.php: -------------------------------------------------------------------------------- 1 | 5], [ 20 | 'token' => 'ORDERTOKEN', 21 | 'id' => 1, 22 | ])); 23 | 24 | $this->assertEquals(new ChangeItemQuantity('ORDERTOKEN', 1, 5), $changeItemQuantityRequest->getCommand()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/Request/DropCartRequestTest.php: -------------------------------------------------------------------------------- 1 | 'ORDERTOKEN'])); 20 | 21 | $this->assertEquals($pickupCartRequest->getCommand(), new DropCart('ORDERTOKEN')); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/Request/PickupCartRequestTest.php: -------------------------------------------------------------------------------- 1 | 'WEB_GB'])); 17 | 18 | $pickupCartCommand = $pickupCartRequest->getCommand(); 19 | 20 | $this->assertEquals('WEB_GB', $pickupCartCommand->channelCode()); 21 | $this->assertNotNull($pickupCartCommand->orderToken()); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/Request/ResendVerificationTokenRequestTest.php: -------------------------------------------------------------------------------- 1 | 'daffy@the-duck.com'], ['channelCode' => 'WEB_GB'])); 20 | 21 | $this->assertEquals($putSimpleItemToCartRequest->getCommand(), new SendVerificationToken('daffy@the-duck.com', 'WEB_GB')); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/Request/VerifyAccountRequestTest.php: -------------------------------------------------------------------------------- 1 | 'RANDOMSTRINGAFAFAKASNFJAFAJ'], [], [])); 20 | 21 | $this->assertEquals($verifyAccountRequest->getCommand(), new VerifyAccount('RANDOMSTRINGAFAFAKASNFJAFAJ')); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/Responses/Expected/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dunglas/ShopApiPlugin/4e952c027532df71068af0b53946937fd16b2276/tests/Responses/Expected/.gitkeep -------------------------------------------------------------------------------- /tests/Responses/Expected/address_book/add_address_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": @integer@, 3 | "firstName": "Jurica", 4 | "lastName": "Separovic", 5 | "phoneNumber": "091892212", 6 | "city": "Split", 7 | "street": "Kupreska 12", 8 | "countryCode": "GB", 9 | "postcode": "2433", 10 | "default": false 11 | } 12 | -------------------------------------------------------------------------------- /tests/Responses/Expected/address_book/update_address.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "@integer@", 3 | "firstName": "New name", 4 | "lastName": "New lastName", 5 | "countryCode": "GB", 6 | "street": "New street", 7 | "city": "New city", 8 | "postcode": "2000", 9 | "provinceName": "Wales", 10 | "provinceCode": "GB-WLS", 11 | "company": "Locastic", 12 | "phoneNumber": "0918972132", 13 | "default": false 14 | } 15 | -------------------------------------------------------------------------------- /tests/Responses/Expected/address_book/validation_create_address_book_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 400, 3 | "message": "Validation failed", 4 | "errors": { 5 | "firstName": [ 6 | "@string@" 7 | ], 8 | "lastName": [ 9 | "@string@" 10 | ], 11 | "countryCode": [ 12 | "@string@", 13 | "@string@" 14 | ], 15 | "street": [ 16 | "@string@" 17 | ], 18 | "city": [ 19 | "@string@" 20 | ], 21 | "postcode": [ 22 | "@string@" 23 | ] 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tests/Responses/Expected/address_book/validation_create_address_book_with_wrong_country_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 400, 3 | "message": "Validation failed", 4 | "errors": { 5 | "countryCode": [ 6 | "The country does not exist" 7 | ] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/Responses/Expected/address_book/validation_create_address_book_with_wrong_province_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 500, 3 | "message": "Province does not exist." 4 | } 5 | -------------------------------------------------------------------------------- /tests/Responses/Expected/cart/add_multiple_products_to_cart_validation_error_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 400, 3 | "message": "Validation failed", 4 | "errors": [ 5 | { 6 | }, 7 | { 8 | "quantity": [ 9 | "sylius.shop_api.quantity.not_null" 10 | ] 11 | }, 12 | { 13 | "quantity": [ 14 | "sylius.shop_api.quantity.not_null" 15 | ] 16 | } 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /tests/Responses/Expected/cart/cart_after_deleting_an_item.json: -------------------------------------------------------------------------------- 1 | { 2 | "tokenValue": "SDAOSLEFNWU35H3QLI5325", 3 | "channel": "WEB_GB", 4 | "currency": "GBP", 5 | "locale": "en_GB", 6 | "checkoutState": "cart", 7 | "items": [], 8 | "totals": { 9 | "total": 0, 10 | "items": 0, 11 | "taxes": 0, 12 | "shipping": 0, 13 | "promotion": 0 14 | }, 15 | "payments": [], 16 | "shipments": [], 17 | "cartDiscounts": [] 18 | } 19 | -------------------------------------------------------------------------------- /tests/Responses/Expected/cart/cart_and_country_does_not_exist_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 400, 3 | "message": "Validation failed", 4 | "errors": { 5 | "cartToken": [ 6 | "Cart does not exists." 7 | ], 8 | "countryCode": [ 9 | "The country does not exist" 10 | ] 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/Responses/Expected/cart/cart_has_not_been_found_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 404, 3 | "message": "Cart with given id does not exists" 4 | } 5 | -------------------------------------------------------------------------------- /tests/Responses/Expected/cart/cart_item_has_not_been_found_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 400, 3 | "message": "Validation failed", 4 | "errors": { 5 | "id": [ 6 | "sylius.shop_api.cart_item.not_exists" 7 | ] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/Responses/Expected/cart/deprecated_empty_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "tokenValue": "SDAOSLEFNWU35H3QLI5325", 3 | "channel": "WEB_GB", 4 | "currency": "GBP", 5 | "locale": "en_GB", 6 | "checkoutState": "cart", 7 | "items": [], 8 | "totals": { 9 | "total": 0, 10 | "items": 0, 11 | "taxes": 0, 12 | "shipping": 0, 13 | "promotion": 0 14 | }, 15 | "payments": [], 16 | "shipments": [], 17 | "cartDiscounts": [] 18 | } 19 | -------------------------------------------------------------------------------- /tests/Responses/Expected/cart/empty_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "tokenValue": "@string@", 3 | "channel": "WEB_GB", 4 | "currency": "GBP", 5 | "locale": "en_GB", 6 | "checkoutState": "cart", 7 | "items": [], 8 | "totals": { 9 | "total": 0, 10 | "items": 0, 11 | "taxes": 0, 12 | "shipping": 0, 13 | "promotion": 0 14 | }, 15 | "payments": [], 16 | "shipments": [], 17 | "cartDiscounts": [] 18 | } 19 | -------------------------------------------------------------------------------- /tests/Responses/Expected/cart/estimated_shipping_cost_bases_on_country_and_province_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "price": { 3 | "current": 500, 4 | "currency": "GBP" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /tests/Responses/Expected/cart/estimated_shipping_cost_bases_on_country_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "price": { 3 | "current": 1500, 4 | "currency": "GBP" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /tests/Responses/Expected/cart/product_variant_has_not_been_found_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 404, 3 | "message": "Variant not found for given configuration" 4 | } 5 | -------------------------------------------------------------------------------- /tests/Responses/Expected/cart/validation_cart_and_cart_item_not_exist_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 400, 3 | "message": "Validation failed", 4 | "errors": { 5 | "token": [ 6 | "Cart does not exists." 7 | ], 8 | "id": [ 9 | "sylius.shop_api.cart_item.not_exists" 10 | ] 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/Responses/Expected/cart/validation_cart_item_not_exists_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 400, 3 | "message": "Validation failed", 4 | "errors": { 5 | "id": [ 6 | "sylius.shop_api.cart_item.not_exists" 7 | ] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/Responses/Expected/cart/validation_cart_not_exists_in_german_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 400, 3 | "message": "Validation failed", 4 | "errors": { 5 | "token": [ 6 | "Warenkorb existiert nicht." 7 | ] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/Responses/Expected/cart/validation_cart_not_exists_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 400, 3 | "message": "Validation failed", 4 | "errors": { 5 | "token": [ 6 | "Cart does not exists." 7 | ] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/Responses/Expected/cart/validation_channel_not_exists_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 400, 3 | "message": "Validation failed", 4 | "errors": { 5 | "channel": [ 6 | "sylius.shop_api.channel.not_exists" 7 | ] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/Responses/Expected/cart/validation_channel_not_found_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 400, 3 | "message": "Validation failed", 4 | "errors": { 5 | "channel": [ 6 | "sylius.shop_api.channel.not_null", 7 | "sylius.shop_api.channel.not_exists" 8 | ] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/Responses/Expected/cart/validation_coupon_not_found_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 400, 3 | "message": "Validation failed", 4 | "errors": { 5 | "coupon": [ 6 | "sylius.shop_api.coupon.not_valid", 7 | "sylius.shop_api.coupon.not_null" 8 | ] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/Responses/Expected/cart/validation_coupon_not_valid_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 400, 3 | "message": "Validation failed", 4 | "errors": { 5 | "coupon": [ 6 | "sylius.shop_api.coupon.not_valid" 7 | ] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/Responses/Expected/cart/validation_product_not_configurable_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 400, 3 | "message": "Validation failed", 4 | "errors": { 5 | "productCode": [ 6 | "sylius.shop_api.product.configurable" 7 | ] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/Responses/Expected/cart/validation_product_not_defined_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 400, 3 | "message": "Validation failed", 4 | "errors": { 5 | "productCode": [ 6 | "sylius.shop_api.product.not_null", 7 | "sylius.shop_api.product.exists" 8 | ] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/Responses/Expected/cart/validation_product_not_exists_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 400, 3 | "message": "Validation failed", 4 | "errors": { 5 | "productCode": [ 6 | "sylius.shop_api.product.exists" 7 | ] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/Responses/Expected/cart/validation_product_not_simple_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 400, 3 | "message": "Validation failed", 4 | "errors": { 5 | "productCode": [ 6 | "sylius.shop_api.product.simple" 7 | ] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/Responses/Expected/cart/validation_product_variant_not_exists_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 400, 3 | "message": "Validation failed", 4 | "errors": { 5 | "variantCode": [ 6 | "sylius.shop_api.product_variant.exists" 7 | ] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/Responses/Expected/cart/validation_quantity_lower_than_one_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 400, 3 | "message": "Validation failed", 4 | "errors": { 5 | "quantity": [ 6 | "sylius.shop_api.quantity.greater_than_0" 7 | ] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/Responses/Expected/cart/validation_token_already_used_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 400, 3 | "message": "Validation failed", 4 | "errors": { 5 | "token": [ 6 | "sylius.shop_api.token.already_taken" 7 | ] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/Responses/Expected/channel_has_not_been_found_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 404, 3 | "message": "Channel with code SPACE_KLINGON has not been found." 4 | } 5 | -------------------------------------------------------------------------------- /tests/Responses/Expected/checkout/get_available_payment_methods.json: -------------------------------------------------------------------------------- 1 | { 2 | "payments": [ 3 | { 4 | "methods": { 5 | "COD": { 6 | "code": "COD", 7 | "name": "Cash on delivery", 8 | "description": "@string@", 9 | "instructions": "@string@" 10 | }, 11 | "PBC": { 12 | "code": "PBC", 13 | "name": "Pay by check", 14 | "description": "@string@", 15 | "instructions": "@string@" 16 | } 17 | } 18 | } 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /tests/Responses/Expected/checkout/get_available_payment_methods_failed.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 400, 3 | "message": "The payment methods cannot be resolved in the current state of cart!" 4 | } 5 | -------------------------------------------------------------------------------- /tests/Responses/Expected/checkout/get_available_shipping_methods.json: -------------------------------------------------------------------------------- 1 | { 2 | "shipments": [ 3 | { 4 | "methods": { 5 | "DHL": { 6 | "code": "DHL", 7 | "name": "DHL", 8 | "description": "@string@", 9 | "price": { 10 | "current": 1500, 11 | "currency": "GBP" 12 | } 13 | }, 14 | "FED-EX": { 15 | "code": "FED-EX", 16 | "name": "FedEx", 17 | "description": "@string@", 18 | "price": { 19 | "current": 2500, 20 | "currency": "GBP" 21 | } 22 | } 23 | } 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /tests/Responses/Expected/checkout/get_available_shipping_methods_failed.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 400, 3 | "message": "The shipment methods cannot be resolved in the current state of cart!" 4 | } 5 | -------------------------------------------------------------------------------- /tests/Responses/Expected/customer/bad_credentials_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 401, 3 | "message": "Bad credentials" 4 | } 5 | -------------------------------------------------------------------------------- /tests/Responses/Expected/customer/customer_log_in_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "token": "@string@" 3 | } 4 | -------------------------------------------------------------------------------- /tests/Responses/Expected/customer/logged_in_customer_details_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "firstName": "Oliver", 3 | "lastName": "Queen", 4 | "email": "oliver@queen.com", 5 | "gender": "m", 6 | "phoneNumber": "0212115512", 7 | "subscribedToNewsletter": false 8 | } 9 | -------------------------------------------------------------------------------- /tests/Responses/Expected/customer/update_customer.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": @integer@, 3 | "firstName": "New name", 4 | "lastName": "New lastName", 5 | "email": "oliver@queen.com", 6 | "birthday": "@string@", 7 | "gender": "m", 8 | "phoneNumber": "0918972132", 9 | "subscribedToNewsletter": true 10 | } 11 | -------------------------------------------------------------------------------- /tests/Responses/Expected/customer/validation_email_not_defined_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 400, 3 | "message": "Validation failed", 4 | "errors": { 5 | "email": [ 6 | "sylius.shop_api.email.not_null", 7 | "sylius.shop_api.email.not_found" 8 | ] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/Responses/Expected/customer/validation_email_not_found_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 400, 3 | "message": "Validation failed", 4 | "errors": { 5 | "email": [ 6 | "sylius.shop_api.email.not_found" 7 | ] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/Responses/Expected/customer/validation_email_not_valid_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 400, 3 | "message": "Validation failed", 4 | "errors": { 5 | "email": [ 6 | "sylius.shop_api.email.not_valid", 7 | "sylius.shop_api.email.not_found" 8 | ] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tests/Responses/Expected/customer/validation_empty_data.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 400, 3 | "message": "Validation failed", 4 | "errors": { 5 | "firstName": [ 6 | "Please enter your first name." 7 | ], 8 | "lastName": [ 9 | "Please enter your last name." 10 | ], 11 | "gender": [ 12 | "Please choose your gender." 13 | ], 14 | "email": [ 15 | "Please enter your email." 16 | ] 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/Responses/Expected/customer/validation_registration_data_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 400, 3 | "message": "Validation failed", 4 | "errors": { 5 | "email": [ 6 | "Please enter your email." 7 | ] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/Responses/Expected/customer/validation_registration_email_taken_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 400, 3 | "message": "Validation failed", 4 | "errors": { 5 | "email": [ 6 | "This email is already used." 7 | ] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/Responses/Expected/order/order_not_found_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 404, 3 | "message": "There is no placed order with with token NOT_EXISTING_TOKEN for customer with email oliver@queen.com" 4 | } 5 | -------------------------------------------------------------------------------- /tests/Responses/Expected/product/channel_has_not_been_found_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 404, 3 | "message": "Channel with code WEB_GB has not been found." 4 | } 5 | -------------------------------------------------------------------------------- /tests/Responses/Expected/product/product_has_not_been_found_for_given_code_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 404, 3 | "message": "Product with code WRONG_PRODUCT_CODE has not been found." 4 | } 5 | -------------------------------------------------------------------------------- /tests/Responses/Expected/product/product_has_not_been_found_for_given_slug_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 404, 3 | "message": "Product with slug some-weird-stuff has not been found in en_GB locale." 4 | } 5 | -------------------------------------------------------------------------------- /tests/Responses/Expected/product/product_without_taxons_details_page.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": "LOGAN_SHOES_CODE", 3 | "name": "Logan Shoes", 4 | "slug": "logan-shoes", 5 | "channelCode": "WEB_GB", 6 | "breadcrumb": "logan-shoes", 7 | "description": "Some description Lorem ipsum dolor sit amet.", 8 | "averageRating": 0, 9 | "taxons": { 10 | "others": [] 11 | }, 12 | "variants": [], 13 | "attributes": [], 14 | "associations": [], 15 | "images": [], 16 | "_links": { 17 | "self": { 18 | "href": "\/shop-api\/WEB_GB\/products\/by-slug\/logan-shoes" 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tests/Responses/Expected/reviews/add_review_failed_email.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 400, 3 | "message": "Validation failed", 4 | "errors": { 5 | "email": [ 6 | "This value is not a valid email address." 7 | ] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/Responses/Expected/reviews/add_review_failed_rating.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": 400, 3 | "message": "Validation failed", 4 | "errors": { 5 | "rating": [ 6 | "This value should be 5 or less." 7 | ] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/Responses/Expected/taxon/strange_taxon_code_response.json: -------------------------------------------------------------------------------- 1 | { 2 | "self": { 3 | "code": "de?lol=xd#boom", 4 | "name": "Yet another taxon", 5 | "slug": "yet_another_taxons", 6 | "description": "Some description Lorem ipsum dolor sit amet.", 7 | "position": 2, 8 | "children": [], 9 | "images": [] 10 | }, 11 | "parentTree": { 12 | "code": "de?lol=xd#boom", 13 | "name": "Yet another taxon", 14 | "slug": "yet_another_taxons", 15 | "description": "Some description Lorem ipsum dolor sit amet.", 16 | "position": 2, 17 | "children": [], 18 | "images": [] 19 | } 20 | } 21 | --------------------------------------------------------------------------------