29
0
mirror of https://github.com/joomla/joomla-cms.git synced 2024-06-25 23:02:55 +00:00

Add tests for global configuration and support mail tests (#40583)

* Add tests for global configuration and support mail tests

* cs

* wait till tab is visible

* visible

* mailer visible

* Update tests/System/plugins/mail.js

Co-authored-by: Brian Teeman <brian@teeman.net>

* Setup mailing in installation task

* Doc

* Add more mail checks

* Do not log the mails as it screwes up the drone output log

---------

Co-authored-by: Brian Teeman <brian@teeman.net>
This commit is contained in:
Allon Moritz 2023-05-15 14:31:39 +02:00 committed by GitHub
parent a818b5fb7c
commit 4ab7aa8dd4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 1051 additions and 190 deletions

View File

@ -37,6 +37,8 @@ module.exports = defineConfig({
db_user: 'root',
db_password: '',
db_prefix: 'jos_',
smtp_host: 'localhost',
smtp_port: '1025',
cmsPath: '.',
},
});

680
package-lock.json generated
View File

@ -78,6 +78,7 @@
"rollup-plugin-vue": "^6.0.0",
"rtlcss": "^3.5.0",
"sass-embedded": "^1.59.3",
"smtp-tester": "^2.0.1",
"stylelint": "^14.16.1",
"stylelint-config-standard": "^24.0.0",
"stylelint-order": "^5.0.0",
@ -2156,6 +2157,34 @@
"integrity": "sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==",
"dev": true
},
"node_modules/@selderee/plugin-htmlparser2": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.10.0.tgz",
"integrity": "sha512-gW69MEamZ4wk1OsOq1nG1jcyhXIQcnrsX5JwixVw/9xaiav8TCyjESAruu1Rz9yyInhgBXxkNwMeygKnN2uxNA==",
"dev": true,
"dependencies": {
"domhandler": "^5.0.3",
"selderee": "^0.10.0"
},
"funding": {
"url": "https://ko-fi.com/killymxi"
}
},
"node_modules/@selderee/plugin-htmlparser2/node_modules/domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"dev": true,
"dependencies": {
"domelementtype": "^2.3.0"
},
"engines": {
"node": ">= 4"
},
"funding": {
"url": "https://github.com/fb55/domhandler?sponsor=1"
}
},
"node_modules/@trysound/sax": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
@ -2787,6 +2816,15 @@
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
"node_modules/base32.js": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/base32.js/-/base32.js-0.1.0.tgz",
"integrity": "sha512-n3TkB02ixgBOhTvANakDb4xaMXnYUVkNoRFJjQflcqMQhyEKxEHdj3E6N8t8sUQ0mjH/3/JxzlXuz3ul/J90pQ==",
"dev": true,
"engines": {
"node": ">=0.12.0"
}
},
"node_modules/base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
@ -3984,6 +4022,15 @@
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true
},
"node_modules/encoding-japanese": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/encoding-japanese/-/encoding-japanese-2.0.0.tgz",
"integrity": "sha512-++P0RhebUC8MJAwJOsT93dT+5oc5oPImp1HubZpAuCZ5kTLnhuuBhKHj2jJeO/Gj93idPBWmIuQ9QWMe5rX3pQ==",
"dev": true,
"engines": {
"node": ">=8.10.0"
}
},
"node_modules/end-of-stream": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
@ -5276,6 +5323,15 @@
"integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==",
"dev": true
},
"node_modules/he": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
"dev": true,
"bin": {
"he": "bin/he"
}
},
"node_modules/hosted-git-info": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
@ -5323,6 +5379,137 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/html-to-text": {
"version": "9.0.4",
"resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-9.0.4.tgz",
"integrity": "sha512-ckrQ5N2yZS7qSgKxUbqrBZ02NxD5cSy7KuYjCNIf+HWbdzY3fbjYjQsoRIl6TiaZ4+XWOi0ggFP8/pmgCK/o+A==",
"dev": true,
"dependencies": {
"@selderee/plugin-htmlparser2": "^0.10.0",
"deepmerge": "^4.3.0",
"dom-serializer": "^2.0.0",
"htmlparser2": "^8.0.1",
"selderee": "^0.10.0"
},
"engines": {
"node": ">=14"
}
},
"node_modules/html-to-text/node_modules/dom-serializer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
"dev": true,
"dependencies": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.2",
"entities": "^4.2.0"
},
"funding": {
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
}
},
"node_modules/html-to-text/node_modules/domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"dev": true,
"dependencies": {
"domelementtype": "^2.3.0"
},
"engines": {
"node": ">= 4"
},
"funding": {
"url": "https://github.com/fb55/domhandler?sponsor=1"
}
},
"node_modules/html-to-text/node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"dev": true,
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/htmlparser2": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
"integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==",
"dev": true,
"funding": [
"https://github.com/fb55/htmlparser2?sponsor=1",
{
"type": "github",
"url": "https://github.com/sponsors/fb55"
}
],
"dependencies": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.3",
"domutils": "^3.0.1",
"entities": "^4.4.0"
}
},
"node_modules/htmlparser2/node_modules/dom-serializer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
"dev": true,
"dependencies": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.2",
"entities": "^4.2.0"
},
"funding": {
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
}
},
"node_modules/htmlparser2/node_modules/domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"dev": true,
"dependencies": {
"domelementtype": "^2.3.0"
},
"engines": {
"node": ">= 4"
},
"funding": {
"url": "https://github.com/fb55/domhandler?sponsor=1"
}
},
"node_modules/htmlparser2/node_modules/domutils": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
"integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
"dev": true,
"dependencies": {
"dom-serializer": "^2.0.0",
"domelementtype": "^2.3.0",
"domhandler": "^5.0.3"
},
"funding": {
"url": "https://github.com/fb55/domutils?sponsor=1"
}
},
"node_modules/htmlparser2/node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"dev": true,
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/http-signature": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz",
@ -5346,6 +5533,18 @@
"node": ">=8.12.0"
}
},
"node_modules/iconv-lite": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"dev": true,
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
@ -5463,6 +5662,12 @@
"node": ">= 0.4"
}
},
"node_modules/ipv6-normalize": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/ipv6-normalize/-/ipv6-normalize-1.0.1.tgz",
"integrity": "sha512-Bm6H79i01DjgGTCWjUuCjJ6QDo1HB96PT/xCYuyJUP9WFbVDrLSbG4EZCvOCun2rNswZb0c3e4Jt/ws795esHA==",
"dev": true
},
"node_modules/is-array-buffer": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz",
@ -6019,6 +6224,15 @@
"node": "> 0.8"
}
},
"node_modules/leac": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/leac/-/leac-0.6.0.tgz",
"integrity": "sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg==",
"dev": true,
"funding": {
"url": "https://ko-fi.com/killymxi"
}
},
"node_modules/levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@ -6032,6 +6246,30 @@
"node": ">= 0.8.0"
}
},
"node_modules/libbase64": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/libbase64/-/libbase64-1.2.1.tgz",
"integrity": "sha512-l+nePcPbIG1fNlqMzrh68MLkX/gTxk/+vdvAb388Ssi7UuUN31MI44w4Yf33mM3Cm4xDfw48mdf3rkdHszLNew==",
"dev": true
},
"node_modules/libmime": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/libmime/-/libmime-5.2.1.tgz",
"integrity": "sha512-A0z9O4+5q+ZTj7QwNe/Juy1KARNb4WaviO4mYeFC4b8dBT2EEqK2pkM+GC8MVnkOjqhl5nYQxRgnPYRRTNmuSQ==",
"dev": true,
"dependencies": {
"encoding-japanese": "2.0.0",
"iconv-lite": "0.6.3",
"libbase64": "1.2.1",
"libqp": "2.0.1"
}
},
"node_modules/libqp": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/libqp/-/libqp-2.0.1.tgz",
"integrity": "sha512-Ka0eC5LkF3IPNQHJmYBWljJsw0UvM6j+QdKRbWyCdTmYwvIDE6a7bCm0UkTAL/K+3KXK5qXT/ClcInU01OpdLg==",
"dev": true
},
"node_modules/lilconfig": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
@ -6047,6 +6285,15 @@
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
"dev": true
},
"node_modules/linkify-it": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz",
"integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==",
"dev": true,
"dependencies": {
"uc.micro": "^1.0.1"
}
},
"node_modules/listr2": {
"version": "3.14.0",
"resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz",
@ -6316,6 +6563,46 @@
"sourcemap-codec": "^1.4.8"
}
},
"node_modules/mailparser": {
"version": "3.6.4",
"resolved": "https://registry.npmjs.org/mailparser/-/mailparser-3.6.4.tgz",
"integrity": "sha512-4bDgbLdlcBKX8jtVskfn/G93nZo3lf7pyuLbAQ031SHQLihEqxtRwHrb9SXMTqiTkEGlOdpDrZE5uH18O+2A+A==",
"dev": true,
"dependencies": {
"encoding-japanese": "2.0.0",
"he": "1.2.0",
"html-to-text": "9.0.4",
"iconv-lite": "0.6.3",
"libmime": "5.2.1",
"linkify-it": "4.0.1",
"mailsplit": "5.4.0",
"nodemailer": "6.9.1",
"tlds": "1.236.0"
}
},
"node_modules/mailsplit": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/mailsplit/-/mailsplit-5.4.0.tgz",
"integrity": "sha512-wnYxX5D5qymGIPYLwnp6h8n1+6P6vz/MJn5AzGjZ8pwICWssL+CCQjWBIToOVHASmATot4ktvlLo6CyLfOXWYA==",
"dev": true,
"dependencies": {
"libbase64": "1.2.1",
"libmime": "5.2.0",
"libqp": "2.0.1"
}
},
"node_modules/mailsplit/node_modules/libmime": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/libmime/-/libmime-5.2.0.tgz",
"integrity": "sha512-X2U5Wx0YmK0rXFbk67ASMeqYIkZ6E5vY7pNWRKtnNzqjvdYYG8xtPDpCnuUEnPU9vlgNev+JoSrcaKSUaNvfsw==",
"dev": true,
"dependencies": {
"encoding-japanese": "2.0.0",
"iconv-lite": "0.6.3",
"libbase64": "1.2.1",
"libqp": "2.0.1"
}
},
"node_modules/map-obj": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz",
@ -6561,6 +6848,15 @@
"integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==",
"dev": true
},
"node_modules/nodemailer": {
"version": "6.9.1",
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.1.tgz",
"integrity": "sha512-qHw7dOiU5UKNnQpXktdgQ1d3OFgRAekuvbJLcdG5dnEo/GtcTHRYM7+UfJARdOFU9WUQO8OiIamgWPmiSFHYAA==",
"dev": true,
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/normalize-package-data": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz",
@ -6861,6 +7157,19 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/parseley": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/parseley/-/parseley-0.11.0.tgz",
"integrity": "sha512-VfcwXlBWgTF+unPcr7yu3HSSA6QUdDaDnrHcytVfj5Z8azAyKBDrYnSIfeSxlrEayndNcLmrXzg+Vxbo6DWRXQ==",
"dev": true,
"dependencies": {
"leac": "^0.6.0",
"peberminta": "^0.8.0"
},
"funding": {
"url": "https://ko-fi.com/killymxi"
}
},
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@ -6903,6 +7212,15 @@
"node": ">=8"
}
},
"node_modules/peberminta": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/peberminta/-/peberminta-0.8.0.tgz",
"integrity": "sha512-YYEs+eauIjDH5nUEGi18EohWE0nV2QbGTqmxQcqgZ/0g+laPCQmuIqq7EBLVi9uim9zMgfJv0QBZEnQ3uHw/Tw==",
"dev": true,
"funding": {
"url": "https://ko-fi.com/killymxi"
}
},
"node_modules/pend": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
@ -8255,6 +8573,18 @@
"url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
"node_modules/selderee": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/selderee/-/selderee-0.10.0.tgz",
"integrity": "sha512-DEL/RW/f4qLw/NrVg97xKaEBC8IpzIG2fvxnzCp3Z4yk4jQ3MXom+Imav9wApjxX2dfS3eW7x0DXafJr85i39A==",
"dev": true,
"dependencies": {
"parseley": "^0.11.0"
},
"funding": {
"url": "https://ko-fi.com/killymxi"
}
},
"node_modules/semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
@ -8390,6 +8720,42 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
"node_modules/smtp-server": {
"version": "3.11.0",
"resolved": "https://registry.npmjs.org/smtp-server/-/smtp-server-3.11.0.tgz",
"integrity": "sha512-j/W6mEKeMNKuiM9oCAAjm87agPEN1O3IU4cFLT4ZOCyyq3UXN7HiIXF+q7izxJcYSar15B/JaSxcijoPCR8Tag==",
"dev": true,
"dependencies": {
"base32.js": "0.1.0",
"ipv6-normalize": "1.0.1",
"nodemailer": "6.7.3"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/smtp-server/node_modules/nodemailer": {
"version": "6.7.3",
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.7.3.tgz",
"integrity": "sha512-KUdDsspqx89sD4UUyUKzdlUOper3hRkDVkrKh/89G+d9WKsU5ox51NWS4tB1XR5dPUdR4SP0E3molyEfOvSa3g==",
"dev": true,
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/smtp-tester": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/smtp-tester/-/smtp-tester-2.0.1.tgz",
"integrity": "sha512-mJicx4trPmlS2PY/ELG4LIKi8JdOGxnvm0/4oQxXErjwBT/crBUlyiMVzeliu69HHWeWRSOdTcNtlc34+1LodA==",
"dev": true,
"dependencies": {
"mailparser": "^3.5.0",
"smtp-server": "^3.11.0"
},
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@ -9016,6 +9382,15 @@
"@popperjs/core": "^2.9.0"
}
},
"node_modules/tlds": {
"version": "1.236.0",
"resolved": "https://registry.npmjs.org/tlds/-/tlds-1.236.0.tgz",
"integrity": "sha512-oP2PZ3KeGlgpHgsEfrtva3/K9kzsJUNliQSbCfrJ7JMCWFoCdtG+9YMq/g2AnADQ1v5tVlbtvKJZ4KLpy/P6MA==",
"dev": true,
"bin": {
"tlds": "bin.js"
}
},
"node_modules/tmp": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
@ -9156,6 +9531,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/uc.micro": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
"integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==",
"dev": true
},
"node_modules/unbox-primitive": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
@ -11150,6 +11531,27 @@
}
}
},
"@selderee/plugin-htmlparser2": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.10.0.tgz",
"integrity": "sha512-gW69MEamZ4wk1OsOq1nG1jcyhXIQcnrsX5JwixVw/9xaiav8TCyjESAruu1Rz9yyInhgBXxkNwMeygKnN2uxNA==",
"dev": true,
"requires": {
"domhandler": "^5.0.3",
"selderee": "^0.10.0"
},
"dependencies": {
"domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"dev": true,
"requires": {
"domelementtype": "^2.3.0"
}
}
}
},
"@trysound/sax": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
@ -11663,6 +12065,12 @@
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
"base32.js": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/base32.js/-/base32.js-0.1.0.tgz",
"integrity": "sha512-n3TkB02ixgBOhTvANakDb4xaMXnYUVkNoRFJjQflcqMQhyEKxEHdj3E6N8t8sUQ0mjH/3/JxzlXuz3ul/J90pQ==",
"dev": true
},
"base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
@ -12533,6 +12941,12 @@
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true
},
"encoding-japanese": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/encoding-japanese/-/encoding-japanese-2.0.0.tgz",
"integrity": "sha512-++P0RhebUC8MJAwJOsT93dT+5oc5oPImp1HubZpAuCZ5kTLnhuuBhKHj2jJeO/Gj93idPBWmIuQ9QWMe5rX3pQ==",
"dev": true
},
"end-of-stream": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
@ -13508,6 +13922,12 @@
"integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==",
"dev": true
},
"he": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
"dev": true
},
"hosted-git-info": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
@ -13545,6 +13965,98 @@
"integrity": "sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==",
"dev": true
},
"html-to-text": {
"version": "9.0.4",
"resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-9.0.4.tgz",
"integrity": "sha512-ckrQ5N2yZS7qSgKxUbqrBZ02NxD5cSy7KuYjCNIf+HWbdzY3fbjYjQsoRIl6TiaZ4+XWOi0ggFP8/pmgCK/o+A==",
"dev": true,
"requires": {
"@selderee/plugin-htmlparser2": "^0.10.0",
"deepmerge": "^4.3.0",
"dom-serializer": "^2.0.0",
"htmlparser2": "^8.0.1",
"selderee": "^0.10.0"
},
"dependencies": {
"dom-serializer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
"dev": true,
"requires": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.2",
"entities": "^4.2.0"
}
},
"domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"dev": true,
"requires": {
"domelementtype": "^2.3.0"
}
},
"entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"dev": true
}
}
},
"htmlparser2": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
"integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==",
"dev": true,
"requires": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.3",
"domutils": "^3.0.1",
"entities": "^4.4.0"
},
"dependencies": {
"dom-serializer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
"dev": true,
"requires": {
"domelementtype": "^2.3.0",
"domhandler": "^5.0.2",
"entities": "^4.2.0"
}
},
"domhandler": {
"version": "5.0.3",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
"dev": true,
"requires": {
"domelementtype": "^2.3.0"
}
},
"domutils": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
"integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
"dev": true,
"requires": {
"dom-serializer": "^2.0.0",
"domelementtype": "^2.3.0",
"domhandler": "^5.0.3"
}
},
"entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"dev": true
}
}
},
"http-signature": {
"version": "1.3.6",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz",
@ -13562,6 +14074,15 @@
"integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==",
"dev": true
},
"iconv-lite": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
"dev": true,
"requires": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
}
},
"ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
@ -13641,6 +14162,12 @@
"side-channel": "^1.0.4"
}
},
"ipv6-normalize": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/ipv6-normalize/-/ipv6-normalize-1.0.1.tgz",
"integrity": "sha512-Bm6H79i01DjgGTCWjUuCjJ6QDo1HB96PT/xCYuyJUP9WFbVDrLSbG4EZCvOCun2rNswZb0c3e4Jt/ws795esHA==",
"dev": true
},
"is-array-buffer": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz",
@ -14045,6 +14572,12 @@
"integrity": "sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==",
"dev": true
},
"leac": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/leac/-/leac-0.6.0.tgz",
"integrity": "sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg==",
"dev": true
},
"levn": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
@ -14055,6 +14588,30 @@
"type-check": "~0.4.0"
}
},
"libbase64": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/libbase64/-/libbase64-1.2.1.tgz",
"integrity": "sha512-l+nePcPbIG1fNlqMzrh68MLkX/gTxk/+vdvAb388Ssi7UuUN31MI44w4Yf33mM3Cm4xDfw48mdf3rkdHszLNew==",
"dev": true
},
"libmime": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/libmime/-/libmime-5.2.1.tgz",
"integrity": "sha512-A0z9O4+5q+ZTj7QwNe/Juy1KARNb4WaviO4mYeFC4b8dBT2EEqK2pkM+GC8MVnkOjqhl5nYQxRgnPYRRTNmuSQ==",
"dev": true,
"requires": {
"encoding-japanese": "2.0.0",
"iconv-lite": "0.6.3",
"libbase64": "1.2.1",
"libqp": "2.0.1"
}
},
"libqp": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/libqp/-/libqp-2.0.1.tgz",
"integrity": "sha512-Ka0eC5LkF3IPNQHJmYBWljJsw0UvM6j+QdKRbWyCdTmYwvIDE6a7bCm0UkTAL/K+3KXK5qXT/ClcInU01OpdLg==",
"dev": true
},
"lilconfig": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
@ -14067,6 +14624,15 @@
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
"dev": true
},
"linkify-it": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz",
"integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==",
"dev": true,
"requires": {
"uc.micro": "^1.0.1"
}
},
"listr2": {
"version": "3.14.0",
"resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz",
@ -14272,6 +14838,48 @@
"sourcemap-codec": "^1.4.8"
}
},
"mailparser": {
"version": "3.6.4",
"resolved": "https://registry.npmjs.org/mailparser/-/mailparser-3.6.4.tgz",
"integrity": "sha512-4bDgbLdlcBKX8jtVskfn/G93nZo3lf7pyuLbAQ031SHQLihEqxtRwHrb9SXMTqiTkEGlOdpDrZE5uH18O+2A+A==",
"dev": true,
"requires": {
"encoding-japanese": "2.0.0",
"he": "1.2.0",
"html-to-text": "9.0.4",
"iconv-lite": "0.6.3",
"libmime": "5.2.1",
"linkify-it": "4.0.1",
"mailsplit": "5.4.0",
"nodemailer": "6.9.1",
"tlds": "1.236.0"
}
},
"mailsplit": {
"version": "5.4.0",
"resolved": "https://registry.npmjs.org/mailsplit/-/mailsplit-5.4.0.tgz",
"integrity": "sha512-wnYxX5D5qymGIPYLwnp6h8n1+6P6vz/MJn5AzGjZ8pwICWssL+CCQjWBIToOVHASmATot4ktvlLo6CyLfOXWYA==",
"dev": true,
"requires": {
"libbase64": "1.2.1",
"libmime": "5.2.0",
"libqp": "2.0.1"
},
"dependencies": {
"libmime": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/libmime/-/libmime-5.2.0.tgz",
"integrity": "sha512-X2U5Wx0YmK0rXFbk67ASMeqYIkZ6E5vY7pNWRKtnNzqjvdYYG8xtPDpCnuUEnPU9vlgNev+JoSrcaKSUaNvfsw==",
"dev": true,
"requires": {
"encoding-japanese": "2.0.0",
"iconv-lite": "0.6.3",
"libbase64": "1.2.1",
"libqp": "2.0.1"
}
}
}
},
"map-obj": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz",
@ -14463,6 +15071,12 @@
"integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==",
"dev": true
},
"nodemailer": {
"version": "6.9.1",
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.1.tgz",
"integrity": "sha512-qHw7dOiU5UKNnQpXktdgQ1d3OFgRAekuvbJLcdG5dnEo/GtcTHRYM7+UfJARdOFU9WUQO8OiIamgWPmiSFHYAA==",
"dev": true
},
"normalize-package-data": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz",
@ -14675,6 +15289,16 @@
"lines-and-columns": "^1.1.6"
}
},
"parseley": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/parseley/-/parseley-0.11.0.tgz",
"integrity": "sha512-VfcwXlBWgTF+unPcr7yu3HSSA6QUdDaDnrHcytVfj5Z8azAyKBDrYnSIfeSxlrEayndNcLmrXzg+Vxbo6DWRXQ==",
"dev": true,
"requires": {
"leac": "^0.6.0",
"peberminta": "^0.8.0"
}
},
"path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@ -14705,6 +15329,12 @@
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
"dev": true
},
"peberminta": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/peberminta/-/peberminta-0.8.0.tgz",
"integrity": "sha512-YYEs+eauIjDH5nUEGi18EohWE0nV2QbGTqmxQcqgZ/0g+laPCQmuIqq7EBLVi9uim9zMgfJv0QBZEnQ3uHw/Tw==",
"dev": true
},
"pend": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
@ -15608,6 +16238,15 @@
"dev": true,
"optional": true
},
"selderee": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/selderee/-/selderee-0.10.0.tgz",
"integrity": "sha512-DEL/RW/f4qLw/NrVg97xKaEBC8IpzIG2fvxnzCp3Z4yk4jQ3MXom+Imav9wApjxX2dfS3eW7x0DXafJr85i39A==",
"dev": true,
"requires": {
"parseley": "^0.11.0"
}
},
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
@ -15708,6 +16347,35 @@
}
}
},
"smtp-server": {
"version": "3.11.0",
"resolved": "https://registry.npmjs.org/smtp-server/-/smtp-server-3.11.0.tgz",
"integrity": "sha512-j/W6mEKeMNKuiM9oCAAjm87agPEN1O3IU4cFLT4ZOCyyq3UXN7HiIXF+q7izxJcYSar15B/JaSxcijoPCR8Tag==",
"dev": true,
"requires": {
"base32.js": "0.1.0",
"ipv6-normalize": "1.0.1",
"nodemailer": "6.7.3"
},
"dependencies": {
"nodemailer": {
"version": "6.7.3",
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.7.3.tgz",
"integrity": "sha512-KUdDsspqx89sD4UUyUKzdlUOper3hRkDVkrKh/89G+d9WKsU5ox51NWS4tB1XR5dPUdR4SP0E3molyEfOvSa3g==",
"dev": true
}
}
},
"smtp-tester": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/smtp-tester/-/smtp-tester-2.0.1.tgz",
"integrity": "sha512-mJicx4trPmlS2PY/ELG4LIKi8JdOGxnvm0/4oQxXErjwBT/crBUlyiMVzeliu69HHWeWRSOdTcNtlc34+1LodA==",
"dev": true,
"requires": {
"mailparser": "^3.5.0",
"smtp-server": "^3.11.0"
}
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@ -16206,6 +16874,12 @@
"@popperjs/core": "^2.9.0"
}
},
"tlds": {
"version": "1.236.0",
"resolved": "https://registry.npmjs.org/tlds/-/tlds-1.236.0.tgz",
"integrity": "sha512-oP2PZ3KeGlgpHgsEfrtva3/K9kzsJUNliQSbCfrJ7JMCWFoCdtG+9YMq/g2AnADQ1v5tVlbtvKJZ4KLpy/P6MA==",
"dev": true
},
"tmp": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
@ -16315,6 +16989,12 @@
"is-typed-array": "^1.1.9"
}
},
"uc.micro": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
"integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==",
"dev": true
},
"unbox-primitive": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",

