From 3587541f78e8f840036b92b1f579182ab27bb8a4 Mon Sep 17 00:00:00 2001 From: Michiel Gerritsen Date: Mon, 8 Jan 2024 13:49:24 +0100 Subject: [PATCH] Feature: New payment method TWINT --- .github/workflows/end-2-end-test.yml | 3 +- .../workflows/templates/docker-compose.yml | 1 + .../templates/magento/configure-mollie.sh | 6 + .../templates/magento/merge-config.php.stub | 81 ++++++++++ Helper/General.php | 1 + Model/Methods/Twint.php | 24 +++ Model/MollieConfigProvider.php | 1 + .../Api/LimitMethodsForRecurringPayments.php | 1 + README.md | 1 + Service/Mollie/PaymentMethods.php | 1 + Service/Order/OrderAmount.php | 2 +- Test/End-2-end/cypress.config.js | 107 +++++++------ .../fixtures/swiss-shipping-address.json | 15 ++ .../VisitCheckoutPaymentCompositeAction.js | 14 ++ .../pages/frontend/CheckoutPaymentPage.js | 2 +- .../Etc/Config/MethodsConfigurationTest.php | 1 + Test/Integration/Helper/GeneralTest.php | 1 + Test/Integration/Model/Methods/TwintTest.php | 12 ++ .../Model/MollieConfigProviderTest.php | 1 + .../Service/Config/PaymentFeeTest.php | 1 + composer.json | 1 + etc/adminhtml/methods.xml | 1 + etc/adminhtml/methods/twint.xml | 151 ++++++++++++++++++ etc/adminhtml/methods/voucher.xml | 2 +- etc/config.xml | 19 +++ etc/graphql/di.xml | 1 + etc/payment.xml | 3 + i18n/de_DE.csv | 1 + i18n/en_US.csv | 1 + i18n/es_ES.csv | 1 + i18n/fr_FR.csv | 1 + i18n/nl_NL.csv | 1 + .../templates/form/mollie_paymentlink.phtml | 1 + view/adminhtml/web/images/twint.svg | 44 +++++ view/frontend/layout/checkout_index_index.xml | 3 + view/frontend/web/images/methods/twint.svg | 44 +++++ .../web/js/view/payment/method-renderer.js | 1 + 37 files changed, 503 insertions(+), 49 deletions(-) create mode 100644 .github/workflows/templates/magento/merge-config.php.stub create mode 100644 Model/Methods/Twint.php create mode 100644 Test/End-2-end/cypress/fixtures/swiss-shipping-address.json create mode 100644 Test/Integration/Model/Methods/TwintTest.php create mode 100644 etc/adminhtml/methods/twint.xml create mode 100644 view/adminhtml/web/images/twint.svg create mode 100644 view/frontend/web/images/methods/twint.svg diff --git a/.github/workflows/end-2-end-test.yml b/.github/workflows/end-2-end-test.yml index c6b6e5773b0..47c67b07bbe 100644 --- a/.github/workflows/end-2-end-test.yml +++ b/.github/workflows/end-2-end-test.yml @@ -87,8 +87,9 @@ jobs: - name: Activate the extension run: | + docker exec magento-project-community-edition php /data/merge-config.php docker exec magento-project-community-edition ./retry "php bin/magento module:enable Mollie_Payment" - docker exec magento-project-community-edition ./retry "php bin/magento setup:upgrade" + docker exec magento-project-community-edition ./retry "php bin/magento setup:upgrade --no-interaction" docker exec magento-project-community-edition /bin/bash /data/configure-mollie.sh docker exec magento-project-community-edition ./retry "bin/magento config:set payment/mollie_general/use_webhooks custom_url" docker exec magento-project-community-edition ./retry "bin/magento config:set payment/mollie_general/custom_webhook_url ${{ env.magento_url }}/mollie/checkout/webhook" diff --git a/.github/workflows/templates/docker-compose.yml b/.github/workflows/templates/docker-compose.yml index 213c0599447..bb5e8e3355d 100644 --- a/.github/workflows/templates/docker-compose.yml +++ b/.github/workflows/templates/docker-compose.yml @@ -10,6 +10,7 @@ services: volumes: - ../../../magento-logs:/data/var/log - ./magento/configure-mollie.sh:/data/configure-mollie.sh + - ./magento/merge-config.php.stub:/data/merge-config.php depends_on: - ngrok diff --git a/.github/workflows/templates/magento/configure-mollie.sh b/.github/workflows/templates/magento/configure-mollie.sh index 8fb86fb33e2..291a70f260d 100644 --- a/.github/workflows/templates/magento/configure-mollie.sh +++ b/.github/workflows/templates/magento/configure-mollie.sh @@ -29,6 +29,7 @@ bin/magento config:set payment/mollie_methods_paymentlink/active 1 & bin/magento config:set payment/mollie_methods_paysafecard/active 1 & bin/magento config:set payment/mollie_methods_pointofsale/active 1 & bin/magento config:set payment/mollie_methods_sofort/active 1 & +bin/magento config:set payment/mollie_methods_twint/active 1 & # Enable Components bin/magento config:set payment/mollie_methods_creditcard/use_components 1 & @@ -38,6 +39,11 @@ bin/magento config:set payment/mollie_methods_ideal/add_qr 1 & bin/magento config:set payment/mollie_general/use_webhooks disabled & +# Configure currency for the swiss store view +bin/magento config:set currency/options/allow EUR,CHF & +bin/magento config:set currency/options/default CHF --scope=ch & +bin/magento config:set payment/mollie_general/currency 0 --scope=ch & + wait if grep -q Magento_TwoFactorAuth "app/etc/config.php"; then diff --git a/.github/workflows/templates/magento/merge-config.php.stub b/.github/workflows/templates/magento/merge-config.php.stub new file mode 100644 index 00000000000..74652e2bef3 --- /dev/null +++ b/.github/workflows/templates/magento/merge-config.php.stub @@ -0,0 +1,81 @@ + [ + 'admin' => [ + 'website_id' => '0', + 'code' => 'admin', + 'name' => 'Admin', + 'sort_order' => '0', + 'default_group_id' => '0', + 'is_default' => '0' + ], + 'base' => [ + 'website_id' => '1', + 'code' => 'base', + 'name' => 'Main Website', + 'sort_order' => '0', + 'default_group_id' => '1', + 'is_default' => '1' + ] + ], + 'groups' => [ + [ + 'group_id' => '0', + 'website_id' => '0', + 'name' => 'Default', + 'root_category_id' => '0', + 'default_store_id' => '0', + 'code' => 'default' + ], + [ + 'group_id' => '1', + 'website_id' => '1', + 'name' => 'Main Website Store', + 'root_category_id' => '2', + 'default_store_id' => '1', + 'code' => 'main_website_store' + ] + ], + 'stores' => [ + 'admin' => [ + 'store_id' => '0', + 'code' => 'admin', + 'website_id' => '0', + 'group_id' => '0', + 'name' => 'Admin', + 'sort_order' => '0', + 'is_active' => '1' + ], + 'default' => [ + 'store_id' => '1', + 'code' => 'default', + 'website_id' => '1', + 'group_id' => '1', + 'name' => 'Default Store View', + 'sort_order' => '0', + 'is_active' => '1' + ], + 'ch' => [ + 'store_id' => '2', + 'code' => 'ch', + 'website_id' => '1', + 'group_id' => '1', + 'name' => 'Swiss', + 'sort_order' => '0', + 'is_active' => '1' + ] + ] +]; + +file_put_contents( + 'app/etc/config.php', + 'getOrders($transactionId); foreach ($orders->getItems() as $order) { - if ($this->config->useBaseCurrency()) { + if ($this->config->useBaseCurrency($order->getStoreId())) { $currencies[] = $order->getBaseCurrencyCode(); $amount += $order->getBaseGrandTotal(); } else { diff --git a/Test/End-2-end/cypress.config.js b/Test/End-2-end/cypress.config.js index 59ed0e4e1b8..b17b6b0b823 100644 --- a/Test/End-2-end/cypress.config.js +++ b/Test/End-2-end/cypress.config.js @@ -18,65 +18,82 @@ module.exports = defineConfig({ require('./cypress/plugins/disable-successful-videos.js')(on, config); // Retrieve available method - await new Promise((resolve, reject) => { + await new Promise((methodsPromiseResolve, reject) => { var https = require('follow-redirects').https; const baseUrl = config.baseUrl; const urlObj = new URL(baseUrl); const hostname = urlObj.hostname; - const query = ` - query { - molliePaymentMethods(input:{amount:100, currency:"EUR"}) { - methods { - code - image - name - } - } - } - `; - - var options = { - 'method': 'GET', - 'hostname': hostname, - 'path': '/graphql?query=' + encodeURIComponent(query), - 'headers': { - 'Content-Type': 'application/json', - // 'Cookie': 'XDEBUG_SESSION=PHPSTORM' - }, - 'maxRedirects': 20 - }; + const currencies = ['EUR', 'CHF']; - console.log('Requesting Mollie payment methods from "' + baseUrl + '". One moment please...'); - var req = https.request(options, function (res) { - var chunks = []; + let promises = []; - res.on("data", function (chunk) { - chunks.push(chunk); + currencies.forEach(currency => { + const query = ` + query { + molliePaymentMethods(input:{amount:100, currency:"${currency}"}) { + methods { + code + image + name + } + } + } + `; + + var options = { + 'method': 'GET', + 'hostname': hostname, + 'path': '/graphql?query=' + encodeURIComponent(query), + 'headers': { + 'Content-Type': 'application/json', + // 'Cookie': 'XDEBUG_SESSION=PHPSTORM' + }, + 'maxRedirects': 20 + }; + + console.log(`Requesting Mollie payment methods from "${baseUrl}" for ${currency}. One moment please...`); + const promise = new Promise((resolve, reject) => { + var req = https.request(options, function (res) { + var chunks = []; + + res.on("data", function (chunk) { + chunks.push(chunk); + }); + + res.on("end", function (chunk) { + const body = Buffer.concat(chunks); + + const methods = JSON.parse(body.toString()).data.molliePaymentMethods.methods.map(data => { + return data.code + }) + + console.log(`Available Mollie payment methods for ${currency}: `, methods); + + resolve(methods); + }); + + res.on("error", function (error) { + console.error('Error while fetching Mollie Payment methods', error); + reject(error); + }); + }); + + req.end(); }); - res.on("end", function (chunk) { - const body = Buffer.concat(chunks); - - const methods = JSON.parse(body.toString()).data.molliePaymentMethods.methods.map(data => { - return data.code - }) - - config.env.mollie_available_methods = methods; + promises.push(promise); + }); - console.log('Available Mollie payment methods: ', methods); + Promise.all(promises).then((values) => { + const methods = [].concat(...values); + config.env.mollie_available_methods = [...new Set(methods)]; - resolve(config); - }); + console.log('Available Mollie payment methods: ', config.env.mollie_available_methods); - res.on("error", function (error) { - console.error('Error while fetching Mollie Payment methods', error); - reject(error); - }); + methodsPromiseResolve(); }); - - req.end(); }); // retrieve admin token diff --git a/Test/End-2-end/cypress/fixtures/swiss-shipping-address.json b/Test/End-2-end/cypress/fixtures/swiss-shipping-address.json new file mode 100644 index 00000000000..22a6dc3250b --- /dev/null +++ b/Test/End-2-end/cypress/fixtures/swiss-shipping-address.json @@ -0,0 +1,15 @@ +{ + "type": { + "username": "johnsmith@mollie.com", + "firstname": "John", + "lastname": "Smith", + "street[0]": "Bahnhofstrasse 10", + "city": "Zurich", + "postcode": "8001", + "telephone": "0441234567" + }, + "select": { + "country_id": "CH", + "region_id": "Zürich" + } +} diff --git a/Test/End-2-end/cypress/support/actions/composite/VisitCheckoutPaymentCompositeAction.js b/Test/End-2-end/cypress/support/actions/composite/VisitCheckoutPaymentCompositeAction.js index a887b532a90..1f57f5c9848 100644 --- a/Test/End-2-end/cypress/support/actions/composite/VisitCheckoutPaymentCompositeAction.js +++ b/Test/End-2-end/cypress/support/actions/composite/VisitCheckoutPaymentCompositeAction.js @@ -50,4 +50,18 @@ export default class VisitCheckoutPaymentCompositeAction { checkoutShippingPage.fillShippingAddressUsingFixture(fixture); } + + changeStoreViewTo(name) { + cy.visit('/'); + + cy.get('.greet.welcome').should('be.visible'); + + cy.get('.switcher-trigger').then(($el) => { + if ($el.text().includes('Default Store View')) { + cy.get('#switcher-language-trigger .view-default').click(); + + cy.get('.switcher-dropdown').contains(name).click(); + } + }); + } } diff --git a/Test/End-2-end/cypress/support/pages/frontend/CheckoutPaymentPage.js b/Test/End-2-end/cypress/support/pages/frontend/CheckoutPaymentPage.js index 327fae43d84..1f64ddf06d7 100644 --- a/Test/End-2-end/cypress/support/pages/frontend/CheckoutPaymentPage.js +++ b/Test/End-2-end/cypress/support/pages/frontend/CheckoutPaymentPage.js @@ -22,7 +22,7 @@ export default class CheckoutPaymentPage { placeOrder() { cy.intercept('mollie/checkout/redirect/paymentToken/*').as('mollieRedirect'); - cy.intercept('POST', 'rest/default/V1/guest-carts/*/payment-information').as('placeOrderAction'); + cy.intercept('POST', 'rest/*/V1/guest-carts/*/payment-information').as('placeOrderAction'); this.pressPlaceOrderButton(); diff --git a/Test/Integration/Etc/Config/MethodsConfigurationTest.php b/Test/Integration/Etc/Config/MethodsConfigurationTest.php index 0293100d849..4c1307f9b1e 100644 --- a/Test/Integration/Etc/Config/MethodsConfigurationTest.php +++ b/Test/Integration/Etc/Config/MethodsConfigurationTest.php @@ -38,6 +38,7 @@ public function methods(): array ['mollie_methods_pointofsale'], ['mollie_methods_przelewy24'], ['mollie_methods_sofort'], + ['mollie_methods_twint'], ]; } diff --git a/Test/Integration/Helper/GeneralTest.php b/Test/Integration/Helper/GeneralTest.php index 061afb7048c..94ef84a9c4b 100644 --- a/Test/Integration/Helper/GeneralTest.php +++ b/Test/Integration/Helper/GeneralTest.php @@ -161,6 +161,7 @@ public function getMethodCodeDataProvider() 'pointofsale' => ['mollie_methods_pointofsale', 'pointofsale'], 'przelewy24' => ['mollie_methods_przelewy24', 'przelewy24'], 'sofort' => ['mollie_methods_sofort', 'sofort'], + 'twint' => ['mollie_methods_twint', 'twint'], ]; } diff --git a/Test/Integration/Model/Methods/TwintTest.php b/Test/Integration/Model/Methods/TwintTest.php new file mode 100644 index 00000000000..c21802245a7 --- /dev/null +++ b/Test/Integration/Model/Methods/TwintTest.php @@ -0,0 +1,12 @@ +assertArrayHasKey('mollie_methods_pointofsale', $result['payment']['image']); $this->assertArrayHasKey('mollie_methods_przelewy24', $result['payment']['image']); $this->assertArrayHasKey('mollie_methods_sofort', $result['payment']['image']); + $this->assertArrayHasKey('mollie_methods_twint', $result['payment']['image']); $this->assertArrayHasKey('mollie_methods_voucher', $result['payment']['image']); $this->assertEquals([], $result['payment']['issuers']['mollie_methods_ideal']); diff --git a/Test/Integration/Service/Config/PaymentFeeTest.php b/Test/Integration/Service/Config/PaymentFeeTest.php index 406b7467f7b..400645f0426 100644 --- a/Test/Integration/Service/Config/PaymentFeeTest.php +++ b/Test/Integration/Service/Config/PaymentFeeTest.php @@ -46,6 +46,7 @@ public function isAvailableForMethodProvider() ['mollie_methods_pointofsale', true], ['mollie_methods_przelewy24', true], ['mollie_methods_sofort', true], + ['mollie_methods_twint', true], ['mollie_methods_voucher', true], ['not_relevant_payment_method', false], ]; diff --git a/composer.json b/composer.json index 285aa072bf7..be5f415c2ec 100644 --- a/composer.json +++ b/composer.json @@ -34,6 +34,7 @@ "refunds", "sofort", "sofortbanking", + "twint", "voucher", "api", "payments", diff --git a/etc/adminhtml/methods.xml b/etc/adminhtml/methods.xml index f46580e3dab..68419f9501d 100644 --- a/etc/adminhtml/methods.xml +++ b/etc/adminhtml/methods.xml @@ -30,5 +30,6 @@ + diff --git a/etc/adminhtml/methods/twint.xml b/etc/adminhtml/methods/twint.xml new file mode 100644 index 00000000000..1b909991562 --- /dev/null +++ b/etc/adminhtml/methods/twint.xml @@ -0,0 +1,151 @@ + + + + + + + Magento\Config\Model\Config\Source\Yesno + payment/mollie_methods_twint/active + + + + payment/mollie_methods_twint/title + + 1 + + + + + Mollie\Payment\Model\Adminhtml\Source\Method + payment/mollie_methods_twint/method + + 1 + + here + to read more about the differences between the Payment and Orders API.]]> + + + + payment/mollie_methods_twint/payment_description + + + payment + 1 + + + + + validate-digits-range digits-range-1-365 + payment/mollie_methods_twint/days_before_expire + + 1 + order + + How many days before orders for this method becomes expired? Leave empty to use default expiration (28 days) + + + + Magento\Payment\Model\Config\Source\Allspecificcountries + payment/mollie_methods_twint/allowspecific + + 1 + + + + + Magento\Directory\Model\Config\Source\Country + 1 + payment/mollie_methods_twint/specificcountry + + 1 + + + + + payment/mollie_methods_twint/min_order_total + + 1 + + + + + payment/mollie_methods_twint/max_order_total + + 1 + + + + + payment/mollie_methods_twint/payment_surcharge_type + Mollie\Payment\Model\Adminhtml\Source\PaymentFeeType + + 1 + + + + + payment/mollie_methods_twint/payment_surcharge_fixed_amount + Mollie\Payment\Model\Adminhtml\Backend\VerifiyPaymentFee + validate-not-negative-number + + 1 + fixed_fee,fixed_fee_and_percentage + + + + + payment/mollie_methods_twint/payment_surcharge_percentage + Mollie\Payment\Model\Adminhtml\Backend\VerifiyPaymentFee + validate-number-range number-range-0-10 + + 1 + percentage,fixed_fee_and_percentage + + + + + payment/mollie_methods_twint/payment_surcharge_limit + + Mollie\Payment\Model\Adminhtml\Backend\VerifiyPaymentFee + validate-not-negative-number + + 1 + percentage,fixed_fee_and_percentage + + + + + payment/mollie_methods_twint/payment_surcharge_tax_class + \Magento\Tax\Model\TaxClass\Source\Product + + 1 + fixed_fee,percentage,fixed_fee_and_percentage + + + + + validate-number + payment/mollie_methods_twint/sort_order + + 1 + + + + diff --git a/etc/adminhtml/methods/voucher.xml b/etc/adminhtml/methods/voucher.xml index 18a3e961cac..a77444df96d 100644 --- a/etc/adminhtml/methods/voucher.xml +++ b/etc/adminhtml/methods/voucher.xml @@ -1,7 +1,7 @@ - 0 1 + + 1 + Mollie\Payment\Model\Methods\Twint + TWINT + {ordernumber} + payment + order + 0 + + 1 + 1 + 1 + 1 + 0 + 1 + 0 + 0 + 1 + 1 Mollie\Payment\Model\Methods\Reorder diff --git a/etc/graphql/di.xml b/etc/graphql/di.xml index 29a3653fbaa..ffe57fbf363 100644 --- a/etc/graphql/di.xml +++ b/etc/graphql/di.xml @@ -27,6 +27,7 @@ Mollie\Payment\GraphQL\DataProvider Mollie\Payment\GraphQL\DataProvider Mollie\Payment\GraphQL\DataProvider + Mollie\Payment\GraphQL\DataProvider diff --git a/etc/payment.xml b/etc/payment.xml index 25c2b1a9109..58a34ee9f49 100644 --- a/etc/payment.xml +++ b/etc/payment.xml @@ -73,6 +73,9 @@ 0 + + 0 + 0 diff --git a/i18n/de_DE.csv b/i18n/de_DE.csv index ffc04215f39..807893a5d71 100644 --- a/i18n/de_DE.csv +++ b/i18n/de_DE.csv @@ -223,6 +223,7 @@ "Point Of Sale (POS)","Point Of Sale (POS)" "Przelewy24","Przelewy24" "Sofort","Sofort" +"TWINT","TWINT" "Voucher","Gutschein" "Category","Kategorie" "Product attribute","Artikelattribut" diff --git a/i18n/en_US.csv b/i18n/en_US.csv index bf91ace9770..3b7e3d1a42d 100644 --- a/i18n/en_US.csv +++ b/i18n/en_US.csv @@ -223,6 +223,7 @@ "Point Of Sale (POS)","Point Of Sale (POS)" "Przelewy24","Przelewy24" "Sofort","Sofort" +"TWINT","TWINT" "Voucher","Voucher" "Category","Category" "Product attribute","Product attribute" diff --git a/i18n/es_ES.csv b/i18n/es_ES.csv index b47786c5312..b0105ab956b 100644 --- a/i18n/es_ES.csv +++ b/i18n/es_ES.csv @@ -223,6 +223,7 @@ "Point Of Sale (POS)","Point Of Sale (POS)" "Przelewy24","Przelewy24" "Sofort","Sofort" +"TWINT","TWINT" "Voucher","Vale" "Category","Categoría" "Product attribute","Atributo del producto" diff --git a/i18n/fr_FR.csv b/i18n/fr_FR.csv index 4a68eba30eb..cb5c5da4edc 100644 --- a/i18n/fr_FR.csv +++ b/i18n/fr_FR.csv @@ -223,6 +223,7 @@ "Point Of Sale (POS)","Point Of Sale (POS)" "Przelewy24","Przelewy24" "Sofort","Sofort" +"TWINT","TWINT" "Voucher","Voucher" "Category","Catégorie" "Product attribute","Attributs du produit" diff --git a/i18n/nl_NL.csv b/i18n/nl_NL.csv index 81ccf595230..9baea213dba 100644 --- a/i18n/nl_NL.csv +++ b/i18n/nl_NL.csv @@ -223,6 +223,7 @@ "Point Of Sale (POS)","Point Of Sale (POS)" "Przelewy24","Przelewy24" "Sofort","Sofort" +"TWINT","TWINT" "Voucher","Bon" "Category","Categorie" "Product attribute","Productkenmerk" diff --git a/view/adminhtml/templates/form/mollie_paymentlink.phtml b/view/adminhtml/templates/form/mollie_paymentlink.phtml index fe94803e4b0..12f0b093905 100644 --- a/view/adminhtml/templates/form/mollie_paymentlink.phtml +++ b/view/adminhtml/templates/form/mollie_paymentlink.phtml @@ -38,6 +38,7 @@ $code; ?>" style="display:none"> + diff --git a/view/adminhtml/web/images/twint.svg b/view/adminhtml/web/images/twint.svg new file mode 100644 index 00000000000..5b148147f18 --- /dev/null +++ b/view/adminhtml/web/images/twint.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/view/frontend/layout/checkout_index_index.xml b/view/frontend/layout/checkout_index_index.xml index 3c108332b73..d89ec3e7119 100644 --- a/view/frontend/layout/checkout_index_index.xml +++ b/view/frontend/layout/checkout_index_index.xml @@ -91,6 +91,9 @@ true + + true + true diff --git a/view/frontend/web/images/methods/twint.svg b/view/frontend/web/images/methods/twint.svg new file mode 100644 index 00000000000..5b148147f18 --- /dev/null +++ b/view/frontend/web/images/methods/twint.svg @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/view/frontend/web/js/view/payment/method-renderer.js b/view/frontend/web/js/view/payment/method-renderer.js index c4d767dee89..6c982ec556c 100644 --- a/view/frontend/web/js/view/payment/method-renderer.js +++ b/view/frontend/web/js/view/payment/method-renderer.js @@ -46,6 +46,7 @@ define( {type: 'mollie_methods_pointofsale', component: pointofsaleComponent}, {type: 'mollie_methods_przelewy24', component: defaultComponent}, {type: 'mollie_methods_sofort', component: defaultComponent}, + {type: 'mollie_methods_twint', component: defaultComponent}, {type: 'mollie_methods_voucher', component: defaultComponent} ];