diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index db97ee7..f9d8504 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -189,3 +189,17 @@ jobs: - name: Run tests run: composer test + + npm: + name: "npm" + runs-on: ubuntu-latest + container: "node" + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Install dependencies + run: npm install + + - name: Run tests + run: npm test diff --git a/assets/dist/thepay.css b/assets/dist/thepay.css index 6fb42b2..d074e74 100644 --- a/assets/dist/thepay.css +++ b/assets/dist/thepay.css @@ -1 +1 @@ -.tp-btn-grid{display:flex;flex-wrap:wrap;justify-content:flex-start;margin:-.5rem}.tp-btn-grid .tp-btn{margin:.5rem;width:calc(100% - 1rem);min-width:100px}@media (min-width:330px){.tp-btn-grid .tp-btn{width:calc(50% - 1rem)}}@media (min-width:576px){.tp-btn-grid .tp-btn{width:calc(33.33333% - 1rem)}}@media (min-width:768px){.tp-btn-grid .tp-btn{width:calc(25% - 1rem)}}@media (min-width:992px){.tp-btn-grid .tp-btn{width:calc(16.66667% - 1rem)}}.tp-btn-grid .tp-btn .tp-icon{width:100%}.tp-btn{display:inline-block;box-sizing:border-box;text-align:center;border:0 solid #e0e0e0;text-decoration:none}.tp-btn,.tp-btn .tp-icon{max-width:100%;box-shadow:none}.tp-btn .tp-icon{display:flex;justify-content:center;align-items:center;background-color:#fff;margin:0 0 .5rem;transition:.3s;width:200px;height:81px;max-height:100%;padding:1rem;border:1px solid #e0e0e0;border-radius:5px}.tp-btn .tp-icon img{width:100%;height:100%}.tp-btn .tp-title{color:#000;text-decoration:none}.tp-btn:active,.tp-btn:focus,.tp-btn:hover{border-color:#1f46ed;box-shadow:none;text-decoration:underline}.tp-btn:active .tp-icon,.tp-btn:focus .tp-icon,.tp-btn:hover .tp-icon{border-color:#1f46ed;box-shadow:0 4px 5px rgba(31,70,237,.69)}.tp-btn:active .tp-title,.tp-btn:focus .tp-title,.tp-btn:hover .tp-title{color:#1f46ed;text-decoration:underline} \ No newline at end of file +.tp-btn-grid{display:flex;flex-wrap:wrap;justify-content:flex-start;margin:-.5rem}.tp-btn-grid .tp-btn{margin:.5rem;min-width:100px;width:calc(100% - 1rem)}@media (min-width:330px){.tp-btn-grid .tp-btn{width:calc(50% - 1rem)}}@media (min-width:576px){.tp-btn-grid .tp-btn{width:calc(33.33333% - 1rem)}}@media (min-width:768px){.tp-btn-grid .tp-btn{width:calc(25% - 1rem)}}@media (min-width:992px){.tp-btn-grid .tp-btn{width:calc(16.66667% - 1rem)}}.tp-btn-grid .tp-btn .tp-icon{width:100%}.tp-btn{border:0 solid #e0e0e0;box-sizing:border-box;display:inline-block;text-align:center;text-decoration:none}.tp-btn,.tp-btn .tp-icon{box-shadow:none;max-width:100%}.tp-btn .tp-icon{align-items:center;background-color:#fff;border:1px solid #e0e0e0;border-radius:5px;display:flex;height:81px;justify-content:center;margin:0 0 .5rem;max-height:100%;padding:1rem;transition:.3s;width:200px}.tp-btn .tp-icon img{height:100%;width:100%}.tp-btn .tp-title{color:#000;text-decoration:none}.tp-btn:active,.tp-btn:focus,.tp-btn:hover{border-color:#1f46ed;box-shadow:none;text-decoration:underline}.tp-btn:active .tp-icon,.tp-btn:focus .tp-icon,.tp-btn:hover .tp-icon{border-color:#1f46ed;box-shadow:0 4px 5px rgba(31,70,237,.69)}.tp-btn:active .tp-title,.tp-btn:focus .tp-title,.tp-btn:hover .tp-title{color:#1f46ed;text-decoration:underline} diff --git a/assets/dist/thepay.js b/assets/dist/thepay.js index c0d28f1..84fdb79 100644 --- a/assets/dist/thepay.js +++ b/assets/dist/thepay.js @@ -1 +1 @@ -!function(e){var t={};function n(r){if(t[r])return t[r].exports;var a=t[r]={i:r,l:!1,exports:{}};return e[r].call(a.exports,a,a.exports,n),a.l=!0,a.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var a in e)n.d(r,a,function(t){return e[t]}.bind(null,a));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/",n(n.s=0)}([function(e,t,n){n(1),e.exports=n(5)},function(e,t,n){void 0===window.ThePayApi&&n(2)},function(e,t,n){var r={};window.ThePayApi=r,r.init=function(){r.initHandlers()};var a=r.helpers=n(3);r.initHandlers=function(){document.addEventListener("click",(function(e){var t=e.target;if(t&&a.elementHasData(t,"thepay"))return r.handleEvent.call(t,e,a.elementGetData(t,"thepay"));var n=a.elementParentByData(t,"thepay");return n?r.handleEvent.call(n,e,a.elementGetData(n,"thepay")):void 0}))},r.handlers={},r.handleEvent=function(e,t){var n=e.type;if(void 0!==r.handlers[t]&&void 0!==r.handlers[t][n])return r.handlers[t][n].call(this,e)},r.registerActionEvent=function(e,t,n){void 0===r.handlers[e]&&(r.handlers[e]={}),r.handlers[e][t]=n},r.unregisterActionEvent=function(e,t){delete r.handlers[e][t]},n(4),r.init()},function(e,t){var n={elementGetData:function(e,t,n){var r=void 0!==e.getAttribute?e.getAttribute("data-"+t):null;if(null===r||""===r)return n;try{return JSON.parse(r)}catch(e){return r}},elementHasData:function(e,t){var n=void 0!==e.getAttribute?e.getAttribute("data-"+t):null;return null!==n&&""!==n},elementParentByData:function(e,t){for(var r=e.parentNode;r;){if(n.elementHasData(r,t))return r;r=void 0!==r.parentNode&&r.parentNode}return null}};e.exports=n},function(e,t){ThePayApi.registerActionEvent("payment-button","click",(function(e){if(ThePayApi.helpers.elementHasData(this,"form-id")){var t=document.getElementById(ThePayApi.helpers.elementGetData(this,"form-id"));if(t){e.preventDefault();var n=ThePayApi.helpers.elementGetData(this,"payment-method");return ThePayApi.sendPaymentRequestForm(t,n),!1}}return!0})),ThePayApi.sendPaymentRequestForm=function(e,t){if(t){var n=e.getAttribute("id")+"-method",r=document.getElementById(n);r||((r=document.createElement("input")).setAttribute("type","hidden"),r.setAttribute("id",n),r.setAttribute("name","payment_method_code"),e.appendChild(r)),r.setAttribute("value",t)}e.submit()}},function(e,t){}]); \ No newline at end of file +(()=>{var e,t={884:e=>{var t={elementGetData:function(e,t,n){var r=void 0!==e.getAttribute?e.getAttribute("data-"+t):null;if(null===r||""===r)return n;try{return JSON.parse(r)}catch(e){return r}},elementHasData:function(e,t){var n=void 0!==e.getAttribute?e.getAttribute("data-"+t):null;return null!==n&&""!==n},elementParentByData:function(e,n){for(var r=e.parentNode;r;){if(t.elementHasData(r,n))return r;r=void 0!==r.parentNode&&r.parentNode}return null}};e.exports=t},363:(e,t,n)=>{var r={};window.ThePayApi=r,r.init=function(){r.initHandlers()};var a=r.helpers=n(884);r.initHandlers=function(){document.addEventListener("click",(function(e){var t=e.target;if(t&&a.elementHasData(t,"thepay"))return r.handleEvent.call(t,e,a.elementGetData(t,"thepay"));var n=a.elementParentByData(t,"thepay");return n?r.handleEvent.call(n,e,a.elementGetData(n,"thepay")):void 0}))},r.handlers={},r.handleEvent=function(e,t){var n=e.type;if(void 0!==r.handlers[t]&&void 0!==r.handlers[t][n])return r.handlers[t][n].call(this,e)},r.registerActionEvent=function(e,t,n){void 0===r.handlers[e]&&(r.handlers[e]={}),r.handlers[e][t]=n},r.unregisterActionEvent=function(e,t){delete r.handlers[e][t]},n(784),r.init()},784:()=>{ThePayApi.registerActionEvent("payment-button","click",(function(e){if(ThePayApi.helpers.elementHasData(this,"form-id")){var t=document.getElementById(ThePayApi.helpers.elementGetData(this,"form-id"));if(t){e.preventDefault();var n=ThePayApi.helpers.elementGetData(this,"payment-method");return ThePayApi.sendPaymentRequestForm(t,n),!1}}return!0})),ThePayApi.sendPaymentRequestForm=function(e,t){if(t){var n=e.getAttribute("id")+"-method",r=document.getElementById(n);r||((r=document.createElement("input")).setAttribute("type","hidden"),r.setAttribute("id",n),r.setAttribute("name","payment_method_code"),e.appendChild(r)),r.setAttribute("value",t)}e.submit()}},381:(e,t,n)=>{void 0===window.ThePayApi&&n(363)},691:()=>{}},n={};function r(e){var a=n[e];if(void 0!==a)return a.exports;var i=n[e]={exports:{}};return t[e](i,i.exports,r),i.exports}r.m=t,e=[],r.O=(t,n,a,i)=>{if(!n){var l=1/0;for(s=0;s=i)&&Object.keys(r.O).every((e=>r.O[e](n[u])))?n.splice(u--,1):(o=!1,i0&&e[s-1][2]>i;s--)e[s]=e[s-1];e[s]=[n,a,i]},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{var e={538:0,716:0};r.O.j=t=>0===e[t];var t=(t,n)=>{var a,i,[l,o,u]=n,d=0;if(l.some((t=>0!==e[t]))){for(a in o)r.o(o,a)&&(r.m[a]=o[a]);if(u)var s=u(r)}for(t&&t(n);dr(381)));var a=r.O(void 0,[716],(()=>r(691)));a=r.O(a)})(); \ No newline at end of file diff --git a/assets/scss/_payments.scss b/assets/scss/_payments.scss index 936cec4..7608b77 100644 --- a/assets/scss/_payments.scss +++ b/assets/scss/_payments.scss @@ -1,3 +1,5 @@ +@use 'sass:math'; + // THEPAY PAYMENTS GRID // Container for payment buttons. .tp-btn-grid { @@ -5,16 +7,16 @@ flex-wrap: $tp-btn-grid-wrap; justify-content: $tp-btn-grid-justify; - margin: -$tp-btn-grid-spacing / 2; + margin: math.div(-$tp-btn-grid-spacing, 2); // Button in grid .tp-btn { - margin: $tp-btn-grid-spacing / 2; + margin: math.div($tp-btn-grid-spacing, 2); width: calc(100% - #{$tp-btn-grid-spacing}); min-width: $tp-btn-grid-min-btn-width; @each $breakpoint, $count in $tp-btn-grid-cols { @include tp-media-breakpoint-up($breakpoint){ - width: calc(#{100% / $count} - #{$tp-btn-grid-spacing}); + width: calc(#{math.div(100%, $count)} - #{$tp-btn-grid-spacing}); } } @@ -29,7 +31,6 @@ text-align: center; display: inline-block; box-sizing: border-box; - text-align: center; max-width: 100%; border: $tp-btn-border solid $tp-btn-border-color; box-shadow: $tp-btn-shadow; @@ -39,7 +40,6 @@ display: flex; justify-content: center; align-items: center; - border-radius: 5px; background-color: $tp-icon-bg; margin: $tp-icon-margin; transition: $tp-icon-transition; diff --git a/assets/scss/_variables.scss b/assets/scss/_variables.scss index 889a73e..2d9ebd7 100644 --- a/assets/scss/_variables.scss +++ b/assets/scss/_variables.scss @@ -1,3 +1,4 @@ +@use 'sass:math'; // THEPAY COLOR VARIABLES $tp-white: #ffffff !default; @@ -63,7 +64,7 @@ $tp-icon-bg: $tp-white !default; $tp-icon-border: $tp-border !default; $tp-icon-border-color: $tp-border-color !default; $tp-icon-shadow: none !default; -$tp-icon-margin: 0 0 $tp-spacing / 2 !default; +$tp-icon-margin: 0 0 math.div($tp-spacing, 2) !default; $tp-icon-transition: .3s !default; $tp-icon-hover-border-color: $tp-main-color !default; $tp-icon-hover-shadow: 0 4px 5px transparentize($tp-icon-hover-border-color, .31) !default; diff --git a/assets/tests/dist.test.js b/assets/tests/dist.test.js new file mode 100644 index 0000000..864dff0 --- /dev/null +++ b/assets/tests/dist.test.js @@ -0,0 +1,14 @@ +const fs = require('node:fs'); +const path = require('node:path'); + +let assetContent = (filename) => fs.readFileSync(path.resolve('assets', filename)).toString(); + +test('Dist style is minified', () => { + // Minified style does not have more than 5 lines. + return expect(assetContent('dist/thepay.css').split(/\n/).length).toBeLessThan(5); +}); + +test('Dist script is minified', () => { + // Minified script does not have more than 5 lines. + return expect(assetContent('dist/thepay.js').split(/\n/).length).toBeLessThan(5); +}); diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..229f976 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,9 @@ +/* + * For a detailed explanation regarding each configuration property, visit: + * https://jestjs.io/docs/configuration + */ + +module.exports = { + // The root directory that Jest should scan for tests and modules within + rootDir: 'assets/tests', +}; diff --git a/package.json b/package.json index 33f67c6..367db98 100644 --- a/package.json +++ b/package.json @@ -1,18 +1,14 @@ { "private": true, "scripts": { - "dev": "npm run development", - "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", - "watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", - "watch-poll": "npm run watch -- --watch-poll", - "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js", - "prod": "npm run production", - "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js" + "build": "mix --production", + "test": "jest" }, - "devDependencies": { - "cross-env": "^7.0.2", - "laravel-mix": "^5.0.4", - "node-sass": "^4.14.1" + "jest": "^29.1.2", + "laravel-mix": "^6.0.49", + "resolve-url-loader": "^5.0.0", + "sass": "^1.55.0", + "sass-loader": "^12.1.0" } } diff --git a/tests/CreatePaymentTest.php b/tests/CreatePaymentTest.php index 4363c2b..e73ddd4 100644 --- a/tests/CreatePaymentTest.php +++ b/tests/CreatePaymentTest.php @@ -98,28 +98,6 @@ public function testGetPaymentMethods() // todo: complete test, implementation was not final at this moment } - /** - * @return void - */ - public function testGetInlineStyles() - { - $result = $this->client->getInlineStyles(); - $lines = count(explode("\n", $result)); - // Minified style does not have more than 5 lines. - static::assertLessThanOrEqual(5, $lines, 'TheClient::getInlineStyles() has more than 5 lines. Fix this bug with "npm run production"'); - } - - /** - * @return void - */ - public function testGetInlineScripts() - { - $result = $this->client->getInlineScripts(); - $lines = count(explode("\n", $result)); - // Minified javascript does not have more than 5 lines. - static::assertLessThanOrEqual(5, $lines, 'TheClient::getInlineScript() has more than 5 lines. Fix this bug with "npm run production"'); - } - /** * @return void */