View File

@ -105,6 +105,7 @@
"rollup-plugin-vue": "^6.0.0",
"rtlcss": "^3.5.0",
"sass-embedded": "^1.59.3",
"smtp-tester": "^2.0.1",
"stylelint": "^14.16.1",
"stylelint-config-standard": "^24.0.0",
"stylelint-order": "^5.0.0",

View File

@ -0,0 +1,33 @@
describe('Test in backend that the application configuration', () => {
beforeEach(() => {
cy.task('clearEmails');
cy.doAdministratorLogin();
cy.visit('/administrator/index.php?option=com_config');
});
it('has a title', () => {
cy.contains('h1', 'Global Configuration').should('exist');
});
it('can display the configuration', () => {
cy.contains('label', 'Site Name').should('exist');
});
it('can send a test mail', () => {
cy.get('#configTabs div[role="tablist"] button[aria-controls="page-server"]').click();
cy.get('#jform_mailer').select('smtp');
cy.get('#jform_smtphost').clear().type(Cypress.env('smtp_host'));
cy.get('#jform_smtpport').clear().type(Cypress.env('smtp_port'));
cy.get('#jform_smtpsecure').select('none');
cy.get('#sendtestmail').click();
cy.task('getMails').then((mails) => {
cy.get('#system-message-container').should('contain.text', 'The email was sent to');
cy.wrap(mails).should('have.lengthOf', 1);
cy.wrap(mails[0].body).should('have.string', 'This is a test mail sent using');
cy.wrap(mails[0].sender).should('equal', Cypress.env('email'));
cy.wrap(mails[0].receivers).should('have.property', Cypress.env('email'));
});
});
});

View File

@ -27,8 +27,11 @@ describe('Install Joomla', () => {
// Update to the correct secret for the API tests because of the bearer token
let content = fileContent.replace(/^.*\$secret.*$/mg, "public $secret = 'tEstValue';");
// Turn off mailing
content = content.replace(/^.*\$mailonline.*$/mg, 'public $mailonline = false;');
// Setup mailing
content = content.replace(/^.*\$mailonline.*$/mg, 'public $mailonline = true;');
content = content.replace(/^.*\$mailer.*$/mg, 'public $mailer = \'smtp\';');
content = content.replace(/^.*\$smtphost.*$/mg, `public $smtphost = '${Cypress.env('smtp_host')}';`);
content = content.replace(/^.*\$smtpport.*$/mg, `public $smtpport = '${Cypress.env('smtp_port')}';`);
// Write the modified content back to the configuration file
cy.task('writeFile', { path: 'configuration.php', content });

View File

@ -1,4 +1,4 @@
describe('Test in frontend that the users profile view', () => {
describe('Test in frontend that the users profile view edit layout', () => {
it('can display a user form without a menu item', () => {
cy.doFrontendLogin();
cy.visit('/index.php?option=com_users&view=profile&layout=edit');

View File

@ -1,14 +1,26 @@
describe('Test in frontend that the users remind view', () => {
beforeEach(() => cy.task('clearEmails'));
it('can send a reminder email for a test user in a menu item', () => {
cy.db_createUser({ name: 'test user', email: 'test@example.com' })
.then(() => cy.db_createMenuItem({ title: 'Automated test reminder', link: 'index.php?option=com_users&view=remind' }))
.then(() => cy.db_createMenuItem({
title: 'Automated test reminder', alias: 'test-reminder', path: 'test-reminder', link: 'index.php?option=com_users&view=remind',
}))
.then(() => {
cy.visit('/');
cy.get('a:contains(Automated test reminder)').click();
cy.get('#jform_email').type('test@example.com');
cy.get('.controls > .btn').click();
cy.get('#system-message-container').should('contain.text', 'If the email address you entered is registered on this site you will shortly receive an email with a reminder.');
cy.task('getMails').then((mails) => {
cy.get('#system-message-container').should('contain.text', 'If the email address you entered is registered on this site you will shortly receive an email with a reminder.');
cy.wrap(mails).should('have.lengthOf', 1);
cy.wrap(mails[0].body).should('have.string', 'A username reminder has been requested');
cy.wrap(mails[0].body).should('have.string', '/test-reminder');
cy.wrap(mails[0].sender).should('equal', Cypress.env('email'));
cy.wrap(mails[0].receivers).should('have.property', 'test@example.com');
});
});
});
@ -19,7 +31,27 @@ describe('Test in frontend that the users remind view', () => {
cy.get('#jform_email').type('test@example.com');
cy.get('.controls > .btn').click();
cy.get('#system-message-container').should('contain.text', 'If the email address you entered is registered on this site you will shortly receive an email with a reminder.');
cy.task('getMails').then((mails) => {
cy.get('#system-message-container').should('contain.text', 'If the email address you entered is registered on this site you will shortly receive an email with a reminder.');
cy.wrap(mails).should('have.lengthOf', 1);
cy.wrap(mails[0].body).should('have.string', 'A username reminder has been requested');
cy.wrap(mails[0].body).should('have.string', '/component/users/login');
cy.wrap(mails[0].sender).should('equal', Cypress.env('email'));
cy.wrap(mails[0].receivers).should('have.property', 'test@example.com');
});
});
});
it('can not send a reminder email for a user which is not registered', () => {
cy.visit('/index.php?option=com_users&view=remind');
cy.get('#jform_email').type('test@example.com');
cy.get('.controls > .btn').click();
cy.task('getMails').then((mails) => {
cy.get('#system-message-container').should('contain.text', 'If the email address you entered is registered on this site you will shortly receive an email with a reminder.');
cy.wrap(mails).should('have.lengthOf', 0);
});
});
});

View File

@ -1,4 +1,6 @@
describe('Test in frontend that the users reset view', () => {
beforeEach(() => cy.task('clearEmails'));
it('can send a reset email for a test user without a menu item', () => {
cy.db_createUser({ email: 'test@example.com' })
.then(() => {
@ -6,20 +8,50 @@ describe('Test in frontend that the users reset view', () => {
cy.get('#jform_email').type('test@example.com');
cy.get('.controls > .btn').click();
cy.get('#system-message-container').should('contain.text', 'If the email address you entered is registered on this site you will shortly receive an email with a link to reset the password for your account.');
cy.task('getMails').then((mails) => {
cy.get('#system-message-container').should('contain.text', 'If the email address you entered is registered on this site you will shortly receive an email with a link to reset the password for your account.');
cy.wrap(mails).should('have.lengthOf', 1);
cy.wrap(mails[0].body).should('have.string', 'To reset your password, you will need to submit this verification code');
cy.wrap(mails[0].body).should('have.string', '/component/users/reset');
cy.wrap(mails[0].sender).should('equal', Cypress.env('email'));
cy.wrap(mails[0].receivers).should('have.property', 'test@example.com');
});
});
});
it('can send a reset email for a test user in a menu item', () => {
cy.db_createUser({ email: 'test@example.com' })
.then(() => cy.db_createMenuItem({ title: 'Automated test reset', link: 'index.php?option=com_users&view=reset' }))
.then(() => cy.db_createMenuItem({
title: 'Automated test reset', alias: 'test-reset', path: 'test-reset', link: 'index.php?option=com_users&view=reset',
}))
.then(() => {
cy.visit('/');
cy.get('a:contains(Automated test reset)').click();
cy.get('#jform_email').type('test@example.com');
cy.get('.controls > .btn').click();
cy.get('#system-message-container').should('contain.text', 'If the email address you entered is registered on this site you will shortly receive an email with a link to reset the password for your account.');
cy.task('getMails').then((mails) => {
cy.get('#system-message-container').should('contain.text', 'If the email address you entered is registered on this site you will shortly receive an email with a link to reset the password for your account.');
cy.wrap(mails).should('have.lengthOf', 1);
cy.wrap(mails[0].body).should('have.string', 'To reset your password, you will need to submit this verification code');
cy.wrap(mails[0].body).should('have.string', '/test-reset');
cy.wrap(mails[0].sender).should('equal', Cypress.env('email'));
cy.wrap(mails[0].receivers).should('have.property', 'test@example.com');
});
});
});
it('can not send a reset email for a user which is not registered', () => {
cy.visit('/index.php?option=com_users&view=reset');
cy.get('#jform_email').type('test@example.com');
cy.get('.controls > .btn').click();
cy.task('getMails').then((mails) => {
cy.get('#system-message-container').should('contain.text', 'If the email address you entered is registered on this site you will shortly receive an email with a link to reset the password for your account.');
cy.wrap(mails).should('have.lengthOf', 0);
});
});
});

145
tests/System/plugins/db.js Normal file
View File

@ -0,0 +1,145 @@
const mysql = require('mysql');
const postgres = require('postgres');
// Items cache which are added by an insert statement
let insertedItems = [];
/**
* Does run the given query against the database from the configuration. It caches all inserted items.
*
* @param {string} query
* @param {object} config The config
* @returns Promise
*/
function queryTestDB(joomlaQuery, config) {
// Substitute the joomla table prefix
let query = joomlaQuery.replaceAll('#__', config.env.db_prefix);
// Parse the table name
const tableNameOfInsert = query.match(/insert\s+into\s+(.*?)\s/i);
// Find an inserted item
let insertItem = tableNameOfInsert && tableNameOfInsert.length > 1 && insertedItems.find((item) => item.table === tableNameOfInsert[1]);
// If it is an insert query, but there is no cache object, create one
if (tableNameOfInsert && tableNameOfInsert.length > 1 && !insertItem) {
insertItem = { table: tableNameOfInsert[1], rows: [] };
// Push it to the cache
insertedItems.push(insertItem);
}
// Check if the DB is from postgres
if (config.env.db_type === 'pgsql' || config.env.db_type === 'PostgreSQL (PDO)') {
const connection = postgres({
host: config.env.db_host,
database: config.env.db_name,
username: config.env.db_user,
password: config.env.db_password,
idle_timeout: 1,
max_lifetime: 1,
});
// Postgres delivers the data direct as result of the insert query
if (insertItem) {
query += ' returning *';
}
// Postgres needs double quotes
query = query.replaceAll('`', '"');
return connection.unsafe(query).then((result) => {
// Select query should always return an array
if (query.indexOf('SELECT') === 0 && !Array.isArray(result)) {
return [result];
}
if (!insertItem || result.length === 0) {
return result;
}
// Push the id to the cache when it is an insert operation
if (insertItem && result.length && result[0].id) {
insertItem.rows.push(result[0].id);
}
// Normalize the object
return { insertId: result[0].id };
});
}
// Return a promise which runs the query
return new Promise((resolve, reject) => {
// Create the connection and connect
const connection = mysql.createConnection({
host: config.env.db_host,
user: config.env.db_user,
password: config.env.db_password,
database: config.env.db_name,
});
// Perform the query
connection.query(query, (error, results) => {
connection.end();
// Reject when an error
if (error && error.errno) {
return reject(error);
}
// Push the id to the cache when it is an insert operation
if (insertItem && results && results.insertId) {
insertItem.rows.push(results.insertId);
}
// Resolve the result
return resolve(results);
});
});
}
/**
* Deletes the inserted items from the database.
*
* @param {object} config The configuration
*
* @returns null
*/
function deleteInsertedItems(config) {
// Holds the promises for the deleted items
const promises = [];
// Loop over the cached items
insertedItems.forEach((item) => {
// When there is nothing to delete, ignore it
if (item.rows.length < 1) {
return;
}
// Delete the items from the database
promises.push(queryTestDB(`DELETE FROM ${item.table} WHERE id IN (${item.rows.join(',')})`, config).then(() => {
// Cleanup some tables we do not have control over from inserted items
if (item.table === `${config.env.db_prefix}users`) {
promises.push(queryTestDB(`DELETE FROM #__user_usergroup_map WHERE user_id IN (${item.rows.join(',')})`, config));
promises.push(queryTestDB(`DELETE FROM #__user_profiles WHERE user_id IN (${item.rows.join(',')})`, config));
}
if (item.table === `${config.env.db_prefix}content`) {
promises.push(queryTestDB(`DELETE FROM #__content_frontpage WHERE content_id IN (${item.rows.join(',')})`, config));
promises.push(queryTestDB(`DELETE FROM #__workflow_associations WHERE item_id IN (${item.rows.join(',')}) AND extension = 'com_content.article'`, config));
}
if (item.table === `${config.env.db_prefix}modules`) {
promises.push(queryTestDB(`DELETE FROM #__modules_menu WHERE moduleid IN (${item.rows.join(',')})`, config));
}
}));
});
// Clear the cache
insertedItems = [];
// Return the promise which waits for all delete queries
return Promise.all(promises);
}
module.exports = { queryTestDB, deleteInsertedItems };

View File

@ -0,0 +1,36 @@
const fs = require('fs');
const fspath = require('path');
/**
* Deletes a folder with the given path recursive.
*
* @param {string} path The path
* @param {object} config The config
*
* @returns null
*/
function deleteFolder(path, config) {
fs.rmSync(`${config.env.cmsPath}/${path}`, { recursive: true, force: true });
return null;
}
/**
* Writes the given content to a file for the given path.
*
* @param {string} path The path
* @param {mixed} content The content
* @param {object} config The config
*
* @returns null
*/
function writeFile(path, content, config) {
fs.mkdirSync(fspath.dirname(`${config.env.cmsPath}/${path}`), { recursive: true, mode: 0o777 });
fs.chmod(fspath.dirname(`${config.env.cmsPath}/${path}`), 0o777);
fs.writeFileSync(`${config.env.cmsPath}/${path}`, content);
fs.chmod(`${config.env.cmsPath}/${path}`, 0o777);
return null;
}
module.exports = { writeFile, deleteFolder };

View File

@ -1,180 +1,6 @@
const mysql = require('mysql');
const postgres = require('postgres');
const fs = require('fs');
const fspath = require('path');
/**
* Deletes a folder with the given path recursive.
*
* @param {string} path The path
* @param {object} config The config
*
* @returns null
*/
function deleteFolder(path, config) {
fs.rmSync(`${config.env.cmsPath}/${path}`, { recursive: true, force: true });
return null;
}
/**
* Writes the given content to a file for the given path.
*
* @param {string} path The path
* @param {mixed} content The content
* @param {object} config The config
*
* @returns null
*/
function writeFile(path, content, config) {
fs.mkdirSync(fspath.dirname(`${config.env.cmsPath}/${path}`), { recursive: true, mode: 0o777 });
fs.chmod(fspath.dirname(`${config.env.cmsPath}/${path}`), 0o777);
fs.writeFileSync(`${config.env.cmsPath}/${path}`, content);
fs.chmod(`${config.env.cmsPath}/${path}`, 0o777);
return null;
}
// Rows cache of items which got inserted
let insertedItems = [];
/**
* Does run the given query against the database from the configuration. It caches all inserted items.
*
* @param {string} query
* @param {object} config The config
* @returns Promise
*/
function queryTestDB(joomlaQuery, config) {
// Substitute the joomla table prefix
let query = joomlaQuery.replaceAll('#__', config.env.db_prefix);
// Parse the table name
const tableNameOfInsert = query.match(/insert\s+into\s+(.*?)\s/i);
// Find an inserted item
let insertItem = tableNameOfInsert && tableNameOfInsert.length > 1 && insertedItems.find((item) => item.table === tableNameOfInsert[1]);
// If it is an insert query, but there is no cache object, create one
if (tableNameOfInsert && tableNameOfInsert.length > 1 && !insertItem) {
insertItem = { table: tableNameOfInsert[1], rows: [] };
// Push it to the cache
insertedItems.push(insertItem);
}
// Check if the DB is from postgres
if (config.env.db_type === 'pgsql' || config.env.db_type === 'PostgreSQL (PDO)') {
const connection = postgres({
host: config.env.db_host,
database: config.env.db_name,
username: config.env.db_user,
password: config.env.db_password,
idle_timeout: 1,
max_lifetime: 1,
});
// Postgres delivers the data direct as result of the insert query
if (insertItem) {
query += ' returning *';
}
// Postgres needs double quotes
query = query.replaceAll('\`', '"');
return connection.unsafe(query).then((result) => {
// Select query should always return an array
if (query.indexOf('SELECT') === 0 && !Array.isArray(result)) {
return [result];
}
if (!insertItem || result.length === 0) {
return result;
}
// Push the id to the cache when it is an insert operation
if (insertItem && result.length && result[0].id) {
insertItem.rows.push(result[0].id);
}
// Normalize the object
return { insertId: result[0].id };
});
}
// Return a promise when resolves the query
return new Promise((resolve, reject) => {
// Create the connection and connect
const connection = mysql.createConnection({
host: config.env.db_host,
user: config.env.db_user,
password: config.env.db_password,
database: config.env.db_name,
});
// Perform the query
connection.query(query, (error, results) => {
connection.end();
// Reject when an error
if (error && error.errno) {
return reject(error);
}
// Push the id to the cache when it is an insert operation
if (insertItem && results && results.insertId) {
insertItem.rows.push(results.insertId);
}
// Resolve the result
return resolve(results);
});
});
}
/**
* Deletes the inserted items from the database.
*
* @param {object} config The configuration
*
* @returns null
*/
function deleteInsertedItems(config) {
// Holds the promises for the deleted items
const promises = [];
// Loop over the cached items
insertedItems.forEach((item) => {
// When there is nothing to delete, ignore it
if (item.rows.length < 1) {
return;
}
// Delete the items from the database
promises.push(queryTestDB(`DELETE FROM ${item.table} WHERE id IN (${item.rows.join(',')})`, config).then(() => {
// Cleanup some tables we do not have control over from inserted items
if (item.table === `${config.env.db_prefix}users`) {
promises.push(queryTestDB(`DELETE FROM #__user_usergroup_map WHERE user_id IN (${item.rows.join(',')})`, config));
promises.push(queryTestDB(`DELETE FROM #__user_profiles WHERE user_id IN (${item.rows.join(',')})`, config));
}
if (item.table === `${config.env.db_prefix}content`) {
promises.push(queryTestDB(`DELETE FROM #__content_frontpage WHERE content_id IN (${item.rows.join(',')})`, config));
promises.push(queryTestDB(`DELETE FROM #__workflow_associations WHERE item_id IN (${item.rows.join(',')}) AND extension = 'com_content.article'`, config));
}
if (item.table === `${config.env.db_prefix}modules`) {
promises.push(queryTestDB(`DELETE FROM #__modules_menu WHERE moduleid IN (${item.rows.join(',')})`, config));
}
}));
});
// Clear the cache
insertedItems = [];
// Return the promise which waits for all delete queries
return Promise.all(promises);
}
const mail = require('./mail');
const fs = require('./fs');
const db = require('./db');
/**
* Does the setup of the plugins.
@ -186,10 +12,13 @@ function deleteInsertedItems(config) {
*/
function setupPlugins(on, config) {
on('task', {
queryDB: (query) => queryTestDB(query, config),
cleanupDB: () => deleteInsertedItems(config),
writeFile: ({ path, content }) => writeFile(path, content, config),
deleteFolder: (path) => deleteFolder(path, config),
queryDB: (query) => db.queryTestDB(query, config),
cleanupDB: () => db.deleteInsertedItems(config),
writeFile: ({ path, content }) => fs.writeFile(path, content, config),
deleteFolder: (path) => fs.deleteFolder(path, config),
getMails: () => mail.getMails(),
clearEmails: () => mail.clearEmails(),
startMailServer: () => mail.startMailServer(config),
});
}

View File

@ -0,0 +1,67 @@
const mailTester = require('smtp-tester');
// The mail server instance
let mailServer = null;
// The cached mails
let cachedMails = [];
/**
* Returns all cached mails. It waits for maximum 3 seconds till a mail arrives.
*
* @returns a promise which resolves the cached mails
*/
async function getMails() {
// Waiting here maximum 3 seconds to get a mail
for (let i = 0; i < 3; i += 1) {
if (cachedMails.length !== 0) {
break;
}
// Sleep for a second
/* eslint-disable no-await-in-loop */
await new Promise((r) => { setTimeout(r, 1000); });
/* eslint-enable no-await-in-loop */
}
return new Promise((resolve) => { resolve(cachedMails); });
}
/**
* Clears the cached mails.
*
* @returns null
*/
function clearEmails() {
cachedMails = [];
return null;
}
/**
* Starts the mail server.
*
* @returns null
*/
function startMailServer(config) {
// Check if the mail server is already started
if (mailServer !== null) {
return null;
}
// Start the mail server on the configured port
mailServer = mailTester.init(config.env.smtp_port);
// Uncomment the next line when you want to see the incoming mails while writing the tests
// mailServer.module('logAll');
// Listen to incoming mails and add them to the internal cache
mailServer.bind((addr, id, email) => cachedMails.push(email));
// Reset the cached mails
cachedMails = [];
return null;
}
module.exports = { getMails, clearEmails, startMailServer };

View File

@ -2,6 +2,7 @@ import './commands';
import 'joomla-cypress';
before(() => {
cy.task('startMailServer');
Cypress.on('uncaught:exception', (err, runnable) => {
console.log(`err :${err}`);
console.log(`runnable :${runnable}`);