Replace wait-until-promise with utility method

and bump default timeout

Also let `_converse.api.waitUntil` use it if a function is passed in.
This commit is contained in:
JC Brand 2019-07-11 22:50:30 +02:00
parent 8a98ef87fe
commit a1630b5c1f
30 changed files with 1020 additions and 1207 deletions

664
package-lock.json generated
View File

@ -873,25 +873,6 @@
"resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz",
"integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==",
"dev": true
},
"get-stream": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
"integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
"dev": true,
"requires": {
"pump": "^3.0.0"
}
},
"pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
"dev": true,
"requires": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
}
}
}
},
@ -918,25 +899,6 @@
"integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==",
"dev": true
},
"get-stream": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
"integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
"dev": true,
"requires": {
"pump": "^3.0.0"
}
},
"pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
"dev": true,
"requires": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
}
},
"semver": {
"version": "5.7.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
@ -971,9 +933,9 @@
}
},
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
"integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==",
"dev": true
}
}
@ -1013,21 +975,6 @@
"which": "^1.3.1"
},
"dependencies": {
"bluebird": {
"version": "3.5.5",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz",
"integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==",
"dev": true
},
"get-stream": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
"integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
"dev": true,
"requires": {
"pump": "^3.0.0"
}
},
"glob": {
"version": "7.1.4",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
@ -1051,20 +998,10 @@
"yallist": "^3.0.2"
}
},
"pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
"dev": true,
"requires": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
}
},
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
"integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==",
"dev": true
},
"semver": {
@ -1189,64 +1126,6 @@
"chalk": "^2.3.1",
"execa": "^1.0.0",
"strong-log-transformer": "^2.0.0"
},
"dependencies": {
"cross-spawn": {
"version": "6.0.5",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
"integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
"dev": true,
"requires": {
"nice-try": "^1.0.4",
"path-key": "^2.0.1",
"semver": "^5.5.0",
"shebang-command": "^1.2.0",
"which": "^1.2.9"
}
},
"execa": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
"integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
"dev": true,
"requires": {
"cross-spawn": "^6.0.0",
"get-stream": "^4.0.0",
"is-stream": "^1.1.0",
"npm-run-path": "^2.0.0",
"p-finally": "^1.0.0",
"signal-exit": "^3.0.0",
"strip-eof": "^1.0.0"
}
},
"get-stream": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
"integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
"dev": true,
"requires": {
"pump": "^3.0.0"
}
},
"pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
"dev": true,
"requires": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
}
},
"which": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
"dev": true,
"requires": {
"isexe": "^2.0.0"
}
}
}
},
"@lerna/clean": {
@ -1318,64 +1197,6 @@
"is-ci": "^1.0.10",
"lodash": "^4.17.5",
"npmlog": "^4.1.2"
},
"dependencies": {
"cross-spawn": {
"version": "6.0.5",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
"integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
"dev": true,
"requires": {
"nice-try": "^1.0.4",
"path-key": "^2.0.1",
"semver": "^5.5.0",
"shebang-command": "^1.2.0",
"which": "^1.2.9"
}
},
"execa": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
"integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
"dev": true,
"requires": {
"cross-spawn": "^6.0.0",
"get-stream": "^4.0.0",
"is-stream": "^1.1.0",
"npm-run-path": "^2.0.0",
"p-finally": "^1.0.0",
"signal-exit": "^3.0.0",
"strip-eof": "^1.0.0"
}
},
"get-stream": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
"integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
"dev": true,
"requires": {
"pump": "^3.0.0"
}
},
"pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
"dev": true,
"requires": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
}
},
"which": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
"dev": true,
"requires": {
"isexe": "^2.0.0"
}
}
}
},
"@lerna/conventional-commits": {
@ -1394,27 +1215,6 @@
"npmlog": "^4.1.2",
"pify": "^3.0.0",
"semver": "^5.5.0"
},
"dependencies": {
"get-stream": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
"integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
"dev": true,
"requires": {
"pump": "^3.0.0"
}
},
"pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
"dev": true,
"requires": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
}
}
}
},
"@lerna/create": {
@ -2050,12 +1850,12 @@
"dev": true
},
"@octokit/endpoint": {
"version": "5.1.7",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-5.1.7.tgz",
"integrity": "sha512-MfsXHx9z9EPxLYSf7PYuzWvVZTotx+/QTFk7UMp4Fv83k3QrvmovEjP0pl141g+Uq/w9CcDuuXhsiq4X3oxVsA==",
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-5.2.1.tgz",
"integrity": "sha512-GoUsRSRhtbCQugRY8eDWg5BnsczUZNq00qArrP7tKPHFmvz2KzJ8DoEq6IAQhLGwAOBHbZQ/Zml3DiaEKAWwkA==",
"dev": true,
"requires": {
"deepmerge": "3.2.1",
"deepmerge": "4.0.0",
"is-plain-object": "^3.0.0",
"universal-user-agent": "^2.1.0",
"url-template": "^2.0.8"
@ -2085,9 +1885,9 @@
"dev": true
},
"@octokit/request": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-4.1.1.tgz",
"integrity": "sha512-LOyL0i3oxRo418EXRSJNk/3Q4I0/NKawTn6H/CQp+wnrG1UFLGu080gSsgnWobhPo5BpUNgSQ5BRk5FOOJhD1Q==",
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.0.0.tgz",
"integrity": "sha512-eAknm2Aq+/uQDLHUn7KHHpXB7A/NFfWgaVN+ZhC6mQlCNRzCv242eLYgt6cC4h2DZL7mM+QidS/UtZVwYvQXBw==",
"dev": true,
"requires": {
"@octokit/endpoint": "^5.1.0",
@ -2127,15 +1927,15 @@
}
},
"@octokit/rest": {
"version": "16.28.2",
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.28.2.tgz",
"integrity": "sha512-csuYiHvJ1P/GFDadVn0QhwO83R1+YREjcwCY7ZIezB6aJTRIEidJZj+R7gAkUhT687cqYb4cXTZsDVu9F+Fmug==",
"version": "16.28.3",
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-16.28.3.tgz",
"integrity": "sha512-hzM2VvVn9o0+sS08y2pp33UF5tKy0XdR2z+/AFD583TjhHlX/9Lmdv3SmRiz0UC6rNqNXe1X7BiZ/QNUwVm27Q==",
"dev": true,
"requires": {
"@octokit/request": "^4.0.1",
"@octokit/request": "^5.0.0",
"@octokit/request-error": "^1.0.2",
"atob-lite": "^2.0.0",
"before-after-hook": "^1.4.0",
"before-after-hook": "^2.0.0",
"btoa-lite": "^1.0.0",
"deprecation": "^2.0.0",
"lodash.get": "^4.4.2",
@ -2853,9 +2653,9 @@
}
},
"before-after-hook": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.4.0.tgz",
"integrity": "sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg==",
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.0.1.tgz",
"integrity": "sha512-dpgMHA51KZyCu7uuxF6FCkN+scfGd/6aLxEr/14vKUo/1nPxcd2fhFv4BgYCbWxKt7JfgpbjJq9nc30Ip/p2uw==",
"dev": true
},
"big.js": {
@ -2880,9 +2680,9 @@
}
},
"bluebird": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
"integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==",
"version": "3.5.5",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz",
"integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==",
"dev": true
},
"bn.js": {
@ -3701,9 +3501,9 @@
},
"dependencies": {
"semver": {
"version": "6.1.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.1.1.tgz",
"integrity": "sha512-rWYq2e5iYW+fFe/oPPtYJxYgjBm8sC4rmoGdUOgBB7VnwKt6HrL793l2voH1UlsyYZpJ4g0wfjnTEO1s1NP2eQ==",
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.2.0.tgz",
"integrity": "sha512-jdFC1VdUGT/2Scgbimf7FSx9iJLXoqfglSF+gJeuNWVpiE37OIbc1jywR/GJyFdz3mnkz2/id0L0J/cr0izR5A==",
"dev": true
},
"through2": {
@ -4136,9 +3936,9 @@
"dev": true
},
"deepmerge": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.2.1.tgz",
"integrity": "sha512-+hbDSzTqEW0fWgnlKksg7XAOtT+ddZS5lHZJ6f6MdixRs9wQy+50fm1uUCVb1IkvjLUYX/SfFO021ZNwriURTw==",
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.0.0.tgz",
"integrity": "sha512-YZ1rOP5+kHor4hMAH+HRQnBQHg+wvS1un1hAOuIcxcBy0hzcUf6Jg2a1w65kpoOUnurOfZbERwjI1TfZxNjcww==",
"dev": true
},
"defaults": {
@ -4439,6 +4239,31 @@
"is-arrayish": "^0.2.1"
}
},
"es-abstract": {
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz",
"integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==",
"dev": true,
"requires": {
"es-to-primitive": "^1.2.0",
"function-bind": "^1.1.1",
"has": "^1.0.3",
"is-callable": "^1.1.4",
"is-regex": "^1.0.4",
"object-keys": "^1.0.12"
}
},
"es-to-primitive": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz",
"integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==",
"dev": true,
"requires": {
"is-callable": "^1.1.4",
"is-date-object": "^1.0.1",
"is-symbol": "^1.0.2"
}
},
"es6-promise": {
"version": "4.2.8",
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
@ -6396,6 +6221,15 @@
"har-schema": "^2.0.0"
}
},
"has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
"dev": true,
"requires": {
"function-bind": "^1.1.1"
}
},
"has-ansi": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
@ -6574,12 +6408,12 @@
"dev": true
},
"https-proxy-agent": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz",
"integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==",
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.2.tgz",
"integrity": "sha512-c8Ndjc9Bkpfx/vCJueCPy0jlP4ccCCSNDp8xwCZzPjKJUm+B+u9WX2x98Qx4n1PiMNTWo3D7KK5ifNV/yJyRzg==",
"dev": true,
"requires": {
"agent-base": "^4.1.0",
"agent-base": "^4.3.0",
"debug": "^3.1.0"
}
},
@ -6854,6 +6688,12 @@
"integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
"dev": true
},
"is-callable": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz",
"integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==",
"dev": true
},
"is-ci": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz",
@ -6872,6 +6712,12 @@
"kind-of": "^3.0.2"
}
},
"is-date-object": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
"integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=",
"dev": true
},
"is-descriptor": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
@ -6969,6 +6815,15 @@
"integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
"dev": true
},
"is-regex": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
"integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
"dev": true,
"requires": {
"has": "^1.0.1"
}
},
"is-ssh": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.3.1.tgz",
@ -6984,6 +6839,15 @@
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
"dev": true
},
"is-symbol": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz",
"integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==",
"dev": true,
"requires": {
"has-symbols": "^1.0.0"
}
},
"is-text-path": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-2.0.0.tgz",
@ -7407,22 +7271,22 @@
"dev": true
},
"lodash.template": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz",
"integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=",
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz",
"integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==",
"dev": true,
"requires": {
"lodash._reinterpolate": "~3.0.0",
"lodash._reinterpolate": "^3.0.0",
"lodash.templatesettings": "^4.0.0"
}
},
"lodash.templatesettings": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz",
"integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=",
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz",
"integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==",
"dev": true,
"requires": {
"lodash._reinterpolate": "~3.0.0"
"lodash._reinterpolate": "^3.0.0"
}
},
"lodash.uniq": {
@ -7479,28 +7343,20 @@
"dev": true,
"requires": {
"pify": "^3.0.0"
},
"dependencies": {
"pify": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
"integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
"dev": true
}
}
},
"make-fetch-happen": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-4.0.1.tgz",
"integrity": "sha512-7R5ivfy9ilRJ1EMKIOziwrns9fGeAD4bAha8EB7BIiBBLHm2KeTUGCrICFt2rbHfzheTLynv50GnNTK1zDTrcQ==",
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-4.0.2.tgz",
"integrity": "sha512-YMJrAjHSb/BordlsDEcVcPyTbiJKkzqMf48N8dAJZT9Zjctrkb6Yg4TY9Sq2AwSIQJFn5qBBKVTYt3vP5FMIHA==",
"dev": true,
"requires": {
"agentkeepalive": "^3.4.1",
"cacache": "^11.0.1",
"cacache": "^11.3.3",
"http-cache-semantics": "^3.8.1",
"http-proxy-agent": "^2.1.0",
"https-proxy-agent": "^2.2.1",
"lru-cache": "^4.1.2",
"lru-cache": "^5.1.1",
"mississippi": "^3.0.0",
"node-fetch-npm": "^2.0.2",
"promise-retry": "^1.1.1",
@ -7508,15 +7364,71 @@
"ssri": "^6.0.0"
},
"dependencies": {
"lru-cache": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
"integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
"cacache": {
"version": "11.3.3",
"resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.3.tgz",
"integrity": "sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA==",
"dev": true,
"requires": {
"pseudomap": "^1.0.2",
"yallist": "^2.1.2"
"bluebird": "^3.5.5",
"chownr": "^1.1.1",
"figgy-pudding": "^3.5.1",
"glob": "^7.1.4",
"graceful-fs": "^4.1.15",
"lru-cache": "^5.1.1",
"mississippi": "^3.0.0",
"mkdirp": "^0.5.1",
"move-concurrently": "^1.0.1",
"promise-inflight": "^1.0.1",
"rimraf": "^2.6.3",
"ssri": "^6.0.1",
"unique-filename": "^1.1.1",
"y18n": "^4.0.0"
}
},
"glob": {
"version": "7.1.4",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
"integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
},
"graceful-fs": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz",
"integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==",
"dev": true
},
"lru-cache": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
"dev": true,
"requires": {
"yallist": "^3.0.2"
}
},
"rimraf": {
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
"integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
"dev": true,
"requires": {
"glob": "^7.1.3"
}
},
"yallist": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz",
"integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==",
"dev": true
}
}
},
@ -7807,9 +7719,9 @@
},
"dependencies": {
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
"integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==",
"dev": true
},
"yallist": {
@ -11589,9 +11501,9 @@
},
"dependencies": {
"graceful-fs": {
"version": "4.1.15",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz",
"integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==",
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz",
"integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==",
"dev": true
},
"which": {
@ -11618,9 +11530,9 @@
}
},
"npm-packlist": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.1.tgz",
"integrity": "sha512-+TcdO7HJJ8peiiYhvPxsEDhF3PJFGUGRcFsGve3vxvxdcpO2Z4Z7rkosRM0kWj6LfbK/P0gu3dzk5RU1ffvFcw==",
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.4.tgz",
"integrity": "sha512-zTLo8UcVYtDU3gdeaFu2Xu0n0EvelfHDGuqtNIn5RO7yQj4H1TqNdBc/yZjxnWA0PVB8D3Woyp0i5B43JwQ6Vw==",
"dev": true,
"requires": {
"ignore-walk": "^3.0.1",
@ -11726,6 +11638,16 @@
"object-keys": "^1.0.11"
}
},
"object.getownpropertydescriptors": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz",
"integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=",
"dev": true,
"requires": {
"define-properties": "^1.1.2",
"es-abstract": "^1.5.1"
}
},
"object.pick": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
@ -12568,16 +12490,14 @@
}
},
"read-package-tree": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/read-package-tree/-/read-package-tree-5.2.2.tgz",
"integrity": "sha512-rW3XWUUkhdKmN2JKB4FL563YAgtINifso5KShykufR03nJ5loGFlkUMe1g/yxmqX073SoYYTsgXu7XdDinKZuA==",
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/read-package-tree/-/read-package-tree-5.3.1.tgz",
"integrity": "sha512-mLUDsD5JVtlZxjSlPPx1RETkNjjvQYuweKwNVt1Sn8kP5Jh44pvYuUHCp6xSVDZWbNxVxG5lyZJ921aJH61sTw==",
"dev": true,
"requires": {
"debuglog": "^1.0.1",
"dezalgo": "^1.0.0",
"once": "^1.3.0",
"read-package-json": "^2.0.0",
"readdir-scoped-modules": "^1.0.0"
"readdir-scoped-modules": "^1.0.0",
"util-promisify": "^2.1.0"
}
},
"read-pkg": {
@ -12617,9 +12537,9 @@
}
},
"readdir-scoped-modules": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/readdir-scoped-modules/-/readdir-scoped-modules-1.0.2.tgz",
"integrity": "sha1-n6+jfShr5dksuuve4DDcm19AZ0c=",
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz",
"integrity": "sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw==",
"dev": true,
"requires": {
"debuglog": "^1.0.1",
@ -14007,9 +13927,9 @@
},
"dependencies": {
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
"integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==",
"dev": true
},
"yallist": {
@ -14673,6 +14593,15 @@
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
"dev": true
},
"util-promisify": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/util-promisify/-/util-promisify-2.1.0.tgz",
"integrity": "sha1-PCI2R2xNMsX/PEcAKt18E7moKlM=",
"dev": true,
"requires": {
"object.getownpropertydescriptors": "^2.0.3"
}
},
"uuid": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
@ -14721,12 +14650,6 @@
"integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==",
"dev": true
},
"wait-until-promise": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/wait-until-promise/-/wait-until-promise-1.0.0.tgz",
"integrity": "sha1-03Uy1bfv9oJwIMtE2OyqIzyWeMU=",
"dev": true
},
"watchpack": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz",
@ -15076,64 +14999,6 @@
"dev": true,
"requires": {
"execa": "^1.0.0"
},
"dependencies": {
"cross-spawn": {
"version": "6.0.5",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
"integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
"dev": true,
"requires": {
"nice-try": "^1.0.4",
"path-key": "^2.0.1",
"semver": "^5.5.0",
"shebang-command": "^1.2.0",
"which": "^1.2.9"
}
},
"execa": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
"integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
"dev": true,
"requires": {
"cross-spawn": "^6.0.0",
"get-stream": "^4.0.0",
"is-stream": "^1.1.0",
"npm-run-path": "^2.0.0",
"p-finally": "^1.0.0",
"signal-exit": "^3.0.0",
"strip-eof": "^1.0.0"
}
},
"get-stream": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
"integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
"dev": true,
"requires": {
"pump": "^3.0.0"
}
},
"pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
"dev": true,
"requires": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
}
},
"which": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
"dev": true,
"requires": {
"isexe": "^2.0.0"
}
}
}
},
"wordwrap": {
@ -15302,34 +15167,6 @@
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
"dev": true
},
"cross-spawn": {
"version": "6.0.5",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
"integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
"dev": true,
"requires": {
"nice-try": "^1.0.4",
"path-key": "^2.0.1",
"semver": "^5.5.0",
"shebang-command": "^1.2.0",
"which": "^1.2.9"
}
},
"execa": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
"integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
"dev": true,
"requires": {
"cross-spawn": "^6.0.0",
"get-stream": "^4.0.0",
"is-stream": "^1.1.0",
"npm-run-path": "^2.0.0",
"p-finally": "^1.0.0",
"signal-exit": "^3.0.0",
"strip-eof": "^1.0.0"
}
},
"find-up": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
@ -15339,30 +15176,6 @@
"locate-path": "^3.0.0"
}
},
"get-stream": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
"integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
"dev": true,
"requires": {
"pump": "^3.0.0"
}
},
"invert-kv": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz",
"integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==",
"dev": true
},
"lcid": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz",
"integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==",
"dev": true,
"requires": {
"invert-kv": "^2.0.0"
}
},
"locate-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
@ -15373,40 +15186,6 @@
"path-exists": "^3.0.0"
}
},
"mem": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz",
"integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==",
"dev": true,
"requires": {
"map-age-cleaner": "^0.1.1",
"mimic-fn": "^2.0.0",
"p-is-promise": "^2.0.0"
}
},
"mimic-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
"dev": true
},
"os-locale": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz",
"integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==",
"dev": true,
"requires": {
"execa": "^1.0.0",
"lcid": "^2.0.0",
"mem": "^4.0.0"
}
},
"p-is-promise": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz",
"integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==",
"dev": true
},
"p-limit": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz",
@ -15431,25 +15210,6 @@
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
"dev": true
},
"pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
"dev": true,
"requires": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
}
},
"which": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
"dev": true,
"requires": {
"isexe": "^2.0.0"
}
},
"yargs-parser": {
"version": "11.1.1",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz",

View File

@ -94,7 +94,6 @@
"style-loader": "^0.23.1",
"uglify-es": "^3.3.9",
"urijs": "^1.19.1",
"wait-until-promise": "^1.0.0",
"webpack": "^4.35.3",
"webpack-cli": "^3.3.5",
"xss": "^1.0.6"

View File

@ -40,7 +40,7 @@
const view = _converse.chatboxviews.get(jid);
spyOn(view, 'renderBookmarkForm').and.callThrough();
spyOn(view, 'closeForm').and.callThrough();
await test_utils.waitUntil(() => !_.isNull(view.el.querySelector('.toggle-bookmark')));
await u.waitUntil(() => !_.isNull(view.el.querySelector('.toggle-bookmark')));
let toggle = view.el.querySelector('.toggle-bookmark');
expect(toggle.title).toBe('Bookmark this groupchat');
toggle.click();
@ -94,7 +94,7 @@
_converse.connection.IQ_stanzas = [];
view.el.querySelector('.btn-primary').click();
await test_utils.waitUntil(() => sent_stanza);
await u.waitUntil(() => sent_stanza);
expect(sent_stanza.toLocaleString()).toBe(
`<iq from="romeo@montague.lit/orchard" id="${IQ_id}" type="set" xmlns="jabber:client">`+
`<pubsub xmlns="http://jabber.org/protocol/pubsub">`+
@ -133,8 +133,8 @@
'id':IQ_id
});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => view.model.get('bookmarked'));
toggle = await test_utils.waitUntil(() => view.el.querySelector('.toggle-bookmark'));
await u.waitUntil(() => view.model.get('bookmarked'));
toggle = await u.waitUntil(() => view.el.querySelector('.toggle-bookmark'));
expect(view.model.get('bookmarked')).toBeTruthy();
expect(toggle.title).toBe('Unbookmark this groupchat');
expect(u.hasClass('on-button', toggle), true);
@ -153,7 +153,7 @@
[{'category': 'pubsub', 'type': 'pep'}],
['http://jabber.org/protocol/pubsub#publish-options']
);
await test_utils.waitUntil(() => _converse.bookmarks);
await u.waitUntil(() => _converse.bookmarks);
let jid = 'lounge@montague.lit';
_converse.bookmarks.create({
'jid': jid,
@ -198,7 +198,7 @@
['http://jabber.org/protocol/pubsub#publish-options']
);
const room_jid = 'coven@chat.shakespeare.lit';
await test_utils.waitUntil(() => _converse.bookmarks);
await u.waitUntil(() => _converse.bookmarks);
_converse.bookmarks.create({
'jid': room_jid,
'autojoin': false,
@ -208,7 +208,7 @@
const model = await _converse.api.rooms.open(room_jid);
spyOn(model, 'join').and.callThrough();
await test_utils.getRoomFeatures(_converse, 'coven', 'chat.shakespeare.lit');
await test_utils.waitUntil(() => model.join.calls.count());
await u.waitUntil(() => model.join.calls.count());
expect(model.get('nick')).toBe('Othello');
done();
}));
@ -224,7 +224,7 @@
);
await _converse.api.rooms.open(`lounge@montague.lit`);
const view = _converse.chatboxviews.get('lounge@montague.lit');
let bookmark_icon = await test_utils.waitUntil(() => view.el.querySelector('.toggle-bookmark'));
let bookmark_icon = await u.waitUntil(() => view.el.querySelector('.toggle-bookmark'));
expect(_.includes(bookmark_icon.classList, 'button-on')).toBeFalsy();
_converse.bookmarks.create({
'jid': view.model.get('jid'),
@ -233,10 +233,10 @@
'nick': ' some1'
});
view.model.set('bookmarked', true);
bookmark_icon = await test_utils.waitUntil(() => view.el.querySelector('.toggle-bookmark'));
bookmark_icon = await u.waitUntil(() => view.el.querySelector('.toggle-bookmark'));
expect(_.includes(bookmark_icon.classList, 'button-on')).toBeTruthy();
view.model.set('bookmarked', false);
bookmark_icon = await test_utils.waitUntil(() => view.el.querySelector('.toggle-bookmark'));
bookmark_icon = await u.waitUntil(() => view.el.querySelector('.toggle-bookmark'));
expect(_.includes(bookmark_icon.classList, 'button-on')).toBeFalsy();
done();
}));
@ -257,7 +257,7 @@
const jid = 'theplay@conference.shakespeare.lit';
const view = _converse.chatboxviews.get(jid);
await test_utils.waitUntil(() => !_.isNull(view.el.querySelector('.toggle-bookmark')));
await u.waitUntil(() => !_.isNull(view.el.querySelector('.toggle-bookmark')));
spyOn(view, 'toggleBookmark').and.callThrough();
spyOn(_converse.bookmarks, 'sendBookmarkStanza').and.callThrough();
@ -271,7 +271,7 @@
});
expect(_converse.bookmarks.length).toBe(1);
expect(view.model.get('bookmarked')).toBeTruthy();
let bookmark_icon = await test_utils.waitUntil(() => view.el.querySelector('.toggle-bookmark'));
let bookmark_icon = await u.waitUntil(() => view.el.querySelector('.toggle-bookmark'));
expect(u.hasClass('button-on', bookmark_icon)).toBeTruthy();
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
@ -280,7 +280,7 @@
});
spyOn(_converse.connection, 'getUniqueId').and.callThrough();
bookmark_icon.click();
bookmark_icon = await test_utils.waitUntil(() => view.el.querySelector('.toggle-bookmark'));
bookmark_icon = await u.waitUntil(() => view.el.querySelector('.toggle-bookmark'));
expect(view.toggleBookmark).toHaveBeenCalled();
expect(u.hasClass('button-on', bookmark_icon)).toBeFalsy();
expect(_converse.bookmarks.length).toBe(0);
@ -360,7 +360,7 @@
[{'category': 'pubsub', 'type': 'pep'}],
['http://jabber.org/protocol/pubsub#publish-options']
);
await test_utils.waitUntil(() => _converse.bookmarks);
await u.waitUntil(() => _converse.bookmarks);
// Emit here instead of mocking fetching of bookmarks.
_converse.api.trigger('bookmarksInitialized');
@ -402,7 +402,7 @@
'jid':'theplay@conference.shakespeare.lit'})
.c('nick').t('JC');
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => _converse.bookmarks.length);
await u.waitUntil(() => _converse.bookmarks.length);
expect(_converse.bookmarks.length).toBe(1);
expect(_converse.chatboxviews.get('theplay@conference.shakespeare.lit')).not.toBeUndefined();
done();
@ -428,7 +428,7 @@
* </iq>
*/
let IQ_id;
const call = await test_utils.waitUntil(() =>
const call = await u.waitUntil(() =>
_.filter(
_converse.connection.send.calls.all(),
call => {
@ -491,7 +491,7 @@
'jid': 'another@conference.shakespeare.lit'
}); // Purposefully exclude the <nick> element to test #1043
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => _converse.bookmarks.onBookmarksReceived.calls.count());
await u.waitUntil(() => _converse.bookmarks.onBookmarksReceived.calls.count());
expect(_converse.bookmarks.models.length).toBe(2);
expect(_converse.bookmarks.findWhere({'jid': 'theplay@conference.shakespeare.lit'}).get('autojoin')).toBe(true);
expect(_converse.bookmarks.findWhere({'jid': 'another@conference.shakespeare.lit'}).get('autojoin')).toBe(false);
@ -512,7 +512,7 @@
test_utils.openControlBox();
let IQ_id;
const call = await test_utils.waitUntil(() =>
const call = await u.waitUntil(() =>
_.filter(
_converse.connection.send.calls.all(),
call => {
@ -566,7 +566,7 @@
}).c('nick').t('JC').up().up();
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => document.querySelectorAll('#chatrooms div.bookmarks.rooms-list .room-item').length);
await u.waitUntil(() => document.querySelectorAll('#chatrooms div.bookmarks.rooms-list .room-item').length);
expect(document.querySelectorAll('#chatrooms div.bookmarks.rooms-list .room-item').length).toBe(5);
let els = document.querySelectorAll('#chatrooms div.bookmarks.rooms-list .room-item a.list-item-link');
expect(els[0].textContent).toBe("1st Bookmark");
@ -578,7 +578,7 @@
spyOn(window, 'confirm').and.returnValue(true);
document.querySelector('#chatrooms .bookmarks.rooms-list .room-item:nth-child(2) a:nth-child(2)').click();
expect(window.confirm).toHaveBeenCalled();
await test_utils.waitUntil(() => document.querySelectorAll('#chatrooms div.bookmarks.rooms-list .room-item').length === 4)
await u.waitUntil(() => document.querySelectorAll('#chatrooms div.bookmarks.rooms-list .room-item').length === 4)
els = document.querySelectorAll('#chatrooms div.bookmarks.rooms-list .room-item a.list-item-link');
expect(els[0].textContent).toBe("1st Bookmark");
expect(els[1].textContent).toBe("Bookmark with a very very long name that will be shortened");
@ -600,7 +600,7 @@
);
let IQ_id;
const call = await test_utils.waitUntil(() =>
const call = await u.waitUntil(() =>
_.filter(
_converse.connection.send.calls.all(),
call => {
@ -638,7 +638,7 @@
});
const el = _converse.chatboxviews.el
const selector = '#chatrooms .bookmarks.rooms-list .room-item';
await test_utils.waitUntil(() => sizzle(selector, el).filter(u.isVisible).length);
await u.waitUntil(() => sizzle(selector, el).filter(u.isVisible).length);
expect(u.hasClass('collapsed', sizzle('#chatrooms .bookmarks.rooms-list', el).pop())).toBeFalsy();
expect(sizzle(selector, el).filter(u.isVisible).length).toBe(1);
expect(_converse.bookmarksview.list_model.get('toggle-state')).toBe(_converse.OPENED);
@ -668,7 +668,7 @@
[{'category': 'pubsub', 'type': 'pep'}],
['http://jabber.org/protocol/pubsub#publish-options']
);
await test_utils.waitUntil(() => _converse.bookmarks);
await u.waitUntil(() => _converse.bookmarks);
// XXX Create bookmarks view here, otherwise we need to mock stanza
// traffic for it to get created.
_converse.bookmarksview = new _converse.BookmarksView(
@ -686,13 +686,13 @@
expect(_converse.bookmarks.length).toBe(1);
const bmarks_view = _converse.bookmarksview;
await test_utils.waitUntil(() => bmarks_view.el.querySelectorAll(".open-room").length, 500);
await u.waitUntil(() => bmarks_view.el.querySelectorAll(".open-room").length, 500);
const room_els = bmarks_view.el.querySelectorAll(".open-room");
expect(room_els.length).toBe(1);
const bookmark = _converse.bookmarksview.el.querySelector(".open-room");
bookmark.click();
await test_utils.waitUntil(() => _converse.chatboxviews.get(jid));
await u.waitUntil(() => _converse.chatboxviews.get(jid));
expect(u.hasClass('hidden', _converse.bookmarksview.el.querySelector(".available-chatroom"))).toBeTruthy();
// Check that it reappears once the room is closed

View File

@ -43,7 +43,7 @@
id: (new Date()).getTime()
}).c('body').t('hello world').tree();
await _converse.chatboxes.onMessage(msg);
await test_utils.waitUntil(() => view.content.querySelectorAll('.chat-msg').length);
await u.waitUntil(() => view.content.querySelectorAll('.chat-msg').length);
expect(view.content.lastElementChild.textContent.trim().indexOf('hello world')).not.toBe(-1);
done();
}));
@ -56,7 +56,7 @@
await test_utils.waitForRoster(_converse, 'current');
await test_utils.waitUntilDiscoConfirmed(_converse, 'montague.lit', [], ['vcard-temp']);
await test_utils.waitUntil(() => _converse.xmppstatus.vcard.get('fullname'));
await u.waitUntil(() => _converse.xmppstatus.vcard.get('fullname'));
await test_utils.openControlBox();
expect(_converse.chatboxes.length).toEqual(1);
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
@ -78,7 +78,7 @@
message = '/me is as well';
await test_utils.sendMessage(view, message);
expect(view.el.querySelectorAll('.chat-msg--action').length).toBe(2);
await test_utils.waitUntil(() => sizzle('.chat-msg__author:last', view.el).pop().textContent.trim() === '**Romeo Montague');
await u.waitUntil(() => sizzle('.chat-msg__author:last', view.el).pop().textContent.trim() === '**Romeo Montague');
const last_el = sizzle('.chat-msg__text:last', view.el).pop();
expect(last_el.textContent).toBe('is as well');
expect(u.hasClass('chat-msg--followup', last_el)).toBe(false);
@ -111,19 +111,19 @@
spyOn(_converse.chatboxviews, 'trimChats');
expect(document.querySelectorAll("#conversejs .chatbox").length).toBe(1); // Controlbox is open
await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group li').length, 700);
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group li').length, 700);
const online_contacts = _converse.rosterview.el.querySelectorAll('.roster-group .current-xmpp-contact a.open-chat');
expect(online_contacts.length).toBe(15);
let el = online_contacts[0];
const jid = el.textContent.trim().replace(/ /g,'.').toLowerCase() + '@montague.lit';
el.click();
await test_utils.waitUntil(() => _converse.chatboxes.length == 2);
await u.waitUntil(() => _converse.chatboxes.length == 2);
expect(_converse.chatboxviews.trimChats).toHaveBeenCalled();
// Check that new chat boxes are created to the left of the
// controlbox (but to the right of all existing chat boxes)
expect(document.querySelectorAll("#conversejs .chatbox").length).toBe(2);
online_contacts[1].click();
await test_utils.waitUntil(() => _converse.chatboxes.length == 3);
await u.waitUntil(() => _converse.chatboxes.length == 3);
el = online_contacts[1];
const new_jid = el.textContent.trim().replace(/ /g,'.').toLowerCase() + '@montague.lit';
expect(_converse.chatboxviews.trimChats).toHaveBeenCalled();
@ -148,8 +148,8 @@
const message_promise = new Promise(resolve => _converse.api.listen.on('message', resolve));
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => _converse.api.chats.get().length === 2);
await test_utils.waitUntil(() => message_promise);
await u.waitUntil(() => _converse.api.chats.get().length === 2);
await u.waitUntil(() => message_promise);
expect(_converse.chatboxviews.keys().length).toBe(2);
done();
}));
@ -168,7 +168,7 @@
</message>`);
const message_promise = new Promise(resolve => _converse.api.listen.on('message', resolve))
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => message_promise);
await u.waitUntil(() => message_promise);
expect(_converse.chatboxviews.keys().length).toBe(1);
done();
}));
@ -193,7 +193,7 @@
expect(document.querySelectorAll("#conversejs .chatbox").length).toBe(1); // Controlbox is open
_converse.rosterview.update(); // XXX: Hack to make sure $roster element is attached.
await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group li').length);
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group li').length);
// Test that they can be maximized again
const online_contacts = _converse.rosterview.el.querySelectorAll('.roster-group .current-xmpp-contact a.open-chat');
expect(online_contacts.length).toBe(15);
@ -202,7 +202,7 @@
const el = online_contacts[i];
el.click();
}
await test_utils.waitUntil(() => _converse.chatboxes.length == 16);
await u.waitUntil(() => _converse.chatboxes.length == 16);
expect(_converse.chatboxviews.trimChats.calls.count()).toBe(16);
for (i=0; i<online_contacts.length; i++) {
@ -214,7 +214,7 @@
expect(trimmed_chatboxes.addChat).toHaveBeenCalled();
expect(chatboxview.onMinimized).toHaveBeenCalled();
}
await test_utils.waitUntil(() => _converse.chatboxviews.keys().length);
await u.waitUntil(() => _converse.chatboxviews.keys().length);
var key = _converse.chatboxviews.keys()[1];
const trimmedview = trimmed_chatboxes.get(key);
const chatbox = trimmedview.model;
@ -237,7 +237,7 @@
await test_utils.waitForRoster(_converse, 'current');
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
const chat = await _converse.api.chats.create(sender_jid, {'minimized': true});
await test_utils.waitUntil(() => _converse.chatboxes.length > 1);
await u.waitUntil(() => _converse.chatboxes.length > 1);
const chatBoxView = _converse.chatboxviews.get(sender_jid);
expect(u.isVisible(chatBoxView.el)).toBeFalsy();
@ -265,7 +265,7 @@
const jid = el.textContent.replace(/ /g,'.').toLowerCase() + '@montague.lit';
spyOn(_converse.api, "trigger");
el.click();
await test_utils.waitUntil(() => _converse.api.trigger.calls.count(), 500);
await u.waitUntil(() => _converse.api.trigger.calls.count(), 500);
expect(_converse.chatboxes.length).toEqual(2);
expect(_converse.api.trigger).toHaveBeenCalledWith('chatBoxFocused', jasmine.any(Object));
done();
@ -284,7 +284,7 @@
test_utils.openControlBox();
test_utils.openChatBoxes(_converse, 6);
await test_utils.waitUntil(() => _converse.chatboxes.length == 7);
await u.waitUntil(() => _converse.chatboxes.length == 7);
expect(_converse.chatboxviews.trimChats).toHaveBeenCalled();
// We instantiate a new ChatBoxes collection, which by default
// will be empty.
@ -316,7 +316,7 @@
test_utils.openControlBox();
const contact_jid = mock.cur_names[7].replace(/ /g,'.').toLowerCase() + '@montague.lit';
await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
await test_utils.openChatBoxFor(_converse, contact_jid);
const controlview = _converse.chatboxviews.get('controlbox'), // The controlbox is currently open
chatview = _converse.chatboxviews.get(contact_jid);
@ -351,7 +351,7 @@
test_utils.openControlBox();
const contact_jid = mock.cur_names[7].replace(/ /g,'.').toLowerCase() + '@montague.lit';
await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
await test_utils.openChatBoxFor(_converse, contact_jid);
const trimmed_chatboxes = _converse.minimized_chats;
const chatview = _converse.chatboxviews.get(contact_jid);
@ -388,7 +388,7 @@
await test_utils.waitForRoster(_converse, 'current');
test_utils.openControlBox();
await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
spyOn(_converse.api, "trigger");
spyOn(_converse.chatboxviews, 'trimChats');
_converse.chatboxes.browserStorage._clear();
@ -399,7 +399,7 @@
expect(_converse.chatboxes.length).toEqual(1);
expect(_converse.chatboxes.pluck('id')).toEqual(['controlbox']);
test_utils.openChatBoxes(_converse, 6);
await test_utils.waitUntil(() => _converse.chatboxes.length == 7)
await u.waitUntil(() => _converse.chatboxes.length == 7)
expect(_converse.chatboxviews.trimChats).toHaveBeenCalled();
expect(_converse.chatboxes.length).toEqual(7);
expect(_converse.api.trigger).toHaveBeenCalledWith('chatBoxInitialized', jasmine.any(Object));
@ -461,7 +461,7 @@
view.delegateEvents(); // We need to rebind all events otherwise our spy won't be called
toolbar.querySelector('li.toggle-smiley').click();
await test_utils.waitUntil(() => u.isVisible(view.el.querySelector('.toggle-smiley .emoji-picker-container')));
await u.waitUntil(() => u.isVisible(view.el.querySelector('.toggle-smiley .emoji-picker-container')));
var picker = view.el.querySelector('.toggle-smiley .emoji-picker-container');
var items = picker.querySelectorAll('.emoji-picker li');
items[0].click()
@ -488,7 +488,7 @@
expect(counter.textContent).toBe('188');
toolbar.querySelector('li.toggle-smiley').click();
await test_utils.waitUntil(() => u.isVisible(view.el.querySelector('.toggle-smiley .emoji-picker-container')));
await u.waitUntil(() => u.isVisible(view.el.querySelector('.toggle-smiley .emoji-picker-container')));
var picker = view.el.querySelector('.toggle-smiley .emoji-picker-container');
var items = picker.querySelectorAll('.emoji-picker li');
items[0].click()
@ -628,7 +628,7 @@
await test_utils.waitForRoster(_converse, 'current');
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
test_utils.openControlBox();
test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
spyOn(_converse.connection, 'send');
await test_utils.openChatBoxFor(_converse, contact_jid);
const view = _converse.chatboxviews.get(contact_jid);
@ -651,14 +651,14 @@
test_utils.openControlBox();
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
await test_utils.openChatBoxFor(_converse, contact_jid);
const view = _converse.chatboxviews.get(contact_jid);
view.model.minimize();
expect(view.model.get('chat_state')).toBe('inactive');
spyOn(_converse.connection, 'send');
view.model.maximize();
await test_utils.waitUntil(() => view.model.get('chat_state') === 'active', 1000);
await u.waitUntil(() => view.model.get('chat_state') === 'active', 1000);
expect(_converse.connection.send).toHaveBeenCalled();
const calls = _.filter(_converse.connection.send.calls.all(), function (call) {
return call.args[0] instanceof Strophe.Builder;
@ -685,7 +685,7 @@
test_utils.openControlBox();
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
await test_utils.openChatBoxFor(_converse, contact_jid);
var view = _converse.chatboxviews.get(contact_jid);
expect(view.model.get('chat_state')).toBe('active');
@ -726,7 +726,7 @@
// See XEP-0085 https://xmpp.org/extensions/xep-0085.html#definitions
spyOn(_converse.api, "trigger");
const sender_jid = mock.cur_names[1].replace(/ /g,'.').toLowerCase() + '@montague.lit';
await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
await test_utils.openChatBoxFor(_converse, sender_jid);
// <composing> state
@ -741,7 +741,7 @@
var view = _converse.chatboxviews.get(sender_jid);
expect(view).toBeDefined();
await test_utils.waitUntil(() => view.model.vcard.get('fullname') === mock.cur_names[1])
await u.waitUntil(() => view.model.vcard.get('fullname') === mock.cur_names[1])
// Check that the notification appears inside the chatbox in the DOM
let events = view.el.querySelectorAll('.chat-state-notification');
expect(events[0].textContent).toEqual(mock.cur_names[1] + ' is typing');
@ -767,7 +767,7 @@
let contact, sent_stanza, IQ_id, stanza;
await test_utils.waitUntilDiscoConfirmed(_converse, 'montague.lit', [], ['vcard-temp']);
await test_utils.waitUntil(() => _converse.xmppstatus.vcard.get('fullname'));
await u.waitUntil(() => _converse.xmppstatus.vcard.get('fullname'));
await test_utils.waitForRoster(_converse, 'current');
// Send a message from a different resource
spyOn(_converse, 'log');
@ -788,7 +788,7 @@
'type': 'chat'
}).c('composing', {'xmlns': Strophe.NS.CHATSTATES}).tree();
await _converse.chatboxes.onMessage(msg);
await test_utils.waitUntil(() => view.model.messages.length);
await u.waitUntil(() => view.model.messages.length);
// Check that the chatbox and its view now exist
const chatbox = _converse.chatboxes.get(recipient_jid);
const chatboxview = _converse.chatboxviews.get(recipient_jid);
@ -814,7 +814,7 @@
await test_utils.waitForRoster(_converse, 'current');
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
test_utils.openControlBox();
await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group li').length, 700);
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group li').length, 700);
_converse.TIMEOUTS.PAUSED = 200; // Make the timeout shorter so that we can test
await test_utils.openChatBoxFor(_converse, contact_jid);
const view = _converse.chatboxviews.get(contact_jid);
@ -829,7 +829,7 @@
expect(_converse.connection.send).toHaveBeenCalled();
let stanza = _converse.connection.send.calls.argsFor(0)[0].tree();
expect(stanza.childNodes[0].tagName).toBe('composing');
await test_utils.waitUntil(() => view.model.get('chat_state') === 'paused', 500);
await u.waitUntil(() => view.model.get('chat_state') === 'paused', 500);
expect(_converse.connection.send).toHaveBeenCalled();
var calls = _.filter(_converse.connection.send.calls.all(), function (call) {
return call.args[0] instanceof Strophe.Builder;
@ -867,7 +867,7 @@
await test_utils.waitForRoster(_converse, 'current');
test_utils.openControlBox();
await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
// TODO: only show paused state if the previous state was composing
// See XEP-0085 https://xmpp.org/extensions/xep-0085.html#definitions
spyOn(_converse.api, "trigger").and.callThrough();
@ -882,7 +882,7 @@
}).c('paused', {'xmlns': Strophe.NS.CHATSTATES}).tree();
await _converse.chatboxes.onMessage(msg);
expect(_converse.api.trigger).toHaveBeenCalledWith('message', jasmine.any(Object));
await test_utils.waitUntil(() => view.model.vcard.get('fullname') === mock.cur_names[1])
await u.waitUntil(() => view.model.vcard.get('fullname') === mock.cur_names[1])
var event = view.el.querySelector('.chat-info.chat-state-notification');
expect(event.textContent).toEqual(mock.cur_names[1] + ' has stopped typing');
done();
@ -895,7 +895,7 @@
let contact, sent_stanza, IQ_id, stanza;
await test_utils.waitUntilDiscoConfirmed(_converse, 'montague.lit', [], ['vcard-temp']);
await test_utils.waitUntil(() => _converse.xmppstatus.vcard.get('fullname'));
await u.waitUntil(() => _converse.xmppstatus.vcard.get('fullname'));
await test_utils.waitForRoster(_converse, 'current');
// Send a message from a different resource
spyOn(_converse, 'log');
@ -916,7 +916,7 @@
'type': 'chat'
}).c('paused', {'xmlns': Strophe.NS.CHATSTATES}).tree();
await _converse.chatboxes.onMessage(msg);
await test_utils.waitUntil(() => view.model.messages.length);
await u.waitUntil(() => view.model.messages.length);
// Check that the chatbox and its view now exist
const chatbox = _converse.chatboxes.get(recipient_jid);
const chatboxview = _converse.chatboxviews.get(recipient_jid);
@ -946,22 +946,22 @@
await test_utils.waitForRoster(_converse, 'current');
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
test_utils.openControlBox();
await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 1000);
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 1000);
await test_utils.openChatBoxFor(_converse, contact_jid);
const view = _converse.chatboxviews.get(contact_jid);
await test_utils.waitUntil(() => view.model.get('chat_state') === 'active', 1000);
await u.waitUntil(() => view.model.get('chat_state') === 'active', 1000);
console.log('chat_state set to active');
expect(view.model.get('chat_state')).toBe('active');
view.onKeyDown({
target: view.el.querySelector('textarea.chat-textarea'),
keyCode: 1
});
await test_utils.waitUntil(() => view.model.get('chat_state') === 'composing', 500);
await u.waitUntil(() => view.model.get('chat_state') === 'composing', 500);
console.log('chat_state set to composing');
expect(view.model.get('chat_state')).toBe('composing');
spyOn(_converse.connection, 'send');
await test_utils.waitUntil(() => view.model.get('chat_state') === 'paused', 1000);
await test_utils.waitUntil(() => view.model.get('chat_state') === 'inactive', 1000);
await u.waitUntil(() => view.model.get('chat_state') === 'paused', 1000);
await u.waitUntil(() => view.model.get('chat_state') === 'inactive', 1000);
console.log('chat_state set to inactive');
expect(_converse.connection.send).toHaveBeenCalled();
var calls = _.filter(_converse.connection.send.calls.all(), function (call) {
@ -1013,7 +1013,7 @@
await test_utils.waitForRoster(_converse, 'current');
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
test_utils.openControlBox();
await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
const view = await test_utils.openChatBoxFor(_converse, contact_jid);
expect(view.model.get('chat_state')).toBe('active');
spyOn(_converse.connection, 'send');
@ -1054,7 +1054,7 @@
.c('composing', {'xmlns': Strophe.NS.CHATSTATES}).up()
.tree();
await _converse.chatboxes.onMessage(msg);
await test_utils.waitUntil(() => view.model.messages.length);
await u.waitUntil(() => view.model.messages.length);
expect(view.el.querySelectorAll('.chat-state-notification').length).toBe(1);
msg = $msg({
from: sender_jid,
@ -1063,7 +1063,7 @@
id: (new Date()).getTime()
}).c('body').c('inactive', {'xmlns': Strophe.NS.CHATSTATES}).tree();
await _converse.chatboxes.onMessage(msg);
await test_utils.waitUntil(() => (view.model.messages.length > 1));
await u.waitUntil(() => (view.model.messages.length > 1));
expect(_converse.api.trigger).toHaveBeenCalledWith('message', jasmine.any(Object));
expect(view.el.querySelectorAll('.chat-state-notification').length).toBe(0);
done();
@ -1092,7 +1092,7 @@
await _converse.chatboxes.onMessage(msg);
expect(_converse.api.trigger).toHaveBeenCalledWith('message', jasmine.any(Object));
const view = _converse.chatboxviews.get(sender_jid);
await test_utils.waitUntil(() => view.model.vcard.get('fullname') === mock.cur_names[1]);
await u.waitUntil(() => view.model.vcard.get('fullname') === mock.cur_names[1]);
const event = view.el.querySelector('.chat-state-notification');
expect(event.textContent).toEqual(mock.cur_names[1] + ' has gone away');
done();
@ -1120,7 +1120,7 @@
expect(view.model.messages.length > 0).toBeTruthy();
expect(view.model.messages.browserStorage.records.length > 0).toBeTruthy();
await test_utils.waitUntil(() => view.el.querySelector('.chat-msg'));
await u.waitUntil(() => view.el.querySelector('.chat-msg'));
message = '/clear';
spyOn(view, 'clearMessages').and.callThrough();
@ -1250,7 +1250,7 @@
// leave converse-chat page
_converse.windowState = 'hidden';
_converse.chatboxes.onMessage(msgFactory());
await test_utils.waitUntil(() => _converse.api.chats.get().length === 2)
await u.waitUntil(() => _converse.api.chats.get().length === 2)
let view = _converse.chatboxviews.get(sender_jid);
expect(_converse.msg_counter).toBe(1);
@ -1265,7 +1265,7 @@
// check that msg_counter is incremented from zero again
_converse.chatboxes.onMessage(msgFactory());
await test_utils.waitUntil(() => _converse.api.chats.get().length === 2)
await u.waitUntil(() => _converse.api.chats.get().length === 2)
view = _converse.chatboxviews.get(sender_jid);
expect(u.isVisible(view.el)).toBeTruthy();
expect(_converse.msg_counter).toBe(1);
@ -1287,7 +1287,7 @@
const view = await test_utils.openChatBoxFor(_converse, sender_jid)
view.model.save('scrolled', true);
await _converse.chatboxes.onMessage(msg);
await test_utils.waitUntil(() => view.model.messages.length);
await u.waitUntil(() => view.model.messages.length);
expect(view.model.get('num_unread')).toBe(1);
done();
}));
@ -1323,7 +1323,7 @@
const chatbox = _converse.chatboxes.get(sender_jid);
_converse.windowState = 'hidden';
_converse.chatboxes.onMessage(msgFactory());
await test_utils.waitUntil(() => chatbox.messages.length);
await u.waitUntil(() => chatbox.messages.length);
expect(chatbox.get('num_unread')).toBe(1);
done();
}));
@ -1341,7 +1341,7 @@
chatbox.save('scrolled', true);
_converse.windowState = 'hidden';
_converse.chatboxes.onMessage(msgFactory());
await test_utils.waitUntil(() => chatbox.messages.length);
await u.waitUntil(() => chatbox.messages.length);
expect(chatbox.get('num_unread')).toBe(1);
done();
}));
@ -1358,7 +1358,7 @@
const chatbox = _converse.chatboxes.get(sender_jid);
_converse.windowState = 'hidden';
_converse.chatboxes.onMessage(msgFactory());
await test_utils.waitUntil(() => chatbox.messages.length);
await u.waitUntil(() => chatbox.messages.length);
expect(chatbox.get('num_unread')).toBe(1);
_converse.saveWindowState(null, 'focus');
expect(chatbox.get('num_unread')).toBe(0);
@ -1378,7 +1378,7 @@
chatbox.save('scrolled', true);
_converse.windowState = 'hidden';
_converse.chatboxes.onMessage(msgFactory());
await test_utils.waitUntil(() => chatbox.messages.length);
await u.waitUntil(() => chatbox.messages.length);
expect(chatbox.get('num_unread')).toBe(1);
_converse.saveWindowState(null, 'focus');
expect(chatbox.get('num_unread')).toBe(1);
@ -1396,19 +1396,19 @@
await test_utils.waitForRoster(_converse, 'current', 1);
let msg, indicator_el;
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 500);
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 500);
await test_utils.openChatBoxFor(_converse, sender_jid);
const chatbox = _converse.chatboxes.get(sender_jid);
chatbox.save('scrolled', true);
msg = test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread');
await _converse.chatboxes.onMessage(msg);
await test_utils.waitUntil(() => chatbox.messages.length);
await u.waitUntil(() => chatbox.messages.length);
const selector = 'a.open-chat:contains("' + chatbox.get('nickname') + '") .msgs-indicator';
indicator_el = sizzle(selector, _converse.rosterview.el).pop();
expect(indicator_el.textContent).toBe('1');
msg = test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread too');
await _converse.chatboxes.onMessage(msg);
await test_utils.waitUntil(() => chatbox.messages.length > 1);
await u.waitUntil(() => chatbox.messages.length > 1);
indicator_el = sizzle(selector, _converse.rosterview.el).pop();
expect(indicator_el.textContent).toBe('2');
done();
@ -1423,7 +1423,7 @@
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
let indicator_el, msg;
await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 500);
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 500);
await test_utils.openChatBoxFor(_converse, sender_jid);
const chatbox = _converse.chatboxes.get(sender_jid);
var chatboxview = _converse.chatboxviews.get(sender_jid);
@ -1431,14 +1431,14 @@
msg = test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread');
await _converse.chatboxes.onMessage(msg);
await test_utils.waitUntil(() => chatbox.messages.length);
await u.waitUntil(() => chatbox.messages.length);
const selector = 'a.open-chat:contains("' + chatbox.get('nickname') + '") .msgs-indicator';
indicator_el = sizzle(selector, _converse.rosterview.el).pop();
expect(indicator_el.textContent).toBe('1');
msg = test_utils.createChatMessage(_converse, sender_jid, 'This message will be unread too');
await _converse.chatboxes.onMessage(msg);
await test_utils.waitUntil(() => chatbox.messages.length === 2);
await u.waitUntil(() => chatbox.messages.length === 2);
indicator_el = sizzle(selector, _converse.rosterview.el).pop();
expect(indicator_el.textContent).toBe('2');
done();
@ -1452,7 +1452,7 @@
await test_utils.waitForRoster(_converse, 'current', 1);
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
const msgFactory = () => test_utils.createChatMessage(_converse, sender_jid, 'This message will be received as unread, but eventually will be read');
await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 500);
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 500);
await test_utils.openChatBoxFor(_converse, sender_jid);
const chatbox = _converse.chatboxes.get(sender_jid);
const view = _converse.chatboxviews.get(sender_jid);
@ -1460,10 +1460,10 @@
const select_msgs_indicator = () => sizzle(selector, _converse.rosterview.el).pop();
view.minimize();
_converse.chatboxes.onMessage(msgFactory());
await test_utils.waitUntil(() => chatbox.messages.length);
await u.waitUntil(() => chatbox.messages.length);
expect(select_msgs_indicator().textContent).toBe('1');
_converse.chatboxes.onMessage(msgFactory());
await test_utils.waitUntil(() => chatbox.messages.length > 1);
await u.waitUntil(() => chatbox.messages.length > 1);
expect(select_msgs_indicator().textContent).toBe('2');
view.model.maximize();
expect(select_msgs_indicator()).toBeUndefined();
@ -1477,7 +1477,7 @@
await test_utils.waitForRoster(_converse, 'current', 1);
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 500);
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 500);
await test_utils.openChatBoxFor(_converse, sender_jid);
const chatbox = _converse.chatboxes.get(sender_jid);
const view = _converse.chatboxviews.get(sender_jid);
@ -1486,7 +1486,7 @@
const select_msgs_indicator = () => sizzle(selector, _converse.rosterview.el).pop();
chatbox.save('scrolled', true);
_converse.chatboxes.onMessage(msgFactory());
await test_utils.waitUntil(() => view.model.messages.length);
await u.waitUntil(() => view.model.messages.length);
expect(select_msgs_indicator().textContent).toBe('1');
view.viewUnreadMessages();
_converse.rosterview.render();
@ -1501,7 +1501,7 @@
await test_utils.waitForRoster(_converse, 'current', 1);
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 500);
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 500);
await test_utils.openChatBoxFor(_converse, sender_jid);
const chatbox = _converse.chatboxes.get(sender_jid);
const view = _converse.chatboxviews.get(sender_jid);
@ -1511,7 +1511,7 @@
const select_msgs_indicator = () => sizzle(selector, _converse.rosterview.el).pop();
chatbox.save('scrolled', true);
_converse.chatboxes.onMessage(msgFactory());
await test_utils.waitUntil(() => view.model.messages.length);
await u.waitUntil(() => view.model.messages.length);
expect(select_msgs_indicator().textContent).toBe('1');
await test_utils.openChatBoxFor(_converse, sender_jid);
expect(select_msgs_indicator().textContent).toBe('1');
@ -1539,7 +1539,7 @@
const chatbox = _converse.chatboxes.get(sender_jid);
chatbox.save('scrolled', true);
_converse.chatboxes.onMessage(msgFactory());
await test_utils.waitUntil(() => chatbox.messages.length);
await u.waitUntil(() => chatbox.messages.length);
const chatboxview = _converse.chatboxviews.get(sender_jid);
chatboxview.minimize();
@ -1567,7 +1567,7 @@
};
view.minimize();
_converse.chatboxes.onMessage(msgFactory());
await test_utils.waitUntil(() => view.model.messages.length);
await u.waitUntil(() => view.model.messages.length);
const unread_count = selectUnreadMsgCount();
expect(u.isVisible(unread_count)).toBeTruthy();
expect(unread_count.innerHTML).toBe('1');
@ -1589,7 +1589,7 @@
const view = _converse.chatboxviews.get(contact_jid);
spyOn(view.model, 'sendMessage').and.callThrough();
test_utils.sendMessage(view, message);
await test_utils.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-msg').length, 1000);
await u.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-msg').length, 1000);
expect(view.model.sendMessage).toHaveBeenCalled();
const msg = sizzle('.chat-content .chat-msg:last .chat-msg__text', view.el).pop();
expect(msg.innerHTML).toEqual(

View File

@ -59,7 +59,7 @@
ask: 'subscribe',
fullname: mock.pend_names[0]
});
await test_utils.waitUntil(() => _.filter(_converse.rosterview.el.querySelectorAll('.roster-group li'), u.isVisible).length, 700);
await u.waitUntil(() => _.filter(_converse.rosterview.el.querySelectorAll('.roster-group li'), u.isVisible).length, 700);
// Checking that only one entry is created because both JID is same (Case sensitive check)
expect(_.filter(_converse.rosterview.el.querySelectorAll('li'), u.isVisible).length).toBe(1);
expect(_converse.rosterview.update).toHaveBeenCalled();
@ -76,7 +76,7 @@
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
await test_utils.openChatBoxFor(_converse, sender_jid);
await test_utils.waitUntil(() => _converse.chatboxes.length);
await u.waitUntil(() => _converse.chatboxes.length);
const chatview = _converse.chatboxviews.get(sender_jid);
chatview.model.set({'minimized': true});
@ -91,7 +91,7 @@
}).c('body').t('hello').up()
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
_converse.chatboxes.onMessage(msg);
await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll(".msgs-indicator").length);
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll(".msgs-indicator").length);
spyOn(chatview.model, 'incrementUnreadMsgCounter').and.callThrough();
expect(_converse.chatboxviews.el.querySelector('.restore-chat .message-count').textContent).toBe('1');
expect(_converse.rosterview.el.querySelector('.msgs-indicator').textContent).toBe('1');
@ -104,7 +104,7 @@
}).c('body').t('hello again').up()
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
_converse.chatboxes.onMessage(msg);
await test_utils.waitUntil(() => chatview.model.incrementUnreadMsgCounter.calls.count());
await u.waitUntil(() => chatview.model.incrementUnreadMsgCounter.calls.count());
expect(_converse.chatboxviews.el.querySelector('.restore-chat .message-count').textContent).toBe('2');
expect(_converse.rosterview.el.querySelector('.msgs-indicator').textContent).toBe('2');
chatview.model.set({'minimized': false});
@ -139,7 +139,7 @@
cbview.el.querySelector('.change-status').click()
var modal = _converse.xmppstatusview.status_modal;
await test_utils.waitUntil(() => u.isVisible(modal.el), 1000);
await u.waitUntil(() => u.isVisible(modal.el), 1000);
const view = _converse.xmppstatusview;
modal.el.querySelector('label[for="radio-busy"]').click(); // Change status to "dnd"
modal.el.querySelector('[type="submit"]').click();
@ -168,7 +168,7 @@
cbview.el.querySelector('.change-status').click()
const modal = _converse.xmppstatusview.status_modal;
await test_utils.waitUntil(() => u.isVisible(modal.el), 1000);
await u.waitUntil(() => u.isVisible(modal.el), 1000);
const view = _converse.xmppstatusview;
const msg = 'I am happy';
modal.el.querySelector('input[name="status_message"]').value = msg;
@ -202,7 +202,7 @@
const cbview = _converse.chatboxviews.get('controlbox');
cbview.el.querySelector('.add-contact').click()
const modal = _converse.rosterview.add_contact_modal;
await test_utils.waitUntil(() => u.isVisible(modal.el), 1000);
await u.waitUntil(() => u.isVisible(modal.el), 1000);
const sendIQ = _converse.connection.sendIQ;
let sent_stanza, IQ_id;
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
@ -240,7 +240,7 @@
expect(modal.jid_auto_complete).toBe(undefined);
expect(modal.name_auto_complete).toBe(undefined);
await test_utils.waitUntil(() => u.isVisible(modal.el), 1000);
await u.waitUntil(() => u.isVisible(modal.el), 1000);
expect(!_.isNull(modal.el.querySelector('form.add-xmpp-contact'))).toBeTruthy();
const input_jid = modal.el.querySelector('input[name="jid"]');
const input_name = modal.el.querySelector('input[name="name"]');
@ -248,7 +248,7 @@
modal.el.querySelector('button[type="submit"]').click();
const IQ_stanzas = _converse.connection.IQ_stanzas;
const sent_stanza = await test_utils.waitUntil(
const sent_stanza = await u.waitUntil(
() => IQ_stanzas.filter(s => sizzle(`query[xmlns="${Strophe.NS.ROSTER}"]`, s).length).pop()
);
expect(Strophe.serialize(sent_stanza)).toEqual(
@ -284,7 +284,7 @@
const cbview = _converse.chatboxviews.get('controlbox');
cbview.el.querySelector('.add-contact').click()
const modal = _converse.rosterview.add_contact_modal;
await test_utils.waitUntil(() => u.isVisible(modal.el), 1000);
await u.waitUntil(() => u.isVisible(modal.el), 1000);
// We only have autocomplete for the name input
expect(modal.jid_auto_complete).toBe(undefined);
@ -293,7 +293,7 @@
const input_el = modal.el.querySelector('input[name="name"]');
input_el.value = 'marty';
input_el.dispatchEvent(new Event('input'));
await test_utils.waitUntil(() => modal.el.querySelector('.suggestion-box li'), 1000);
await u.waitUntil(() => modal.el.querySelector('.suggestion-box li'), 1000);
const sendIQ = _converse.connection.sendIQ;
let sent_stanza, IQ_id;
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
@ -357,7 +357,7 @@
const cbview = _converse.chatboxviews.get('controlbox');
cbview.el.querySelector('.add-contact').click()
modal = _converse.rosterview.add_contact_modal;
await test_utils.waitUntil(() => u.isVisible(modal.el), 1000);
await u.waitUntil(() => u.isVisible(modal.el), 1000);
expect(modal.jid_auto_complete).toBe(undefined);
expect(modal.name_auto_complete).toBe(undefined);

View File

@ -271,10 +271,10 @@
expect(box.get('box_id')).toBe(`box-${btoa(jid)}`);
const view = _converse.chatboxviews.get(jid);
await test_utils.waitUntil(() => u.isVisible(view.el));
await u.waitUntil(() => u.isVisible(view.el));
// Test for multiple JIDs
test_utils.openChatBoxFor(_converse, jid2);
await test_utils.waitUntil(() => _converse.chatboxes.length == 2);
await u.waitUntil(() => _converse.chatboxes.length == 2);
const list = _converse.api.chats.get([jid, jid2]);
expect(Array.isArray(list)).toBeTruthy();
expect(list[0].get('box_id')).toBe(`box-${btoa(jid)}`);
@ -303,7 +303,7 @@
['close', 'endOTR', 'focus', 'get', 'initiateOTR', 'is_chatroom', 'maximize', 'minimize', 'open', 'set']
);
const view = _converse.chatboxviews.get(jid);
await test_utils.waitUntil(() => u.isVisible(view.el));
await u.waitUntil(() => u.isVisible(view.el));
// Test for multiple JIDs
const list = await _converse.api.chats.open([jid, jid2]);
expect(Array.isArray(list)).toBeTruthy();

View File

@ -8,6 +8,7 @@
const Strophe = converse.env.Strophe;
const $iq = converse.env.$iq;
const _ = converse.env._;
const u = converse.env.utils;
describe("Service Discovery", function () {
@ -16,167 +17,162 @@
it("stores the features it receives",
mock.initConverse(
null, ['discoInitialized'], {},
function (done, _converse) {
async function (done, _converse) {
const IQ_stanzas = _converse.connection.IQ_stanzas;
const IQ_ids = _converse.connection.IQ_ids;
test_utils.waitUntil(function () {
await u.waitUntil(function () {
return _.filter(IQ_stanzas, function (iq) {
return iq.querySelector('iq[to="montague.lit"] query[xmlns="http://jabber.org/protocol/disco#info"]');
}).length > 0;
}, 300).then(function () {
/* <iq type='result'
* from='plays.shakespeare.lit'
* to='romeo@montague.net/orchard'
* id='info1'>
* <query xmlns='http://jabber.org/protocol/disco#info'>
* <identity
* category='server'
* type='im'/>
* <identity
* category='conference'
* type='text'
* name='Play-Specific Chatrooms'/>
* <identity
* category='directory'
* type='chatroom'
* name='Play-Specific Chatrooms'/>
* <feature var='http://jabber.org/protocol/disco#info'/>
* <feature var='http://jabber.org/protocol/disco#items'/>
* <feature var='http://jabber.org/protocol/muc'/>
* <feature var='jabber:iq:register'/>
* <feature var='jabber:iq:search'/>
* <feature var='jabber:iq:time'/>
* <feature var='jabber:iq:version'/>
* </query>
* </iq>
*/
var stanza = _.find(IQ_stanzas, function (iq) {
return iq.querySelector('iq[to="montague.lit"] query[xmlns="http://jabber.org/protocol/disco#info"]');
});
var info_IQ_id = IQ_ids[IQ_stanzas.indexOf(stanza)];
stanza = $iq({
'type': 'result',
'from': 'montague.lit',
'to': 'romeo@montague.lit/orchard',
'id': info_IQ_id
}).c('query', {'xmlns': 'http://jabber.org/protocol/disco#info'})
.c('identity', {
'category': 'server',
'type': 'im'}).up()
.c('identity', {
'category': 'conference',
'type': 'text',
'name': 'Play-Specific Chatrooms'}).up()
.c('identity', {
'category': 'directory',
'type': 'chatroom',
'name': 'Play-Specific Chatrooms'}).up()
.c('feature', {
'var': 'http://jabber.org/protocol/disco#info'}).up()
.c('feature', {
'var': 'http://jabber.org/protocol/disco#items'}).up()
.c('feature', {
'var': 'jabber:iq:register'}).up()
.c('feature', {
'var': 'jabber:iq:time'}).up()
.c('feature', {
'var': 'jabber:iq:version'});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
_converse.api.disco.entities.get().then(function (entities) {
expect(entities.length).toBe(2); // We have an extra entity, which is the user's JID
expect(entities.get(_converse.domain).features.length).toBe(5);
expect(entities.get(_converse.domain).identities.length).toBe(3);
expect(entities.get('montague.lit').features.where({'var': 'jabber:iq:version'}).length).toBe(1);
expect(entities.get('montague.lit').features.where({'var': 'jabber:iq:time'}).length).toBe(1);
expect(entities.get('montague.lit').features.where({'var': 'jabber:iq:register'}).length).toBe(1);
expect(entities.get('montague.lit').features.where(
{'var': 'http://jabber.org/protocol/disco#items'}).length).toBe(1);
expect(entities.get('montague.lit').features.where(
{'var': 'http://jabber.org/protocol/disco#info'}).length).toBe(1);
test_utils.waitUntil(function () {
// Converse.js sees that the entity has a disco#items feature,
// so it will make a query for it.
return _.filter(IQ_stanzas, function (iq) {
return iq.querySelector('query[xmlns="http://jabber.org/protocol/disco#items"]');
}).length > 0;
}, 300).then(function () {
/* <iq type='result'
* from='catalog.shakespeare.lit'
* to='romeo@montague.net/orchard'
* id='items2'>
* <query xmlns='http://jabber.org/protocol/disco#items'>
* <item jid='people.shakespeare.lit'
* name='Directory of Characters'/>
* <item jid='plays.shakespeare.lit'
* name='Play-Specific Chatrooms'/>
* <item jid='mim.shakespeare.lit'
* name='Gateway to Marlowe IM'/>
* <item jid='words.shakespeare.lit'
* name='Shakespearean Lexicon'/>
*
* <item jid='catalog.shakespeare.lit'
* node='books'
* name='Books by and about Shakespeare'/>
* <item jid='catalog.shakespeare.lit'
* node='clothing'
* name='Wear your literary taste with pride'/>
* <item jid='catalog.shakespeare.lit'
* node='music'
* name='Music from the time of Shakespeare'/>
* </query>
* </iq>
*/
var stanza = _.find(IQ_stanzas, function (iq) {
return iq.querySelector('iq[to="montague.lit"] query[xmlns="http://jabber.org/protocol/disco#items"]');
});
var items_IQ_id = IQ_ids[IQ_stanzas.indexOf(stanza)];
stanza = $iq({
'type': 'result',
'from': 'montague.lit',
'to': 'romeo@montague.lit/orchard',
'id': items_IQ_id
}).c('query', {'xmlns': 'http://jabber.org/protocol/disco#items'})
.c('item', {
'jid': 'people.shakespeare.lit',
'name': 'Directory of Characters'}).up()
.c('item', {
'jid': 'plays.shakespeare.lit',
'name': 'Play-Specific Chatrooms'}).up()
.c('item', {
'jid': 'words.shakespeare.lit',
'name': 'Gateway to Marlowe IM'}).up()
.c('item', {
'jid': 'montague.lit',
'node': 'books',
'name': 'Books by and about Shakespeare'}).up()
.c('item', {
'node': 'montague.lit',
'name': 'Wear your literary taste with pride'}).up()
.c('item', {
'jid': 'montague.lit',
'node': 'music',
'name': 'Music from the time of Shakespeare'
});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
return test_utils.waitUntil(() => _converse.disco_entities);
}).then(() => {
const entities = _converse.disco_entities;
expect(entities.length).toBe(2); // We have an extra entity, which is the user's JID
expect(entities.get(_converse.domain).items.length).toBe(3);
expect(_.includes(entities.get(_converse.domain).items.pluck('jid'), 'people.shakespeare.lit')).toBeTruthy();
expect(_.includes(entities.get(_converse.domain).items.pluck('jid'), 'plays.shakespeare.lit')).toBeTruthy();
expect(_.includes(entities.get(_converse.domain).items.pluck('jid'), 'words.shakespeare.lit')).toBeTruthy();
expect(entities.get(_converse.domain).identities.where({'category': 'conference'}).length).toBe(1);
expect(entities.get(_converse.domain).identities.where({'category': 'directory'}).length).toBe(1);
done();
});
});
});
/* <iq type='result'
* from='plays.shakespeare.lit'
* to='romeo@montague.net/orchard'
* id='info1'>
* <query xmlns='http://jabber.org/protocol/disco#info'>
* <identity
* category='server'
* type='im'/>
* <identity
* category='conference'
* type='text'
* name='Play-Specific Chatrooms'/>
* <identity
* category='directory'
* type='chatroom'
* name='Play-Specific Chatrooms'/>
* <feature var='http://jabber.org/protocol/disco#info'/>
* <feature var='http://jabber.org/protocol/disco#items'/>
* <feature var='http://jabber.org/protocol/muc'/>
* <feature var='jabber:iq:register'/>
* <feature var='jabber:iq:search'/>
* <feature var='jabber:iq:time'/>
* <feature var='jabber:iq:version'/>
* </query>
* </iq>
*/
let stanza = _.find(IQ_stanzas, function (iq) {
return iq.querySelector('iq[to="montague.lit"] query[xmlns="http://jabber.org/protocol/disco#info"]');
});
const info_IQ_id = IQ_ids[IQ_stanzas.indexOf(stanza)];
stanza = $iq({
'type': 'result',
'from': 'montague.lit',
'to': 'romeo@montague.lit/orchard',
'id': info_IQ_id
}).c('query', {'xmlns': 'http://jabber.org/protocol/disco#info'})
.c('identity', {
'category': 'server',
'type': 'im'}).up()
.c('identity', {
'category': 'conference',
'type': 'text',
'name': 'Play-Specific Chatrooms'}).up()
.c('identity', {
'category': 'directory',
'type': 'chatroom',
'name': 'Play-Specific Chatrooms'}).up()
.c('feature', {
'var': 'http://jabber.org/protocol/disco#info'}).up()
.c('feature', {
'var': 'http://jabber.org/protocol/disco#items'}).up()
.c('feature', {
'var': 'jabber:iq:register'}).up()
.c('feature', {
'var': 'jabber:iq:time'}).up()
.c('feature', {
'var': 'jabber:iq:version'});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
let entities = await _converse.api.disco.entities.get()
expect(entities.length).toBe(2); // We have an extra entity, which is the user's JID
expect(entities.get(_converse.domain).features.length).toBe(5);
expect(entities.get(_converse.domain).identities.length).toBe(3);
expect(entities.get('montague.lit').features.where({'var': 'jabber:iq:version'}).length).toBe(1);
expect(entities.get('montague.lit').features.where({'var': 'jabber:iq:time'}).length).toBe(1);
expect(entities.get('montague.lit').features.where({'var': 'jabber:iq:register'}).length).toBe(1);
expect(entities.get('montague.lit').features.where(
{'var': 'http://jabber.org/protocol/disco#items'}).length).toBe(1);
expect(entities.get('montague.lit').features.where(
{'var': 'http://jabber.org/protocol/disco#info'}).length).toBe(1);
await u.waitUntil(function () {
// Converse.js sees that the entity has a disco#items feature,
// so it will make a query for it.
return _.filter(IQ_stanzas, function (iq) {
return iq.querySelector('query[xmlns="http://jabber.org/protocol/disco#items"]');
}).length > 0;
});
/* <iq type='result'
* from='catalog.shakespeare.lit'
* to='romeo@montague.net/orchard'
* id='items2'>
* <query xmlns='http://jabber.org/protocol/disco#items'>
* <item jid='people.shakespeare.lit'
* name='Directory of Characters'/>
* <item jid='plays.shakespeare.lit'
* name='Play-Specific Chatrooms'/>
* <item jid='mim.shakespeare.lit'
* name='Gateway to Marlowe IM'/>
* <item jid='words.shakespeare.lit'
* name='Shakespearean Lexicon'/>
*
* <item jid='catalog.shakespeare.lit'
* node='books'
* name='Books by and about Shakespeare'/>
* <item jid='catalog.shakespeare.lit'
* node='clothing'
* name='Wear your literary taste with pride'/>
* <item jid='catalog.shakespeare.lit'
* node='music'
* name='Music from the time of Shakespeare'/>
* </query>
* </iq>
*/
stanza = _.find(IQ_stanzas, function (iq) {
return iq.querySelector('iq[to="montague.lit"] query[xmlns="http://jabber.org/protocol/disco#items"]');
});
var items_IQ_id = IQ_ids[IQ_stanzas.indexOf(stanza)];
stanza = $iq({
'type': 'result',
'from': 'montague.lit',
'to': 'romeo@montague.lit/orchard',
'id': items_IQ_id
}).c('query', {'xmlns': 'http://jabber.org/protocol/disco#items'})
.c('item', {
'jid': 'people.shakespeare.lit',
'name': 'Directory of Characters'}).up()
.c('item', {
'jid': 'plays.shakespeare.lit',
'name': 'Play-Specific Chatrooms'}).up()
.c('item', {
'jid': 'words.shakespeare.lit',
'name': 'Gateway to Marlowe IM'}).up()
.c('item', {
'jid': 'montague.lit',
'node': 'books',
'name': 'Books by and about Shakespeare'}).up()
.c('item', {
'node': 'montague.lit',
'name': 'Wear your literary taste with pride'}).up()
.c('item', {
'jid': 'montague.lit',
'node': 'music',
'name': 'Music from the time of Shakespeare'
});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await u.waitUntil(() => _converse.disco_entities);
entities = _converse.disco_entities;
expect(entities.length).toBe(2); // We have an extra entity, which is the user's JID
expect(entities.get(_converse.domain).items.length).toBe(3);
expect(_.includes(entities.get(_converse.domain).items.pluck('jid'), 'people.shakespeare.lit')).toBeTruthy();
expect(_.includes(entities.get(_converse.domain).items.pluck('jid'), 'plays.shakespeare.lit')).toBeTruthy();
expect(_.includes(entities.get(_converse.domain).items.pluck('jid'), 'words.shakespeare.lit')).toBeTruthy();
expect(entities.get(_converse.domain).identities.where({'category': 'conference'}).length).toBe(1);
expect(entities.get(_converse.domain).identities.where({'category': 'directory'}).length).toBe(1);
done();
}));
});

View File

@ -19,7 +19,7 @@
const IQ_stanzas = _converse.connection.IQ_stanzas;
const IQ_ids = _converse.connection.IQ_ids;
await test_utils.waitUntilDiscoConfirmed(_converse, _converse.bare_jid, [], []);
await test_utils.waitUntil(() => _.filter(
await u.waitUntil(() => _.filter(
IQ_stanzas,
iq => iq.querySelector('iq[to="montague.lit"] query[xmlns="http://jabber.org/protocol/disco#info"]')).length
);
@ -67,7 +67,7 @@
// Converse.js sees that the entity has a disco#items feature,
// so it will make a query for it.
await test_utils.waitUntil(() => _.filter(
await u.waitUntil(() => _.filter(
IQ_stanzas,
iq => iq.querySelector('iq[to="montague.lit"] query[xmlns="http://jabber.org/protocol/disco#items"]')
).length
@ -101,7 +101,7 @@
_converse.api.disco.entities.get().then(function (entities) {
expect(entities.length).toBe(2);
expect(entities.get('montague.lit').items.length).toBe(1);
return test_utils.waitUntil(function () {
return u.waitUntil(function () {
// Converse.js sees that the entity has a disco#info feature,
// so it will make a query for it.
return _.filter(IQ_stanzas, function (iq) {
@ -110,7 +110,7 @@
}, 300);
});
stanza = await test_utils.waitUntil(() =>
stanza = await u.waitUntil(() =>
_.filter(
IQ_stanzas,
iq => iq.querySelector('iq[to="upload.montague.lit"] query[xmlns="http://jabber.org/protocol/disco#info"]')
@ -223,7 +223,7 @@
const contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@montague.lit';
await test_utils.openChatBoxFor(_converse, contact_jid);
const view = _converse.chatboxviews.get(contact_jid);
test_utils.waitUntil(() => view.el.querySelector('.upload-file'));
u.waitUntil(() => view.el.querySelector('.upload-file'));
expect(view.el.querySelector('.chat-toolbar .upload-file')).not.toBe(null);
done();
}));
@ -240,7 +240,7 @@
await test_utils.waitUntilDiscoConfirmed(_converse, _converse.domain, [], [], ['upload.montague.lit'], 'items');
await test_utils.waitUntilDiscoConfirmed(_converse, 'upload.montague.lit', [], [Strophe.NS.HTTPUPLOAD], []);
await test_utils.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
await test_utils.waitUntil(() => _converse.chatboxviews.get('lounge@montague.lit').el.querySelector('.upload-file'));
await u.waitUntil(() => _converse.chatboxviews.get('lounge@montague.lit').el.querySelector('.upload-file'));
const view = _converse.chatboxviews.get('lounge@montague.lit');
expect(view.el.querySelector('.chat-toolbar .upload-file')).not.toBe(null);
done();
@ -274,7 +274,7 @@
view.model.sendFiles([file]);
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
await test_utils.waitUntil(() => _.filter(IQ_stanzas, iq => iq.querySelector('iq[to="upload.montague.tld"] request')).length);
await u.waitUntil(() => _.filter(IQ_stanzas, iq => iq.querySelector('iq[to="upload.montague.tld"] request')).length);
const iq = IQ_stanzas.pop();
expect(Strophe.serialize(iq)).toBe(
`<iq from="romeo@montague.lit/orchard" `+
@ -309,10 +309,10 @@
const message = view.model.messages.at(0);
expect(view.el.querySelector('.chat-content progress').getAttribute('value')).toBe('0');
message.set('progress', 0.5);
test_utils.waitUntil(() => view.el.querySelector('.chat-content progress').getAttribute('value') === '0.5')
u.waitUntil(() => view.el.querySelector('.chat-content progress').getAttribute('value') === '0.5')
.then(() => {
message.set('progress', 1);
test_utils.waitUntil(() => view.el.querySelector('.chat-content progress').getAttribute('value') === '1')
u.waitUntil(() => view.el.querySelector('.chat-content progress').getAttribute('value') === '1')
}).then(() => {
message.save({
'upload': _converse.SUCCESS,
@ -326,7 +326,7 @@
spyOn(_converse.connection, 'send').and.callFake(stanza => (sent_stanza = stanza));
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => sent_stanza, 1000);
await u.waitUntil(() => sent_stanza, 1000);
expect(sent_stanza.toLocaleString()).toBe(
`<message from="romeo@montague.lit/orchard" `+
`id="${sent_stanza.nodeTree.getAttribute("id")}" `+
@ -341,7 +341,7 @@
`</x>`+
`<origin-id id="${sent_stanza.nodeTree.querySelector('origin-id').getAttribute("id")}" xmlns="urn:xmpp:sid:0"/>`+
`</message>`);
await test_utils.waitUntil(() => view.el.querySelector('.chat-image'), 1000);
await u.waitUntil(() => view.el.querySelector('.chat-image'), 1000);
// Check that the image renders
expect(view.el.querySelector('.chat-msg .chat-msg__media').innerHTML.trim()).toEqual(
`<!-- src/templates/image.html -->\n`+
@ -369,7 +369,7 @@
// Wait until MAM query has been sent out
const sent_stanzas = _converse.connection.sent_stanzas;
await test_utils.waitUntil(() => sent_stanzas.filter(s => sizzle(`[xmlns="${Strophe.NS.MAM}"]`, s).length).pop());
await u.waitUntil(() => sent_stanzas.filter(s => sizzle(`[xmlns="${Strophe.NS.MAM}"]`, s).length).pop());
const view = _converse.chatboxviews.get('lounge@montague.lit');
const file = {
@ -381,7 +381,7 @@
view.model.sendFiles([file]);
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
await test_utils.waitUntil(() => _.filter(IQ_stanzas, iq => iq.querySelector('iq[to="upload.montague.tld"] request')).length);
await u.waitUntil(() => _.filter(IQ_stanzas, iq => iq.querySelector('iq[to="upload.montague.tld"] request')).length);
const iq = IQ_stanzas.pop();
expect(Strophe.serialize(iq)).toBe(
`<iq from="romeo@montague.lit/orchard" `+
@ -415,10 +415,10 @@
const message = view.model.messages.at(0);
expect(view.el.querySelector('.chat-content progress').getAttribute('value')).toBe('0');
message.set('progress', 0.5);
test_utils.waitUntil(() => view.el.querySelector('.chat-content progress').getAttribute('value') === '0.5')
u.waitUntil(() => view.el.querySelector('.chat-content progress').getAttribute('value') === '0.5')
.then(() => {
message.set('progress', 1);
test_utils.waitUntil(() => view.el.querySelector('.chat-content progress').getAttribute('value') === '1')
u.waitUntil(() => view.el.querySelector('.chat-content progress').getAttribute('value') === '1')
}).then(() => {
message.save({
'upload': _converse.SUCCESS,
@ -432,7 +432,7 @@
spyOn(_converse.connection, 'send').and.callFake(stanza => (sent_stanza = stanza));
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => sent_stanza, 1000);
await u.waitUntil(() => sent_stanza, 1000);
expect(sent_stanza.toLocaleString()).toBe(
`<message `+
`from="romeo@montague.lit/orchard" `+
@ -447,7 +447,7 @@
`</x>`+
`<origin-id id="${sent_stanza.nodeTree.querySelector('origin-id').getAttribute("id")}" xmlns="urn:xmpp:sid:0"/>`+
`</message>`);
await test_utils.waitUntil(() => view.el.querySelector('.chat-image'), 1000);
await u.waitUntil(() => view.el.querySelector('.chat-image'), 1000);
// Check that the image renders
expect(view.el.querySelector('.chat-msg .chat-msg__media').innerHTML.trim()).toEqual(
`<!-- src/templates/image.html -->\n`+
@ -464,7 +464,7 @@
const send_backup = XMLHttpRequest.prototype.send;
await test_utils.waitUntilDiscoConfirmed(_converse, _converse.bare_jid, [], []);
await test_utils.waitUntil(() => _.filter(
await u.waitUntil(() => _.filter(
IQ_stanzas,
iq => iq.querySelector('iq[to="montague.lit"] query[xmlns="http://jabber.org/protocol/disco#info"]')).length
);
@ -497,7 +497,7 @@
expect(entities.get(_converse.domain).features.length).toBe(2);
expect(entities.get(_converse.domain).identities.length).toBe(1);
await test_utils.waitUntil(function () {
await u.waitUntil(function () {
// Converse.js sees that the entity has a disco#items feature,
// so it will make a query for it.
return _.filter(IQ_stanzas, function (iq) {
@ -525,7 +525,7 @@
expect(entities.length).toBe(2);
expect(entities.get('montague.lit').items.length).toBe(1);
await test_utils.waitUntil(function () {
await u.waitUntil(function () {
// Converse.js sees that the entity has a disco#info feature,
// so it will make a query for it.
return _.filter(IQ_stanzas, function (iq) {
@ -567,7 +567,7 @@
'name': "my-juliet.jpg"
};
view.model.sendFiles([file]);
await test_utils.waitUntil(() => view.el.querySelectorAll('.message').length)
await u.waitUntil(() => view.el.querySelectorAll('.message').length)
const messages = view.el.querySelectorAll('.message.chat-error');
expect(messages.length).toBe(1);
expect(messages[0].textContent).toBe(
@ -606,7 +606,7 @@
};
view.model.sendFiles([file]);
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
await test_utils.waitUntil(() => _.filter(IQ_stanzas, iq => iq.querySelector('iq[to="upload.montague.tld"] request')).length)
await u.waitUntil(() => _.filter(IQ_stanzas, iq => iq.querySelector('iq[to="upload.montague.tld"] request')).length)
const iq = IQ_stanzas.pop();
expect(Strophe.serialize(iq)).toBe(
`<iq from="romeo@montague.lit/orchard" `+
@ -640,10 +640,10 @@
const message = view.model.messages.at(0);
expect(view.el.querySelector('.chat-content progress').getAttribute('value')).toBe('0');
message.set('progress', 0.5);
test_utils.waitUntil(() => view.el.querySelector('.chat-content progress').getAttribute('value') === '0.5')
u.waitUntil(() => view.el.querySelector('.chat-content progress').getAttribute('value') === '0.5')
.then(() => {
message.set('progress', 1);
test_utils.waitUntil(() => view.el.querySelector('.chat-content progress').getAttribute('value') === '1')
u.waitUntil(() => view.el.querySelector('.chat-content progress').getAttribute('value') === '1')
}).then(() => {
expect(view.el.querySelector('.chat-content .chat-msg__text').textContent).toBe('Uploading file: my-juliet.jpg, 22.91 KB');
done();

View File

@ -2,6 +2,8 @@
define(["jasmine", "mock", "test-utils"], factory);
} (this, function (jasmine, mock, test_utils) {
const u = converse.env.utils;
describe("The Login Form", function () {
it("contains a checkbox to indicate whether the computer is trusted or not",
@ -12,7 +14,7 @@
async function (done, _converse) {
test_utils.openControlBox();
const cbview = await test_utils.waitUntil(() => _converse.chatboxviews.get('controlbox'));
const cbview = await u.waitUntil(() => _converse.chatboxviews.get('controlbox'));
const checkboxes = cbview.el.querySelectorAll('input[type="checkbox"]');
expect(checkboxes.length).toBe(1);
@ -46,7 +48,7 @@
allow_registration: false },
function (done, _converse) {
test_utils.waitUntil(() => _converse.chatboxviews.get('controlbox'))
u.waitUntil(() => _converse.chatboxviews.get('controlbox'))
.then(() => {
var cbview = _converse.chatboxviews.get('controlbox');
test_utils.openControlBox();

View File

@ -33,7 +33,7 @@
<stanza-id xmlns="urn:xmpp:sid:0" id="45fbbf2a-1059-479d-9283-c8effaf05621" by="trek-radio@conference.lightwitch.org"/>
</message>`);
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => view.content.querySelectorAll('.chat-msg').length);
await u.waitUntil(() => view.content.querySelectorAll('.chat-msg').length);
expect(view.model.messages.length).toBe(1);
expect(view.model.messages.at(0).get('is_archived')).toBe(false);
expect(view.model.messages.at(0).get('stanza_id trek-radio@conference.lightwitch.org')).toBe('45fbbf2a-1059-479d-9283-c8effaf05621');
@ -54,13 +54,13 @@
spyOn(view.model, 'findDuplicateFromArchiveID').and.callThrough();
spyOn(view.model, 'updateMessage').and.callThrough();
view.model.onMessage(stanza);
await test_utils.waitUntil(() => view.model.findDuplicateFromArchiveID.calls.count());
await u.waitUntil(() => view.model.findDuplicateFromArchiveID.calls.count());
expect(view.model.findDuplicateFromArchiveID.calls.count()).toBe(1);
const result = await view.model.findDuplicateFromArchiveID.calls.all()[0].returnValue
expect(result instanceof _converse.Message).toBe(true);
expect(view.content.querySelectorAll('.chat-msg').length).toBe(1);
await test_utils.waitUntil(() => view.model.updateMessage.calls.count());
await u.waitUntil(() => view.model.updateMessage.calls.count());
expect(view.model.messages.length).toBe(1);
expect(view.model.messages.at(0).get('is_archived')).toBe(true);
expect(view.model.messages.at(0).get('stanza_id trek-radio@conference.lightwitch.org')).toBe('45fbbf2a-1059-479d-9283-c8effaf05621');
@ -80,7 +80,7 @@
<stanza-id xmlns="urn:xmpp:sid:0" id="45fbbf2a-1059-479d-9283-c8effaf05621" by="trek-radio@conference.lightwitch.org"/>
</message>`);
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => view.content.querySelectorAll('.chat-msg').length);
await u.waitUntil(() => view.content.querySelectorAll('.chat-msg').length);
// Not sure whether such a race-condition might pose a problem
// in "real-world" situations.
stanza = u.toStanza(
@ -98,7 +98,7 @@
</message>`);
spyOn(view.model, 'findDuplicateFromArchiveID').and.callThrough();
view.model.onMessage(stanza);
await test_utils.waitUntil(() => view.model.findDuplicateFromArchiveID.calls.count());
await u.waitUntil(() => view.model.findDuplicateFromArchiveID.calls.count());
expect(view.model.findDuplicateFromArchiveID.calls.count()).toBe(1);
const result = await view.model.findDuplicateFromArchiveID.calls.all()[0].returnValue
expect(result instanceof _converse.Message).toBe(true);
@ -128,7 +128,7 @@
</result>
</message>`);
view.model.onMessage(stanza);
await test_utils.waitUntil(() => view.content.querySelectorAll('.chat-msg').length);
await u.waitUntil(() => view.content.querySelectorAll('.chat-msg').length);
expect(view.content.querySelectorAll('.chat-msg').length).toBe(1);
stanza = u.toStanza(
@ -148,7 +148,7 @@
spyOn(view.model, 'findDuplicateFromArchiveID').and.callThrough();
view.model.onMessage(stanza);
await test_utils.waitUntil(() => view.model.findDuplicateFromArchiveID.calls.count());
await u.waitUntil(() => view.model.findDuplicateFromArchiveID.calls.count());
expect(view.model.findDuplicateFromArchiveID.calls.count()).toBe(1);
const result = await view.model.findDuplicateFromArchiveID.calls.all()[0].returnValue
expect(result instanceof _converse.Message).toBe(true);
@ -173,7 +173,7 @@
IQ_id = sendIQ.bind(this)(iq, callback, errback);
});
_converse.api.archive.query();
await test_utils.waitUntil(() => sent_stanza);
await u.waitUntil(() => sent_stanza);
const queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
expect(sent_stanza.toString()).toBe(
`<iq id="${IQ_id}" type="set" xmlns="jabber:client"><query queryid="${queryid}" xmlns="urn:xmpp:mam:2"/></iq>`);
@ -193,7 +193,7 @@
IQ_id = sendIQ.bind(this)(iq, callback, errback);
});
_converse.api.archive.query({'with':'juliet@capulet.lit'});
await test_utils.waitUntil(() => sent_stanza);
await u.waitUntil(() => sent_stanza);
const queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
expect(sent_stanza.toString()).toBe(
`<iq id="${IQ_id}" type="set" xmlns="jabber:client">`+
@ -221,7 +221,7 @@
await test_utils.waitUntilDiscoConfirmed(_converse, room_jid, null, [Strophe.NS.MAM]);
const sent_stanzas = _converse.connection.sent_stanzas;
const stanza = await test_utils.waitUntil(
const stanza = await u.waitUntil(
() => sent_stanzas.filter(s => sizzle(`[xmlns="${Strophe.NS.MAM}"]`, s).length).pop());
const queryid = stanza.querySelector('query').getAttribute('queryid');
@ -249,7 +249,7 @@
await test_utils.waitUntilDiscoConfirmed(_converse, room_jid, null, [Strophe.NS.MAM]);
const sent_stanzas = _converse.connection.sent_stanzas;
const sent_stanza = await test_utils.waitUntil(
const sent_stanza = await u.waitUntil(
() => sent_stanzas.filter(s => sizzle(`[xmlns="${Strophe.NS.MAM}"]`, s).length).pop());
const queryid = sent_stanza.querySelector('query').getAttribute('queryid');
@ -327,7 +327,7 @@
'start': start,
'end': end
});
await test_utils.waitUntil(() => sent_stanza);
await u.waitUntil(() => sent_stanza);
const queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
expect(sent_stanza.toString()).toBe(
`<iq id="${IQ_id}" type="set" xmlns="jabber:client">`+
@ -380,7 +380,7 @@
}
const start = '2010-06-07T00:00:00Z';
_converse.api.archive.query({'start': start});
await test_utils.waitUntil(() => sent_stanza);
await u.waitUntil(() => sent_stanza);
const queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
expect(sent_stanza.toString()).toBe(
`<iq id="${IQ_id}" type="set" xmlns="jabber:client">`+
@ -413,7 +413,7 @@
});
const start = '2010-06-07T00:00:00Z';
_converse.api.archive.query({'start': start, 'max':10});
await test_utils.waitUntil(() => sent_stanza);
await u.waitUntil(() => sent_stanza);
const queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
expect(sent_stanza.toString()).toBe(
`<iq id="${IQ_id}" type="set" xmlns="jabber:client">`+
@ -453,7 +453,7 @@
'after': '09af3-cc343-b409f',
'max':10
});
await test_utils.waitUntil(() => sent_stanza);
await u.waitUntil(() => sent_stanza);
const queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
expect(sent_stanza.toString()).toBe(
`<iq id="${IQ_id}" type="set" xmlns="jabber:client">`+
@ -488,7 +488,7 @@
IQ_id = sendIQ.bind(this)(iq, callback, errback);
});
_converse.api.archive.query({'before': '', 'max':10});
await test_utils.waitUntil(() => sent_stanza);
await u.waitUntil(() => sent_stanza);
const queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
expect(sent_stanza.toString()).toBe(
`<iq id="${IQ_id}" type="set" xmlns="jabber:client">`+
@ -527,7 +527,7 @@
rsm['with'] = 'romeo@montague.lit'; // eslint-disable-line dot-notation
rsm.start = '2010-06-07T00:00:00Z';
_converse.api.archive.query(rsm);
await test_utils.waitUntil(() => sent_stanza);
await u.waitUntil(() => sent_stanza);
const queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
expect(sent_stanza.toString()).toBe(
`<iq id="${IQ_id}" type="set" xmlns="jabber:client">`+
@ -564,7 +564,7 @@
IQ_id = sendIQ.bind(this)(iq, callback, errback);
});
const promise = _converse.api.archive.query({'with': 'romeo@capulet.lit', 'max':'10'});
await test_utils.waitUntil(() => sent_stanza);
await u.waitUntil(() => sent_stanza);
const queryid = sent_stanza.nodeTree.querySelector('query').getAttribute('queryid');
/* <message id='aeb213' to='juliet@capulet.lit/chamber'>
@ -682,7 +682,7 @@
.c('never').c('jid').t('montague@montague.lit');
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => _converse.onMAMPreferences.calls.count());
await u.waitUntil(() => _converse.onMAMPreferences.calls.count());
expect(_converse.onMAMPreferences).toHaveBeenCalled();
expect(sent_stanza.toString()).toBe(
@ -711,7 +711,7 @@
.c('always').up()
.c('never');
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => feature.save.calls.count());
await u.waitUntil(() => feature.save.calls.count());
expect(feature.save).toHaveBeenCalled();
expect(feature.get('preferences')['default']).toBe('never'); // eslint-disable-line dot-notation
done();
@ -738,7 +738,7 @@
sent_stanza = iq;
IQ_id = sendIQ.bind(this)(iq, callback, errback);
});
await test_utils.waitUntil(() => sent_stanza);
await u.waitUntil(() => sent_stanza);
const stanza_el = sent_stanza.root().nodeTree;
const queryid = stanza_el.querySelector('query').getAttribute('queryid');
expect(sent_stanza.toString()).toBe(

View File

@ -94,7 +94,7 @@
expect(textarea.value).toBe('But soft, what light through yonder window breaks?');
expect(view.model.messages.at(0).get('correcting')).toBe(true);
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
await test_utils.waitUntil(() => u.hasClass('correcting', view.el.querySelector('.chat-msg')) === true);
await u.waitUntil(() => u.hasClass('correcting', view.el.querySelector('.chat-msg')) === true);
action = view.el.querySelector('.chat-msg .chat-msg__action');
action.style.opacity = 1;
@ -102,7 +102,7 @@
expect(textarea.value).toBe('');
expect(view.model.messages.at(0).get('correcting')).toBe(false);
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
await test_utils.waitUntil(() => (u.hasClass('correcting', view.el.querySelector('.chat-msg')) === false), 500);
await u.waitUntil(() => (u.hasClass('correcting', view.el.querySelector('.chat-msg')) === false), 500);
// Test that messages from other users don't have the pencil icon
_converse.chatboxes.onMessage(
@ -178,7 +178,7 @@
expect(textarea.value).toBe('But soft, what light through yonder airlock breaks?');
expect(view.model.messages.at(0).get('correcting')).toBe(true);
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
await test_utils.waitUntil(() => u.hasClass('correcting', view.el.querySelector('.chat-msg')), 500);
await u.waitUntil(() => u.hasClass('correcting', view.el.querySelector('.chat-msg')), 500);
spyOn(_converse.connection, 'send');
textarea.value = 'But soft, what light through yonder window breaks?';
@ -212,7 +212,7 @@
expect(older_versions[keys[0]]).toBe('But soft, what light through yonder airlock breaks?');
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
await test_utils.waitUntil(() => (u.hasClass('correcting', view.el.querySelector('.chat-msg')) === false), 500);
await u.waitUntil(() => (u.hasClass('correcting', view.el.querySelector('.chat-msg')) === false), 500);
// Test that pressing the down arrow cancels message correction
expect(textarea.value).toBe('');
@ -223,7 +223,7 @@
expect(textarea.value).toBe('But soft, what light through yonder window breaks?');
expect(view.model.messages.at(0).get('correcting')).toBe(true);
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
await test_utils.waitUntil(() => u.hasClass('correcting', view.el.querySelector('.chat-msg')), 500);
await u.waitUntil(() => u.hasClass('correcting', view.el.querySelector('.chat-msg')), 500);
expect(textarea.value).toBe('But soft, what light through yonder window breaks?');
view.onKeyDown({
target: textarea,
@ -232,7 +232,7 @@
expect(textarea.value).toBe('');
expect(view.model.messages.at(0).get('correcting')).toBe(false);
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
await test_utils.waitUntil(() => (u.hasClass('correcting', view.el.querySelector('.chat-msg')) === false), 500);
await u.waitUntil(() => (u.hasClass('correcting', view.el.querySelector('.chat-msg')) === false), 500);
textarea.value = 'It is the east, and Juliet is the one.';
view.onKeyDown({
@ -260,7 +260,7 @@
expect(view.model.messages.at(0).get('correcting')).toBeFalsy();
expect(view.model.messages.at(1).get('correcting')).toBeFalsy();
expect(view.model.messages.at(2).get('correcting')).toBe(true);
await test_utils.waitUntil(() => u.hasClass('correcting', sizzle('.chat-msg:last', view.el).pop()), 500);
await u.waitUntil(() => u.hasClass('correcting', sizzle('.chat-msg:last', view.el).pop()), 500);
textarea.selectionEnd = 0; // Happens by pressing up,
// but for some reason not in tests, so we set it manually.
@ -272,7 +272,7 @@
expect(view.model.messages.at(0).get('correcting')).toBeFalsy();
expect(view.model.messages.at(1).get('correcting')).toBe(true);
expect(view.model.messages.at(2).get('correcting')).toBeFalsy();
await test_utils.waitUntil(() => u.hasClass('correcting', sizzle('.chat-msg', view.el)[1]), 500);
await u.waitUntil(() => u.hasClass('correcting', sizzle('.chat-msg', view.el)[1]), 500);
textarea.value = 'It is the east, and Juliet is the sun.';
view.onKeyDown({
@ -309,7 +309,7 @@
let message, msg;
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length)
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length)
spyOn(_converse, 'log');
spyOn(_converse.chatboxes, 'getChatBox').and.callThrough();
_converse.filter_by_resource = true;
@ -337,7 +337,7 @@
.c('body').t("message")
.tree();
await _converse.chatboxes.onMessage(msg);
await test_utils.waitUntil(() => _converse.api.chats.get().length);
await u.waitUntil(() => _converse.api.chats.get().length);
const view = _converse.api.chatviews.get(sender_jid);
msg = $msg({'id': 'aeb214', 'to': _converse.bare_jid})
@ -550,7 +550,7 @@
}).c('body').t(msgtext).tree();
await _converse.chatboxes.onMessage(msg);
await test_utils.waitUntil(() => (_converse.api.chats.get().length > 1))
await u.waitUntil(() => (_converse.api.chats.get().length > 1))
const chatbox = _converse.chatboxes.get(sender_jid);
const view = _converse.chatboxviews.get(sender_jid);
@ -561,15 +561,14 @@
const msg_obj = chatbox.messages.models[0];
expect(msg_obj.get('message')).toEqual(msgtext);
expect(msg_obj.get('fullname')).toBeUndefined();
expect(msg_obj.get('nickname')).toBeUndefined();
expect(msg_obj.get('nickname')).toBe(null);
expect(msg_obj.get('sender')).toEqual('them');
expect(msg_obj.get('is_delayed')).toEqual(false);
// Now check that the message appears inside the chatbox in the DOM
const chat_content = view.el.querySelector('.chat-content');
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
expect(chat_content.querySelector('.chat-msg .chat-msg__text').textContent).toEqual(msgtext);
expect(chat_content.querySelector('.chat-msg__time').textContent.match(/^[0-9][0-9]:[0-9][0-9]/)).toBeTruthy();
await test_utils.waitUntil(() => chatbox.vcard.get('fullname') === 'Juliet Capulet')
await u.waitUntil(() => chatbox.vcard.get('fullname') === 'Juliet Capulet')
expect(chat_content.querySelector('span.chat-msg__author').textContent.trim()).toBe('Juliet Capulet');
done();
}));
@ -602,7 +601,6 @@
'type': 'chat'
}).c('body').t(msgtext).tree();
await _converse.chatboxes.onMessage(msg);
await test_utils.waitUntil(() => _converse.api.chats.get().length);
// Check that the chatbox and its view now exist
const chatbox = _converse.chatboxes.get(recipient_jid);
const view = _converse.chatboxviews.get(recipient_jid);
@ -683,7 +681,7 @@
test_utils.openControlBox();
spyOn(_converse.api, "trigger").and.callThrough();
await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
await test_utils.openChatBoxFor(_converse, contact_jid);
const chatview = _converse.api.chatviews.get(contact_jid);
expect(u.isVisible(chatview.el)).toBeTruthy();
@ -701,7 +699,7 @@
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
await _converse.chatboxes.onMessage(msg);
await test_utils.waitUntil(() => chatview.model.messages.length);
await u.waitUntil(() => chatview.model.messages.length);
expect(_converse.api.trigger).toHaveBeenCalledWith('message', jasmine.any(Object));
const trimmed_chatboxes = _converse.minimized_chats;
const trimmedview = trimmed_chatboxes.get(contact_jid);
@ -720,7 +718,7 @@
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree()
);
await test_utils.waitUntil(() => (chatview.model.messages.length > 1));
await u.waitUntil(() => (chatview.model.messages.length > 1));
expect(u.isVisible(chatview.el)).toBeFalsy();
expect(trimmedview.model.get('minimized')).toBeTruthy();
count = trimmedview.el.querySelector('.message-count');
@ -743,7 +741,7 @@
const contact_name = mock.cur_names[1];
const contact_jid = contact_name.replace(/ /g,'.').toLowerCase() + '@montague.lit';
await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length);
await test_utils.openChatBoxFor(_converse, contact_jid);
test_utils.clearChatBoxMessages(_converse, contact_jid);
const one_day_ago = dayjs().subtract(1, 'day');
@ -770,7 +768,7 @@
expect(msg_obj.get('nickname')).toBe(null);
expect(msg_obj.get('sender')).toEqual('them');
expect(msg_obj.get('is_delayed')).toEqual(true);
await test_utils.waitUntil(() => chatbox.vcard.get('fullname') === 'Juliet Capulet')
await u.waitUntil(() => chatbox.vcard.get('fullname') === 'Juliet Capulet')
const chat_content = view.el.querySelector('.chat-content');
expect(chat_content.querySelector('.chat-msg .chat-msg__text').textContent).toEqual(message);
expect(chat_content.querySelector('.chat-msg__time').textContent.match(/^[0-9][0-9]:[0-9][0-9]/)).toBeTruthy();
@ -1002,7 +1000,7 @@
const view = _converse.chatboxviews.get(contact_jid);
spyOn(view.model, 'sendMessage').and.callThrough();
test_utils.sendMessage(view, message);
await test_utils.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-image').length, 1000)
await u.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-image').length, 1000)
expect(view.model.sendMessage).toHaveBeenCalled();
let msg = sizzle('.chat-content .chat-msg:last .chat-msg__text').pop();
expect(msg.innerHTML.trim()).toEqual(
@ -1011,7 +1009,7 @@
' src="' + message + '"></a>');
message += "?param1=val1&param2=val2";
test_utils.sendMessage(view, message);
await test_utils.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-image').length === 2, 1000);
await u.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-image').length === 2, 1000);
expect(view.model.sendMessage).toHaveBeenCalled();
msg = sizzle('.chat-content .chat-msg:last .chat-msg__text').pop();
expect(msg.innerHTML.trim()).toEqual(
@ -1022,7 +1020,7 @@
// Test now with two images in one message
message += ' hello world '+base_url+"/logo/conversejs-filled.svg";
test_utils.sendMessage(view, message);
await test_utils.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-image').length === 4, 1000);
await u.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-image').length === 4, 1000);
expect(view.model.sendMessage).toHaveBeenCalled();
msg = sizzle('.chat-content .chat-msg:last .chat-msg__text').pop();
expect(msg.textContent.trim()).toEqual('hello world');
@ -1075,7 +1073,7 @@
const base_time = new Date();
const ONE_MINUTE_LATER = 60000;
await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 300);
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 300);
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
_converse.filter_by_resource = true;
@ -1283,7 +1281,7 @@
}).c('body').t('Message!').up()
.c('request', {'xmlns': Strophe.NS.RECEIPTS}).tree();
await _converse.chatboxes.onMessage(msg);
await test_utils.waitUntil(() => _converse.api.chats.get().length);
await u.waitUntil(() => _converse.api.chats.get().length);
expect(view.model.sendReceiptStanza).not.toHaveBeenCalled();
done();
}));
@ -1313,7 +1311,7 @@
}).c('body').t('Message!').up()
.c('request', {'xmlns': Strophe.NS.RECEIPTS}).tree();
await _converse.chatboxes.onMessage(msg);
await test_utils.waitUntil(() => _converse.api.chats.get().length);
await u.waitUntil(() => _converse.api.chats.get().length);
expect(view.model.sendReceiptStanza).not.toHaveBeenCalled();
done();
}));
@ -1336,7 +1334,7 @@
preventDefault: _.noop,
keyCode: 13 // Enter
});
await test_utils.waitUntil(() => _converse.api.chats.get().length);
await u.waitUntil(() => _converse.api.chats.get().length);
const chatbox = _converse.chatboxes.get(contact_jid);
expect(chatbox).toBeDefined();
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
@ -1429,7 +1427,7 @@
const include_nick = false;
await test_utils.waitForRoster(_converse, 'current', 1, include_nick);
test_utils.openControlBox();
await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 300);
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 300);
spyOn(_converse.api, "trigger").and.callThrough();
const message = 'This is a received message';
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
@ -1444,7 +1442,7 @@
}).c('body').t(message).up()
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree()
);
await test_utils.waitUntil(() => (_converse.api.chats.get().length === 2));
await u.waitUntil(() => (_converse.api.chats.get().length === 2));
const chatbox = _converse.chatboxes.get(sender_jid);
expect(chatbox).toBeDefined();
const view = _converse.api.chatviews.get(sender_jid);
@ -1462,7 +1460,7 @@
const chat_content = view.el.querySelector('.chat-content');
expect(chat_content.querySelector('.chat-msg .chat-msg__text').textContent).toEqual(message);
expect(chat_content.querySelector('.chat-msg__time').textContent.match(/^[0-9][0-9]:[0-9][0-9]/)).toBeTruthy();
await test_utils.waitUntil(() => chatbox.vcard.get('fullname') === mock.cur_names[0]);
await u.waitUntil(() => chatbox.vcard.get('fullname') === mock.cur_names[0]);
expect(chat_content.querySelector('span.chat-msg__author').textContent.trim()).toBe('Mercutio');
done();
}));
@ -1473,7 +1471,7 @@
async function (done, _converse) {
await test_utils.waitForRoster(_converse, 'current', 1, false);
await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 300);
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length, 300);
const message = '\n\n This is a received message \n\n';
const sender_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
_converse.chatboxes.onMessage(
@ -1485,7 +1483,7 @@
}).c('body').t(message).up()
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree()
);
await test_utils.waitUntil(() => (_converse.api.chats.get().length === 2));
await u.waitUntil(() => (_converse.api.chats.get().length === 2));
const view = _converse.api.chatviews.get(sender_jid);
expect(view.model.messages.length).toEqual(1);
const msg_obj = view.model.messages.at(0);
@ -1549,7 +1547,7 @@
expect(view.el.querySelectorAll('.chat-msg__content .fa-edit').length).toBe(1);
view.el.querySelector('.chat-msg__content .fa-edit').click();
const modal = view.model.messages.at(0).message_versions_modal;
await test_utils.waitUntil(() => u.isVisible(modal.el), 1000);
await u.waitUntil(() => u.isVisible(modal.el), 1000);
const older_msgs = modal.el.querySelectorAll('.older-msg');
expect(older_msgs.length).toBe(2);
expect(older_msgs[0].childNodes[0].nodeName).toBe('TIME');
@ -1594,7 +1592,7 @@
expect(_converse.chatboxes.get(sender_jid)).not.toBeDefined();
await _converse.chatboxes.onMessage(msg);
await test_utils.waitUntil(() => _converse.api.chats.get().length);
await u.waitUntil(() => _converse.api.chats.get().length);
expect(_converse.api.trigger).toHaveBeenCalledWith('message', jasmine.any(Object));
// Check that the chatbox and its view now exist
@ -1604,14 +1602,13 @@
expect(chatbox).toBeDefined();
expect(view).toBeDefined();
expect(chatbox.get('fullname') === sender_jid);
await new Promise(resolve => view.once('messageInserted', resolve));
await test_utils.waitUntil(() => view.el.querySelector('.chat-msg__author').textContent.trim() === 'Mercutio');
await u.waitUntil(() => view.el.querySelector('.chat-msg__author').textContent.trim() === 'Mercutio');
let author_el = view.el.querySelector('.chat-msg__author');
expect( _.includes(author_el.textContent.trim(), 'Mercutio')).toBeTruthy();
await test_utils.waitUntil(() => vcard_fetched, 100);
await u.waitUntil(() => vcard_fetched, 100);
expect(_converse.api.vcard.get).toHaveBeenCalled();
await test_utils.waitUntil(() => chatbox.vcard.get('fullname') === mock.cur_names[0])
await u.waitUntil(() => chatbox.vcard.get('fullname') === mock.cur_names[0])
author_el = view.el.querySelector('.chat-msg__author');
expect( _.includes(author_el.textContent.trim(), 'Mercutio')).toBeTruthy();
done();
@ -1669,7 +1666,7 @@
expect(msg_obj.get('sender')).toEqual('them');
expect(msg_obj.get('is_delayed')).toEqual(false);
await test_utils.waitUntil(() => view.el.querySelector('.chat-msg__author').textContent.trim() === 'Mercutio');
await u.waitUntil(() => view.el.querySelector('.chat-msg__author').textContent.trim() === 'Mercutio');
// Now check that the message appears inside the chatbox in the DOM
const chat_content = view.el.querySelector('.chat-content');
expect(chat_content.querySelector('.chat-msg .chat-msg__text').textContent).toEqual(message);
@ -1888,11 +1885,11 @@
}
await Promise.all(promises);
// XXX Fails on Travis
// await test_utils.waitUntil(() => view.content.scrollTop, 1000)
await test_utils.waitUntil(() => !view.model.get('auto_scrolled'), 500);
// await u.waitUntil(() => view.content.scrollTop, 1000)
await u.waitUntil(() => !view.model.get('auto_scrolled'), 500);
view.content.scrollTop = 0;
// XXX Fails on Travis
// await test_utils.waitUntil(() => view.model.get('scrolled'), 900);
// await u.waitUntil(() => view.model.get('scrolled'), 900);
view.model.set('scrolled', true);
const message = 'This message is received while the chat area is scrolled up';
@ -1904,19 +1901,19 @@
}).c('body').t(message).up()
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree());
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
await test_utils.waitUntil(() => view.model.messages.length > 20, 1000);
await u.waitUntil(() => view.model.messages.length > 20, 1000);
// Now check that the message appears inside the chatbox in the DOM
const chat_content = view.el.querySelector('.chat-content');
const msg_txt = sizzle('.chat-content .chat-msg:last .chat-msg__text', view.el).pop().textContent;
expect(msg_txt).toEqual(message);
await test_utils.waitUntil(() => u.isVisible(view.el.querySelector('.new-msgs-indicator')), 900);
await u.waitUntil(() => u.isVisible(view.el.querySelector('.new-msgs-indicator')), 900);
expect(view.model.get('scrolled')).toBe(true);
expect(view.content.scrollTop).toBe(0);
expect(u.isVisible(view.el.querySelector('.new-msgs-indicator'))).toBeTruthy();
// Scroll down again
view.content.scrollTop = view.content.scrollHeight;
// XXX Fails on Travis
// await test_utils.waitUntil(() => !u.isVisible(view.el.querySelector('.new-msgs-indicator')), 900);
// await u.waitUntil(() => !u.isVisible(view.el.querySelector('.new-msgs-indicator')), 900);
done();
}));
@ -1926,7 +1923,7 @@
async function (done, _converse) {
await test_utils.waitForRoster(_converse, 'current');
await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length)
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length)
// Send a message from a different resource
spyOn(_converse, 'log');
spyOn(_converse.chatboxes, 'getChatBox').and.callThrough();
@ -1940,7 +1937,7 @@
}).c('body').t("This message will not be shown").up()
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
await _converse.chatboxes.onMessage(msg);
await test_utils.waitUntil(() => _converse.api.chats.get().length);
await u.waitUntil(() => _converse.api.chats.get().length);
expect(_converse.log).toHaveBeenCalledWith(
"onMessage: Ignoring incoming message intended for a different resource: romeo@montague.lit/some-other-resource",
Strophe.LogLevel.INFO);
@ -1956,9 +1953,9 @@
}).c('body').t(message).up()
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
await _converse.chatboxes.onMessage(msg);
await test_utils.waitUntil(() => _converse.chatboxviews.keys().length > 1, 1000);
await u.waitUntil(() => _converse.chatboxviews.keys().length > 1, 1000);
const view = _converse.chatboxviews.get(sender_jid);
await test_utils.waitUntil(() => view.model.messages.length);
await u.waitUntil(() => view.model.messages.length);
expect(_converse.chatboxes.getChatBox).toHaveBeenCalled();
const chat_content = sizzle('.chat-content:last', view.el).pop();
const msg_txt = chat_content.querySelector('.chat-msg .chat-msg__text').textContent;
@ -1990,7 +1987,7 @@
</message>`)
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
await test_utils.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-msg audio').length, 1000);
await u.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-msg audio').length, 1000);
let msg = view.el.querySelector('.chat-msg .chat-msg__text');
expect(msg.classList.length).toEqual(1);
expect(u.hasClass('chat-msg__text', msg)).toBe(true);
@ -2041,7 +2038,7 @@
<x xmlns="jabber:x:oob"><url>https://montague.lit/video.mp4</url></x>
</message>`);
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-msg video').length, 2000)
await u.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-msg video').length, 2000)
let msg = view.el.querySelector('.chat-msg .chat-msg__text');
expect(msg.classList.length).toBe(1);
expect(msg.textContent).toEqual('Have you seen this funny video?');
@ -2090,7 +2087,7 @@
</message>`);
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
await test_utils.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-msg a').length, 1000);
await u.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-msg a').length, 1000);
const msg = view.el.querySelector('.chat-msg .chat-msg__text');
expect(u.hasClass('chat-msg__text', msg)).toBe(true);
expect(msg.textContent).toEqual('Have you downloaded this funny file?');
@ -2122,7 +2119,7 @@
<x xmlns="jabber:x:oob"><url>${url}</url></x>
</message>`);
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-msg img').length, 2000);
await u.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-msg img').length, 2000);
const msg = view.el.querySelector('.chat-msg .chat-msg__text');
expect(u.hasClass('chat-msg__text', msg)).toBe(true);
@ -2163,7 +2160,7 @@
spyOn(_converse.connection, 'send').and.callFake(s => sent_stanzas.push(s));
spyOn(view.model, 'sendMarker').and.callThrough();
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => view.model.sendMarker.calls.count() === 1);
await u.waitUntil(() => view.model.sendMarker.calls.count() === 1);
expect(Strophe.serialize(sent_stanzas[0])).toBe(
`<message from="romeo@montague.lit/orchard" `+
`id="${sent_stanzas[0].nodeTree.getAttribute('id')}" `+
@ -2193,7 +2190,7 @@
const sent_stanzas = [];
spyOn(_converse.connection, 'send').and.callFake(s => sent_stanzas.push(s));
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => _converse.api.chats.get().length == 2);
await u.waitUntil(() => _converse.api.chats.get().length == 2);
const sent_messages = sent_stanzas
.map(s => _.isElement(s) ? s : s.nodeTree)
.filter(e => e.nodeName === 'message');
@ -2251,7 +2248,7 @@
</message>`);
spyOn(_converse.api, "trigger").and.callThrough();
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => _converse.api.trigger.calls.count(), 500);
await u.waitUntil(() => _converse.api.trigger.calls.count(), 500);
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
expect(view.model.messages.length).toBe(1);
done();
@ -2336,9 +2333,9 @@
by="room@muc.example.com"/>
</message>`);
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => _converse.api.chats.get().length);
await test_utils.waitUntil(() => view.model.messages.length === 1);
await test_utils.waitUntil(() => view.model.findDuplicateFromStanzaID.calls.count() === 1);
await u.waitUntil(() => _converse.api.chats.get().length);
await u.waitUntil(() => view.model.messages.length === 1);
await u.waitUntil(() => view.model.findDuplicateFromStanzaID.calls.count() === 1);
let result = await view.model.findDuplicateFromStanzaID.calls.all()[0].returnValue;
expect(result).toBe(undefined);
@ -2354,11 +2351,11 @@
</message>`);
spyOn(view.model, 'updateMessage');
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => view.model.findDuplicateFromStanzaID.calls.count() === 2);
await u.waitUntil(() => view.model.findDuplicateFromStanzaID.calls.count() === 2);
result = await view.model.findDuplicateFromStanzaID.calls.all()[1].returnValue;
expect(result instanceof _converse.Message).toBe(true);
expect(view.model.messages.length).toBe(1);
await test_utils.waitUntil(() => view.model.updateMessage.calls.count());
await u.waitUntil(() => view.model.updateMessage.calls.count());
done();
}));
@ -2424,7 +2421,7 @@
.c('status').attrs({code:'210'}).nodeTree;
_converse.connection._dataRecv(test_utils.createRequest(presence));
view.model.sendMessage('hello world');
await test_utils.waitUntil(() => view.el.querySelectorAll('.chat-msg').length === 3);
await u.waitUntil(() => view.el.querySelectorAll('.chat-msg').length === 3);
expect(view.model.messages.last().occupant.get('affiliation')).toBe('owner');
expect(view.model.messages.last().occupant.get('role')).toBe('moderator');
@ -2492,7 +2489,7 @@
'id': u.getUniqueId(),
}).c('body').t('But soft, what light through yonder chimney breaks?').up()
.c('replace', {'id': msg_id, 'xmlns': 'urn:xmpp:message-correct:0'}).tree());
await test_utils.waitUntil(() => view.el.querySelector('.chat-msg__text').textContent ===
await u.waitUntil(() => view.el.querySelector('.chat-msg__text').textContent ===
'But soft, what light through yonder chimney breaks?', 500);
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
expect(view.el.querySelectorAll('.chat-msg__content .fa-edit').length).toBe(1);
@ -2505,13 +2502,13 @@
}).c('body').t('But soft, what light through yonder window breaks?').up()
.c('replace', {'id': msg_id, 'xmlns': 'urn:xmpp:message-correct:0'}).tree());
await test_utils.waitUntil(() => view.el.querySelector('.chat-msg__text').textContent ===
await u.waitUntil(() => view.el.querySelector('.chat-msg__text').textContent ===
'But soft, what light through yonder window breaks?', 500);
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
expect(view.el.querySelectorAll('.chat-msg__content .fa-edit').length).toBe(1);
view.el.querySelector('.chat-msg__content .fa-edit').click();
const modal = view.model.messages.at(0).message_versions_modal;
await test_utils.waitUntil(() => u.isVisible(modal.el), 1000);
await u.waitUntil(() => u.isVisible(modal.el), 1000);
const older_msgs = modal.el.querySelectorAll('.older-msg');
expect(older_msgs.length).toBe(2);
expect(older_msgs[0].childNodes[1].textContent).toBe(': But soft, what light through yonder airlock breaks?');
@ -2613,7 +2610,7 @@
expect(textarea.value).toBe('But soft, what light through yonder window breaks?');
expect(view.model.messages.at(0).get('correcting')).toBe(true);
expect(view.el.querySelectorAll('.chat-msg').length).toBe(2);
await test_utils.waitUntil(() => u.hasClass('correcting', view.el.querySelector('.chat-msg')), 500);
await u.waitUntil(() => u.hasClass('correcting', view.el.querySelector('.chat-msg')), 500);
expect(textarea.value).toBe('But soft, what light through yonder window breaks?');
view.onKeyDown({
target: textarea,
@ -2622,7 +2619,7 @@
expect(textarea.value).toBe('');
expect(view.model.messages.at(0).get('correcting')).toBe(false);
expect(view.el.querySelectorAll('.chat-msg').length).toBe(2);
await test_utils.waitUntil(() => !u.hasClass('correcting', view.el.querySelector('.chat-msg')), 500);
await u.waitUntil(() => !u.hasClass('correcting', view.el.querySelector('.chat-msg')), 500);
done();
}));
@ -2658,7 +2655,7 @@
<origin-id xmlns="urn:xmpp:sid:0" id="${msg_obj.get('origin_id')}"/>
</message>`);
await view.model.onMessage(stanza);
await test_utils.waitUntil(() => view.el.querySelectorAll('.chat-msg__body.chat-msg__body--received').length, 500);
await u.waitUntil(() => view.el.querySelectorAll('.chat-msg__body.chat-msg__body--received').length, 500);
expect(view.el.querySelectorAll('.chat-msg__receipt').length).toBe(0);
expect(view.el.querySelectorAll('.chat-msg__body.chat-msg__body--received').length).toBe(1);
expect(view.model.messages.length).toBe(1);
@ -2679,8 +2676,8 @@
const view = _converse.api.chatviews.get(muc_jid);
view.model.sendMessage('hello world');
await test_utils.waitUntil(() => _converse.api.chats.get().length);
await test_utils.waitUntil(() => view.model.messages.length === 1);
await u.waitUntil(() => _converse.api.chats.get().length);
await u.waitUntil(() => view.model.messages.length === 1);
const msg = view.model.messages.at(0);
expect(msg.get('stanza_id')).toBeUndefined();
expect(msg.get('origin_id')).toBe(msg.get('origin_id'));
@ -2698,7 +2695,7 @@
</message>`);
spyOn(view.model, 'updateMessage').and.callThrough();
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => view.model.updateMessage.calls.count() === 1);
await u.waitUntil(() => view.model.updateMessage.calls.count() === 1);
expect(view.model.messages.length).toBe(1);
expect(view.model.messages.at(0).get('stanza_id room@muc.example.com')).toBe("5f3dbc5e-e1d3-4077-a492-693f3769c7ad");
expect(view.model.messages.at(0).get('origin_id')).toBe(msg.get('origin_id'));
@ -2734,7 +2731,7 @@
spyOn(_converse.api, "trigger").and.callThrough();
spyOn(view.model, "isReceipt").and.callThrough();
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => view.model.isReceipt.calls.count() === 1);
await u.waitUntil(() => view.model.isReceipt.calls.count() === 1);
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
expect(view.el.querySelectorAll('.chat-msg__receipt').length).toBe(0);
expect(_converse.api.trigger).toHaveBeenCalledWith('message', jasmine.any(Object));
@ -2770,7 +2767,7 @@
</message>`);
spyOn(view.model, "isChatMarker").and.callThrough();
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => view.model.isChatMarker.calls.count() === 1);
await u.waitUntil(() => view.model.isChatMarker.calls.count() === 1);
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
expect(view.el.querySelectorAll('.chat-msg__receipt').length).toBe(0);
@ -2780,7 +2777,7 @@
<displayed xmlns="urn:xmpp:chat-markers:0" id="${msg_obj.get('msgid')}"/>
</message>`);
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => view.model.isChatMarker.calls.count() === 2);
await u.waitUntil(() => view.model.isChatMarker.calls.count() === 2);
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
expect(view.el.querySelectorAll('.chat-msg__receipt').length).toBe(0);
@ -2791,7 +2788,7 @@
</message>`);
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => view.model.isChatMarker.calls.count() === 3);
await u.waitUntil(() => view.model.isChatMarker.calls.count() === 3);
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
expect(view.el.querySelectorAll('.chat-msg__receipt').length).toBe(0);
@ -2802,7 +2799,7 @@
<markable xmlns="urn:xmpp:chat-markers:0"/>
</message>`);
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => view.model.isChatMarker.calls.count() === 4);
await u.waitUntil(() => view.model.isChatMarker.calls.count() === 4);
expect(view.el.querySelectorAll('.chat-msg').length).toBe(2);
expect(view.el.querySelectorAll('.chat-msg__receipt').length).toBe(0);
done();
@ -3027,11 +3024,11 @@
expect(textarea.value).toBe('hello @z3r0 @gibson @mr.robot, how are you?');
expect(view.model.messages.at(0).get('correcting')).toBe(true);
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
await test_utils.waitUntil(() => u.hasClass('correcting', view.el.querySelector('.chat-msg')), 500);
await u.waitUntil(() => u.hasClass('correcting', view.el.querySelector('.chat-msg')), 500);
textarea.value = 'hello @z3r0 @gibson @sw0rdf1sh, how are you?';
view.onKeyDown(enter_event);
await test_utils.waitUntil(() => view.el.querySelector('.chat-msg__text').textContent ===
await u.waitUntil(() => view.el.querySelector('.chat-msg__text').textContent ===
'hello z3r0 gibson sw0rdf1sh, how are you?', 500);
const correction = _converse.connection.send.calls.all()[2].args[0];

View File

@ -66,7 +66,7 @@
expect(u.isVisible(_converse.minimized_chats.el.querySelector('.minimized-chats-flyout'))).toBeTruthy();
expect(_converse.minimized_chats.toggleview.model.get('collapsed')).toBeFalsy();
_converse.minimized_chats.el.querySelector('#toggle-minimized-chats').click();
await test_utils.waitUntil(() => u.isVisible(_converse.minimized_chats.el.querySelector('.minimized-chats-flyout')));
await u.waitUntil(() => u.isVisible(_converse.minimized_chats.el.querySelector('.minimized-chats-flyout')));
expect(_converse.minimized_chats.toggleview.model.get('collapsed')).toBeTruthy();
done();
}));
@ -93,7 +93,7 @@
contact_jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@montague.lit';
test_utils.openChatBoxFor(_converse, contact_jid);
}
test_utils.waitUntil(() => _converse.chatboxes.length == 4).then(() => {
u.waitUntil(() => _converse.chatboxes.length == 4).then(() => {
for (i=0; i<3; i++) {
chatview = _converse.chatboxviews.get(contact_jid);
chatview.model.set({'minimized': true});
@ -106,7 +106,7 @@
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
_converse.chatboxes.onMessage(msg);
}
return test_utils.waitUntil(() => chatview.model.messages.length);
return u.waitUntil(() => chatview.model.messages.length);
}).then(() => {
expect(u.isVisible(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count'))).toBeTruthy();
expect(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count').textContent).toBe((3).toString());
@ -169,7 +169,7 @@
type: 'groupchat'
}).c('body').t(message).tree();
view.model.onMessage(msg);
await test_utils.waitUntil(() => view.model.messages.length);
await u.waitUntil(() => view.model.messages.length);
expect(u.isVisible(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count'))).toBeTruthy();
expect(_converse.minimized_chats.toggleview.el.querySelector('.unread-message-count').textContent).toBe('1');
done();

View File

@ -53,7 +53,7 @@
async function (done, _converse) {
test_utils.createContacts(_converse, 'current');
await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group .group-toggle').length, 300);
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group .group-toggle').length, 300);
let muc_jid = 'chillout@montague.lit';
await test_utils.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
let room = _converse.api.rooms.get(muc_jid);
@ -107,13 +107,13 @@
let chatroomview, IQ_id;
test_utils.openControlBox();
test_utils.createContacts(_converse, 'current');
await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group .group-toggle').length);
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group .group-toggle').length);
let room = await _converse.api.rooms.open(jid);
// Test on groupchat that's not yet open
expect(room instanceof Backbone.Model).toBeTruthy();
chatroomview = _converse.chatboxviews.get(jid);
expect(chatroomview.is_chatroom).toBeTruthy();
await test_utils.waitUntil(() => u.isVisible(chatroomview.el));
await u.waitUntil(() => u.isVisible(chatroomview.el));
// Test again, now that the room exists.
room = await _converse.api.rooms.open(jid);
@ -128,19 +128,19 @@
room = await _converse.api.rooms.open(jid);
expect(room instanceof Backbone.Model).toBeTruthy();
chatroomview = _converse.chatboxviews.get(jid.toLowerCase());
await test_utils.waitUntil(() => u.isVisible(chatroomview.el));
await u.waitUntil(() => u.isVisible(chatroomview.el));
jid = 'leisure@montague.lit';
room = await _converse.api.rooms.open(jid);
expect(room instanceof Backbone.Model).toBeTruthy();
chatroomview = _converse.chatboxviews.get(jid.toLowerCase());
await test_utils.waitUntil(() => u.isVisible(chatroomview.el));
await u.waitUntil(() => u.isVisible(chatroomview.el));
jid = 'leiSure@montague.lit';
room = await _converse.api.rooms.open(jid);
expect(room instanceof Backbone.Model).toBeTruthy();
chatroomview = _converse.chatboxviews.get(jid.toLowerCase());
await test_utils.waitUntil(() => u.isVisible(chatroomview.el));
await u.waitUntil(() => u.isVisible(chatroomview.el));
chatroomview.close();
_converse.muc_instant_rooms = false;
@ -244,7 +244,7 @@
spyOn(chatroomview.model, 'sendConfiguration').and.callThrough();
_converse.connection._dataRecv(test_utils.createRequest(node));
await test_utils.waitUntil(() => chatroomview.model.sendConfiguration.calls.count() === 1);
await u.waitUntil(() => chatroomview.model.sendConfiguration.calls.count() === 1);
const sent_stanza = IQ_stanzas.filter(s => s.getAttribute('type') === 'set').pop();
expect(sizzle('field[var="muc#roomconfig_roomname"] value', sent_stanza).pop().textContent).toBe('Room');
@ -280,7 +280,7 @@
}
});
await test_utils.openChatRoom(_converse, 'lounge', 'montague.lit', 'romeo');
let stanza = await test_utils.waitUntil(() => _.filter(
let stanza = await u.waitUntil(() => _.filter(
IQ_stanzas,
iq => iq.querySelector(
`iq[to="${muc_jid}"] query[xmlns="http://jabber.org/protocol/disco#info"]`
@ -315,7 +315,7 @@
* node="x-roomuser-item"/>
* </iq>
*/
stanza = await test_utils.waitUntil(() => _.filter(
stanza = await u.waitUntil(() => _.filter(
IQ_stanzas,
s => sizzle(`iq[to="${muc_jid}"] query[node="x-roomuser-item"]`, s).length
).pop()
@ -340,12 +340,12 @@
.c('item-not-found', {'xmlns': "urn:ietf:params:xml:ns:xmpp-stanzas"});
_converse.connection._dataRecv(test_utils.createRequest(result_stanza));
const input = await test_utils.waitUntil(() => view.el.querySelector('input[name="nick"]'));
const input = await u.waitUntil(() => view.el.querySelector('input[name="nick"]'));
expect(view.model.get('connection_status')).toBe(converse.ROOMSTATUS.NICKNAME_REQUIRED);
input.value = 'nicky';
view.el.querySelector('input[type=submit]').click();
expect(view.model.join).toHaveBeenCalled();
await test_utils.waitUntil(() => view.model.get('connection_status') === converse.ROOMSTATUS.CONNECTING);
await u.waitUntil(() => view.model.get('connection_status') === converse.ROOMSTATUS.CONNECTING);
// The user has just entered the room (because join was called)
// and receives their own presence from the server.
@ -374,9 +374,9 @@
.c('status').attrs({code:'201'}).nodeTree;
_converse.connection._dataRecv(test_utils.createRequest(presence));
await test_utils.waitUntil(() => view.model.get('connection_status') === converse.ROOMSTATUS.ENTERED);
await u.waitUntil(() => view.model.get('connection_status') === converse.ROOMSTATUS.ENTERED);
await test_utils.returnMemberLists(_converse, muc_jid);
// await test_utils.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-info').length === 2);
// await u.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-info').length === 2);
const info_texts = Array.from(view.el.querySelectorAll('.chat-content .chat-info')).map(e => e.textContent);
expect(info_texts[0]).toBe('A new groupchat has been created');
@ -421,7 +421,7 @@
spyOn(view.model, 'clearMessages').and.callThrough();
view.model.close();
await test_utils.waitUntil(() => view.model.clearMessages.calls.count());
await u.waitUntil(() => view.model.clearMessages.calls.count());
expect(view.model.messages.length).toBe(0);
expect(view.content.innerHTML).toBe('');
done()
@ -451,7 +451,7 @@
await view.model.onMessage(msg);
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
view.el.querySelector('.chat-msg__text a').click();
await test_utils.waitUntil(() => _converse.chatboxes.length === 3)
await u.waitUntil(() => _converse.chatboxes.length === 3)
expect(_.includes(_converse.chatboxes.pluck('id'), 'coven@chat.shakespeare.lit')).toBe(true);
done()
}));
@ -486,7 +486,7 @@
.c('status', {code: '100'});
_converse.connection._dataRecv(test_utils.createRequest(presence));
await test_utils.waitUntil(() => chat_content.querySelectorAll('.chat-info').length === 2);
await u.waitUntil(() => chat_content.querySelectorAll('.chat-info').length === 2);
expect(sizzle('div.chat-info:first', chat_content).pop().textContent)
.toBe("This groupchat is not anonymous");
expect(sizzle('div.chat-info:last', chat_content).pop().textContent)
@ -1227,7 +1227,7 @@
async function (done, _converse) {
await test_utils.waitUntilDiscoConfirmed(_converse, 'montague.lit', [], ['vcard-temp']);
await test_utils.waitUntil(() => _converse.xmppstatus.vcard.get('fullname'));
await u.waitUntil(() => _converse.xmppstatus.vcard.get('fullname'));
test_utils.createContacts(_converse, 'current');
await test_utils.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo');
const view = _converse.chatboxviews.get('lounge@montague.lit');
@ -1275,7 +1275,7 @@
await _converse.api.rooms.open('coven@chat.shakespeare.lit', {'nick': 'some1'});
const view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
await test_utils.waitUntil(() => u.isVisible(view.el));
await u.waitUntil(() => u.isVisible(view.el));
spyOn(view.model, 'saveAffiliationAndRole').and.callThrough();
// We pretend this is a new room, so no disco info is returned.
const features_stanza = $iq({
@ -1308,7 +1308,7 @@
_converse.connection._dataRecv(test_utils.createRequest(presence));
expect(view.model.saveAffiliationAndRole).toHaveBeenCalled();
expect(u.isVisible(view.el.querySelector('.toggle-chatbox-button'))).toBeTruthy();
await test_utils.waitUntil(() => !_.isNull(view.el.querySelector('.configure-chatroom-button')))
await u.waitUntil(() => !_.isNull(view.el.querySelector('.configure-chatroom-button')))
expect(u.isVisible(view.el.querySelector('.configure-chatroom-button'))).toBeTruthy();
view.el.querySelector('.configure-chatroom-button').click();
@ -1446,7 +1446,7 @@
.c('value').t('cauldronburn');
_converse.connection._dataRecv(test_utils.createRequest(config_stanza));
await test_utils.waitUntil(() => view.el.querySelectorAll('form.chatroom-form').length)
await u.waitUntil(() => view.el.querySelectorAll('form.chatroom-form').length)
expect(view.el.querySelectorAll('form.chatroom-form').length).toBe(1);
expect(view.el.querySelectorAll('form.chatroom-form fieldset').length).toBe(2);
const membersonly = view.el.querySelectorAll('input[name="muc#roomconfig_membersonly"]');
@ -1489,7 +1489,7 @@
const muc_jid = 'lounge@montague.lit'
await test_utils.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo', [], ['juliet']);
const view = _converse.chatboxviews.get(muc_jid);
await test_utils.waitUntil(() => view.model.occupants.length === 2);
await u.waitUntil(() => view.model.occupants.length === 2);
const occupants = view.el.querySelector('.occupant-list');
for (let i=0; i<mock.chatroom_names.length; i++) {
@ -1508,7 +1508,7 @@
_converse.connection._dataRecv(test_utils.createRequest(presence));
}
await test_utils.waitUntil(() => occupants.querySelectorAll('li').length > 2, 500);
await u.waitUntil(() => occupants.querySelectorAll('li').length > 2, 500);
expect(occupants.querySelectorAll('li').length).toBe(2+mock.chatroom_names.length);
expect(view.model.occupants.length).toBe(2+mock.chatroom_names.length);
@ -1546,7 +1546,7 @@
role: 'visitor'
});
_converse.connection._dataRecv(test_utils.createRequest(presence));
await test_utils.waitUntil(() => occupants.querySelectorAll('li').length > 8, 500);
await u.waitUntil(() => occupants.querySelectorAll('li').length > 8, 500);
expect(occupants.querySelectorAll('li').length).toBe(9);
expect(view.model.occupants.length).toBe(9);
expect(view.model.occupants.filter(o => o.isMember()).length).toBe(8);
@ -1589,7 +1589,7 @@
_converse.connection._dataRecv(test_utils.createRequest(presence));
}
await test_utils.waitUntil(() => occupants.querySelectorAll('li').length > 1, 500);
await u.waitUntil(() => occupants.querySelectorAll('li').length > 1, 500);
expect(occupants.querySelectorAll('li').length).toBe(1+mock.chatroom_names.length);
mock.chatroom_names.forEach(name => {
@ -1644,7 +1644,7 @@
_converse.connection._dataRecv(test_utils.createRequest(presence));
const view = _converse.chatboxviews.get('lounge@montague.lit');
await test_utils.waitUntil(() => view.el.querySelectorAll('li .occupant-nick').length, 500);
await u.waitUntil(() => view.el.querySelectorAll('li .occupant-nick').length, 500);
const occupants = view.el.querySelector('.occupant-list').querySelectorAll('li .occupant-nick');
expect(occupants.length).toBe(2);
expect(occupants[0].textContent.trim()).toBe("&lt;img src=&quot;x&quot; onerror=&quot;alert(123)&quot;/&gt;");
@ -1660,7 +1660,7 @@
const view = _converse.chatboxviews.get('lounge@montague.lit');
let contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@montague.lit';
await test_utils.waitUntil(() => view.el.querySelectorAll('.occupant-list li').length, 500);
await u.waitUntil(() => view.el.querySelectorAll('.occupant-list li').length, 500);
let occupants = view.el.querySelectorAll('.occupant-list li');
expect(occupants.length).toBe(1);
expect(occupants[0].querySelector('.occupant-nick').textContent.trim()).toBe("romeo");
@ -1680,7 +1680,7 @@
.c('status').attrs({code:'110'}).nodeTree;
_converse.connection._dataRecv(test_utils.createRequest(presence));
await test_utils.waitUntil(() => view.el.querySelectorAll('.occupant-list li').length > 1, 500);
await u.waitUntil(() => view.el.querySelectorAll('.occupant-list li').length > 1, 500);
occupants = view.el.querySelectorAll('.occupant-list li');
expect(occupants.length).toBe(2);
expect(occupants[0].querySelector('.occupant-nick').textContent.trim()).toBe("moderatorman");
@ -1705,7 +1705,7 @@
.c('status').attrs({code:'110'}).nodeTree;
_converse.connection._dataRecv(test_utils.createRequest(presence));
await test_utils.waitUntil(() => view.el.querySelectorAll('.occupant-list li').length > 2, 500);
await u.waitUntil(() => view.el.querySelectorAll('.occupant-list li').length > 2, 500);
occupants = view.el.querySelector('.occupant-list').querySelectorAll('li');
expect(occupants.length).toBe(3);
expect(occupants[2].querySelector('.occupant-nick').textContent.trim()).toBe("visitorwoman");
@ -1759,7 +1759,7 @@
await test_utils.openChatRoom(_converse, 'lounge', 'montague.lit', 'romeo');
let stanza = await test_utils.waitUntil(() => _.filter(
let stanza = await u.waitUntil(() => _.filter(
IQ_stanzas,
iq => iq.querySelector(
`iq[to="${muc_jid}"] query[xmlns="http://jabber.org/protocol/disco#info"]`
@ -1786,7 +1786,7 @@
* node='x-roomuser-item'/>
* </iq>
*/
const iq = await test_utils.waitUntil(() => _.filter(
const iq = await u.waitUntil(() => _.filter(
IQ_stanzas,
s => sizzle(`iq[to="${muc_jid}"] query[node="x-roomuser-item"]`, s).length
).pop()
@ -1838,7 +1838,7 @@
.c('status').attrs({code:'210'}).nodeTree;
_converse.connection._dataRecv(test_utils.createRequest(presence));
await test_utils.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-info').length === 2);
await u.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-info').length === 2);
const info_text = sizzle('.chat-content .chat-info:first', view.el).pop().textContent;
expect(info_text).toBe('Your nickname has been automatically set to thirdwitch');
done();
@ -1875,11 +1875,11 @@
expect(view.el.querySelectorAll('input.invited-contact').length).toBe(1);
view.model.getOwnOccupant().set('affiliation', 'member');
await test_utils.waitUntil(() => view.el.querySelectorAll('input.invited-contact').length === 0);
await u.waitUntil(() => view.el.querySelectorAll('input.invited-contact').length === 0);
view.model.features.set('open', 'true');
spyOn(view.model, 'directInvite').and.callThrough();
await test_utils.waitUntil(() => view.el.querySelectorAll('input.invited-contact').length);
await u.waitUntil(() => view.el.querySelectorAll('input.invited-contact').length);
const input = view.el.querySelector('input.invited-contact');
expect(input.getAttribute('placeholder')).toBe('Invite');
input.value = "Balt";
@ -1888,7 +1888,7 @@
let sent_stanza;
spyOn(_converse.connection, 'send').and.callFake(stanza => (sent_stanza = stanza));
const hint = await test_utils.waitUntil(() => view.el.querySelector('.suggestion-box__results li'));
const hint = await u.waitUntil(() => view.el.querySelector('.suggestion-box__results li'));
expect(input.value).toBe('Balt');
expect(hint.textContent).toBe('Balthasar');
@ -2143,7 +2143,7 @@
_converse.connection._dataRecv(test_utils.createRequest(stanza));
let sent_stanzas = _converse.connection.sent_stanzas;
const iq = await test_utils.waitUntil(() => sent_stanzas.filter(s => sizzle(`[xmlns="${Strophe.NS.PING}"]`, s).length).pop());
const iq = await u.waitUntil(() => sent_stanzas.filter(s => sizzle(`[xmlns="${Strophe.NS.PING}"]`, s).length).pop());
expect(Strophe.serialize(iq)).toBe(
`<iq id="${iq.getAttribute('id')}" to="coven@chat.shakespeare.lit/romeo" type="get" xmlns="jabber:client">`+
`<ping xmlns="urn:xmpp:ping"/>`+
@ -2164,7 +2164,7 @@
_converse.connection._dataRecv(test_utils.createRequest(result));
await test_utils.getRoomFeatures(_converse, 'coven', 'chat.shakespeare.lit');
const pres = await test_utils.waitUntil(
const pres = await u.waitUntil(
() => sent_stanzas.slice(index).filter(s => s.nodeName === 'presence').pop());
expect(Strophe.serialize(pres)).toBe(
`<presence from="${_converse.jid}" to="coven@chat.shakespeare.lit/romeo" xmlns="jabber:client">`+
@ -2194,7 +2194,7 @@
</x>
</message>`);
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-info').length === 2);
await u.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-info').length === 2);
const info_messages = view.el.querySelectorAll('.chat-content .chat-info');
expect(info_messages[0].textContent).toBe('romeo has entered the groupchat');
expect(info_messages[1].textContent).toBe('groupchat logging is now enabled');
@ -2248,7 +2248,7 @@
expect(view.model.get('connection_status')).toBe(converse.ROOMSTATUS.ENTERED);
const chat_content = view.el.querySelector('.chat-content');
await test_utils.waitUntil(() => view.el.querySelectorAll('li .occupant-nick').length, 500);
await u.waitUntil(() => view.el.querySelectorAll('li .occupant-nick').length, 500);
let occupants = view.el.querySelector('.occupant-list');
expect(occupants.childNodes.length).toBe(1);
expect(occupants.firstElementChild.querySelector('.occupant-nick').textContent.trim()).toBe("oldnick");
@ -2274,7 +2274,7 @@
.c('status').attrs({code:'110'}).nodeTree;
_converse.connection._dataRecv(test_utils.createRequest(presence));
await test_utils.waitUntil(() => view.el.querySelectorAll('.chat-info').length === 2);
await u.waitUntil(() => view.el.querySelectorAll('.chat-info').length === 2);
expect(sizzle('div.chat-info:last').pop().textContent).toBe(
__(_converse.muc.new_nickname_messages["303"], "newnick")
@ -2322,7 +2322,7 @@
const muc_jid = 'coven@chat.shakespeare.lit';
await _converse.api.rooms.open(muc_jid, {'nick': 'some1'});
const stanza = await test_utils.waitUntil(() => _.filter(
const stanza = await u.waitUntil(() => _.filter(
IQ_stanzas,
iq => iq.querySelector(
`iq[to="${muc_jid}"] query[xmlns="http://jabber.org/protocol/disco#info"]`
@ -2374,7 +2374,7 @@
.c('feature', {'var': 'muc_nonanonymous'});
_converse.connection._dataRecv(test_utils.createRequest(features_stanza));
let view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
await test_utils.waitUntil(() => (view.model.get('connection_status') === converse.ROOMSTATUS.CONNECTING));
await u.waitUntil(() => (view.model.get('connection_status') === converse.ROOMSTATUS.CONNECTING));
view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
expect(view.model.features.get('fetched')).toBeTruthy();
expect(view.model.features.get('passwordprotected')).toBe(true);
@ -2425,7 +2425,7 @@
chatroomview.el.querySelector('.configure-chatroom-button').click();
const IQs = _converse.connection.IQ_stanzas;
let iq = await test_utils.waitUntil(() => _.filter(
let iq = await u.waitUntil(() => _.filter(
IQs,
iq => iq.querySelector(
`iq[to="${jid}"] query[xmlns="${Strophe.NS.MUC_OWNER}"]`
@ -2497,13 +2497,13 @@
</query>
</iq>`);
_converse.connection._dataRecv(test_utils.createRequest(response_el));
const el = await test_utils.waitUntil(() => document.querySelector('.chatroom-form legend'));
const el = await u.waitUntil(() => document.querySelector('.chatroom-form legend'));
expect(el.textContent).toBe("Configuration for room@conference.example.org");
sizzle('[name="muc#roomconfig_membersonly"]', chatroomview.el).pop().click();
sizzle('[name="muc#roomconfig_roomname"]', chatroomview.el).pop().value = "New room name"
chatroomview.el.querySelector('.btn-primary').click();
iq = await test_utils.waitUntil(() => _.filter(IQs, iq => u.matchesSelector(iq, `iq[to="${jid}"][type="set"]`)).pop());
iq = await u.waitUntil(() => _.filter(IQs, iq => u.matchesSelector(iq, `iq[to="${jid}"][type="set"]`)).pop());
const result = $iq({
"xmlns": "jabber:client",
"type": "result",
@ -2515,7 +2515,7 @@
IQs.length = 0; // Empty the array
_converse.connection._dataRecv(test_utils.createRequest(result));
iq = await test_utils.waitUntil(() => _.filter(
iq = await u.waitUntil(() => _.filter(
IQs,
iq => iq.querySelector(
`iq[to="${jid}"] query[xmlns="http://jabber.org/protocol/disco#info"]`
@ -2553,7 +2553,7 @@
_converse.connection._dataRecv(test_utils.createRequest(features_stanza));
await test_utils.waitUntil(() => new Promise(success => chatroomview.model.features.on('change', success)));
await u.waitUntil(() => new Promise(success => chatroomview.model.features.on('change', success)));
features_list = chatroomview.el.querySelector('.features-list');
features_shown = features_list.textContent.split('\n').map(s => s.trim()).filter(s => s);
expect(_.difference(["Password protected", "Hidden", "Members only", "Temporary", "Not anonymous", "Not moderated"], features_shown).length).toBe(0);
@ -2617,7 +2617,7 @@
.c('status', {code: '104'}).up()
.c('status', {code: '172'});
_converse.connection._dataRecv(test_utils.createRequest(message));
await test_utils.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-info').length === 3);
await u.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-info').length === 3);
const chat_body = view.el.querySelector('.chatroom-body');
expect(sizzle('.message:last', chat_body).pop().textContent)
.toBe('This groupchat is now no longer anonymous');
@ -2730,7 +2730,7 @@
expect(u.isVisible(view.el)).toBeFalsy();
expect(view.model.get('minimized')).toBeTruthy();
expect(view.onMinimized).toHaveBeenCalled();
await test_utils.waitUntil(() => trimmed_chatboxes.get(view.model.get('id')));
await u.waitUntil(() => trimmed_chatboxes.get(view.model.get('id')));
const trimmedview = trimmed_chatboxes.get(view.model.get('id'));
trimmedview.el.querySelector("a.restore-chat").click();
expect(view.onMaximized).toHaveBeenCalled();
@ -2943,7 +2943,7 @@
});
_converse.connection.IQ_stanzas = [];
_converse.connection._dataRecv(test_utils.createRequest(result));
iq_stanza = await test_utils.waitUntil(() => _.filter(
iq_stanza = await u.waitUntil(() => _.filter(
_converse.connection.IQ_stanzas,
iq => iq.querySelector('iq[to="lounge@muc.montague.lit"][type="get"] item[affiliation="member"]')).pop()
);
@ -2967,7 +2967,7 @@
_converse.connection._dataRecv(test_utils.createRequest(result));
expect(view.model.occupants.length).toBe(2);
iq_stanza = await test_utils.waitUntil(() => _.filter(
iq_stanza = await u.waitUntil(() => _.filter(
_converse.connection.IQ_stanzas,
iq => iq.querySelector('iq[to="lounge@muc.montague.lit"][type="get"] item[affiliation="owner"]')).pop()
);
@ -2991,7 +2991,7 @@
_converse.connection._dataRecv(test_utils.createRequest(result));
expect(view.model.occupants.length).toBe(2);
iq_stanza = await test_utils.waitUntil(() => _.filter(
iq_stanza = await u.waitUntil(() => _.filter(
_converse.connection.IQ_stanzas,
iq => iq.querySelector('iq[to="lounge@muc.montague.lit"][type="get"] item[affiliation="admin"]')).pop()
);
@ -3012,8 +3012,8 @@
"id": iq_stanza.getAttribute("id")
}).c("query", {"xmlns": "http://jabber.org/protocol/muc#admin"})
_converse.connection._dataRecv(test_utils.createRequest(result));
await test_utils.waitUntil(() => view.el.querySelectorAll('.occupant').length, 500);
await test_utils.waitUntil(() => view.el.querySelectorAll('.badge').length > 1);
await u.waitUntil(() => view.el.querySelectorAll('.occupant').length, 500);
await u.waitUntil(() => view.el.querySelectorAll('.badge').length > 1);
expect(view.model.occupants.length).toBe(2);
expect(view.el.querySelectorAll('.occupant').length).toBe(2);
done();
@ -3363,7 +3363,7 @@
.c('status', {'code': '307'});
_converse.connection._dataRecv(test_utils.createRequest(presence));
await test_utils.waitUntil(() => view.el.querySelectorAll('.chat-info').length === 4);
await u.waitUntil(() => view.el.querySelectorAll('.chat-info').length === 4);
expect(view.el.querySelectorAll('.chat-info')[3].textContent).toBe("annoying guy has been kicked out");
expect(view.el.querySelectorAll('.chat-info').length).toBe(4);
done();
@ -3700,7 +3700,7 @@
spyOn(_converse.api, "trigger");
expect(_converse.chatboxes.length).toBe(2);
_converse.connection._dataRecv(test_utils.createRequest(result_stanza));
await test_utils.waitUntil(() => (view.model.get('connection_status') === converse.ROOMSTATUS.DISCONNECTED));
await u.waitUntil(() => (view.model.get('connection_status') === converse.ROOMSTATUS.DISCONNECTED));
expect(_converse.chatboxes.length).toBe(1);
expect(_converse.api.trigger).toHaveBeenCalledWith('chatBoxClosed', jasmine.any(Object));
done();
@ -3764,7 +3764,7 @@
const muc_jid = 'members-only@muc.montague.lit'
await test_utils.openChatRoomViaModal(_converse, muc_jid, 'romeo');
const view = _converse.chatboxviews.get(muc_jid);
const iq = await test_utils.waitUntil(() => _.filter(
const iq = await u.waitUntil(() => _.filter(
_converse.connection.IQ_stanzas,
iq => iq.querySelector(
`iq[to="${muc_jid}"] query[xmlns="http://jabber.org/protocol/disco#info"]`
@ -3788,7 +3788,7 @@
.c('feature', {'var': 'muc_temporary'}).up()
.c('feature', {'var': 'muc_membersonly'}).up();
_converse.connection._dataRecv(test_utils.createRequest(features_stanza));
await test_utils.waitUntil(() => view.model.get('connection_status') === converse.ROOMSTATUS.CONNECTING);
await u.waitUntil(() => view.model.get('connection_status') === converse.ROOMSTATUS.CONNECTING);
const presence = $pres().attrs({
from: `${muc_jid}/romeo`,
@ -3813,7 +3813,7 @@
const muc_jid = 'off-limits@muc.montague.lit'
await test_utils.openChatRoomViaModal(_converse, muc_jid, 'romeo');
const iq = await test_utils.waitUntil(() => _.filter(
const iq = await u.waitUntil(() => _.filter(
_converse.connection.IQ_stanzas,
iq => iq.querySelector(
`iq[to="${muc_jid}"] query[xmlns="http://jabber.org/protocol/disco#info"]`
@ -3833,7 +3833,7 @@
_converse.connection._dataRecv(test_utils.createRequest(features_stanza));
const view = _converse.chatboxviews.get(muc_jid);
await test_utils.waitUntil(() => view.model.get('connection_status') === converse.ROOMSTATUS.CONNECTING);
await u.waitUntil(() => view.model.get('connection_status') === converse.ROOMSTATUS.CONNECTING);
const presence = $pres().attrs({
from: `${muc_jid}/romeo`,
@ -3882,7 +3882,7 @@
it("will automatically choose a new nickname if a nickname conflict happens and muc_nickname_from_jid=true",
mock.initConverse(
null, ['rosterGroupsFetched'], {},
null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
async function (done, _converse) {
const muc_jid = 'conflicting@muc.montague.lit'
@ -3950,7 +3950,7 @@
await test_utils.openChatRoomViaModal(_converse, muc_jid, 'romeo')
// We pretend this is a new room, so no disco info is returned.
const iq = await test_utils.waitUntil(() => _.filter(
const iq = await u.waitUntil(() => _.filter(
_converse.connection.IQ_stanzas,
iq => iq.querySelector(
`iq[to="${muc_jid}"] query[xmlns="http://jabber.org/protocol/disco#info"]`
@ -3965,7 +3965,7 @@
_converse.connection._dataRecv(test_utils.createRequest(features_stanza));
const view = _converse.chatboxviews.get(muc_jid);
await test_utils.waitUntil(() => (view.model.get('connection_status') === converse.ROOMSTATUS.CONNECTING));
await u.waitUntil(() => (view.model.get('connection_status') === converse.ROOMSTATUS.CONNECTING));
const presence = $pres().attrs({
from: `${muc_jid}/romeo`,
@ -3990,7 +3990,7 @@
const muc_jid = 'conformist@muc.montague.lit'
await test_utils.openChatRoomViaModal(_converse, muc_jid, 'romeo');
const iq = await test_utils.waitUntil(() => _.filter(
const iq = await u.waitUntil(() => _.filter(
_converse.connection.IQ_stanzas,
iq => iq.querySelector(
`iq[to="${muc_jid}"] query[xmlns="http://jabber.org/protocol/disco#info"]`
@ -4006,7 +4006,7 @@
_converse.connection._dataRecv(test_utils.createRequest(features_stanza));
const view = _converse.chatboxviews.get(muc_jid);
await test_utils.waitUntil(() => (view.model.get('connection_status') === converse.ROOMSTATUS.CONNECTING));
await u.waitUntil(() => (view.model.get('connection_status') === converse.ROOMSTATUS.CONNECTING));
const presence = $pres().attrs({
from: `${muc_jid}/romeo`,
@ -4032,7 +4032,7 @@
const muc_jid = 'nonexistent@muc.montague.lit'
await test_utils.openChatRoomViaModal(_converse, muc_jid, 'romeo');
const iq = await test_utils.waitUntil(() => _.filter(
const iq = await u.waitUntil(() => _.filter(
_converse.connection.IQ_stanzas,
iq => iq.querySelector(
`iq[to="${muc_jid}"] query[xmlns="http://jabber.org/protocol/disco#info"]`
@ -4048,7 +4048,7 @@
_converse.connection._dataRecv(test_utils.createRequest(features_stanza));
const view = _converse.chatboxviews.get(muc_jid);
await test_utils.waitUntil(() => (view.model.get('connection_status') === converse.ROOMSTATUS.CONNECTING));
await u.waitUntil(() => (view.model.get('connection_status') === converse.ROOMSTATUS.CONNECTING));
const presence = $pres().attrs({
from: `${muc_jid}/romeo`,
@ -4074,7 +4074,7 @@
const muc_jid = 'maxed-out@muc.montague.lit'
await test_utils.openChatRoomViaModal(_converse, muc_jid, 'romeo')
const iq = await test_utils.waitUntil(() => _.filter(
const iq = await u.waitUntil(() => _.filter(
_converse.connection.IQ_stanzas,
iq => iq.querySelector(
`iq[to="${muc_jid}"] query[xmlns="http://jabber.org/protocol/disco#info"]`
@ -4090,7 +4090,7 @@
_converse.connection._dataRecv(test_utils.createRequest(features_stanza));
const view = _converse.chatboxviews.get(muc_jid);
await test_utils.waitUntil(() => (view.model.get('connection_status') === converse.ROOMSTATUS.CONNECTING));
await u.waitUntil(() => (view.model.get('connection_status') === converse.ROOMSTATUS.CONNECTING));
const presence = $pres().attrs({
from: `${muc_jid}/romeo`,
@ -4126,7 +4126,7 @@
});
await _converse.api.rooms.open(muc_jid, {'nick': 'romeo'});
let stanza = await test_utils.waitUntil(() => _.filter(
let stanza = await u.waitUntil(() => _.filter(
IQ_stanzas,
iq => iq.querySelector(
`iq[to="${muc_jid}"] query[xmlns="http://jabber.org/protocol/disco#info"]`
@ -4156,7 +4156,7 @@
.c('feature', {'var': 'muc_temporary'}).up()
.c('feature', {'var': 'muc_membersonly'}).up();
_converse.connection._dataRecv(test_utils.createRequest(features_stanza));
await test_utils.waitUntil(() => (view.model.get('connection_status') === converse.ROOMSTATUS.CONNECTING));
await u.waitUntil(() => (view.model.get('connection_status') === converse.ROOMSTATUS.CONNECTING));
expect(view.model.features.get('membersonly')).toBeTruthy();
test_utils.createContacts(_converse, 'current');
@ -4250,8 +4250,8 @@
'jid': 'crone1@shakespeare.lit',
});
_converse.connection._dataRecv(test_utils.createRequest(owner_list_stanza));
await test_utils.waitUntil(() => IQ_ids.length, 300);
stanza = await test_utils.waitUntil(() => _.filter(
await u.waitUntil(() => IQ_ids.length, 300);
stanza = await u.waitUntil(() => _.filter(
IQ_stanzas,
iq => iq.querySelector(
`iq[to="${muc_jid}"] query[xmlns="http://jabber.org/protocol/muc#admin"]`
@ -4353,7 +4353,7 @@
roomspanel.el.querySelector('.show-add-muc-modal').click();
test_utils.closeControlBox(_converse);
const modal = roomspanel.add_room_modal;
await test_utils.waitUntil(() => u.isVisible(modal.el), 1000)
await u.waitUntil(() => u.isVisible(modal.el), 1000)
let label_name = modal.el.querySelector('label[for="chatroom"]');
expect(label_name.textContent).toBe('Groupchat address:');
@ -4371,8 +4371,8 @@
roomspanel.delegateEvents(); // We need to rebind all events otherwise our spy won't be called
modal.el.querySelector('input[name="chatroom"]').value = 'lounce@muc.montague.lit';
modal.el.querySelector('form input[type="submit"]').click();
await test_utils.waitUntil(() => _converse.chatboxes.length);
await test_utils.waitUntil(() => sizzle('.chatroom', _converse.el).filter(u.isVisible).length === 1);
await u.waitUntil(() => _converse.chatboxes.length);
await u.waitUntil(() => sizzle('.chatroom', _converse.el).filter(u.isVisible).length === 1);
roomspanel.model.set('muc_domain', 'muc.example.org');
roomspanel.el.querySelector('.show-add-muc-modal').click();
@ -4394,13 +4394,13 @@
roomspanel.el.querySelector('.show-add-muc-modal').click();
test_utils.closeControlBox(_converse);
const modal = roomspanel.add_room_modal;
await test_utils.waitUntil(() => u.isVisible(modal.el), 1000)
await u.waitUntil(() => u.isVisible(modal.el), 1000)
const name_input = modal.el.querySelector('input[name="chatroom"]');
name_input.value = 'lounge@montague.lit';
expect(modal.el.querySelector('label[for="nickname"]')).toBe(null);
expect(modal.el.querySelector('input[name="nickname"]')).toBe(null);
modal.el.querySelector('form input[type="submit"]').click();
await test_utils.waitUntil(() => _converse.chatboxes.length > 1);
await u.waitUntil(() => _converse.chatboxes.length > 1);
const chatroom = _converse.chatboxes.get('lounge@montague.lit');
expect(chatroom.get('nick')).toBe('romeo');
done();
@ -4417,7 +4417,7 @@
roomspanel.el.querySelector('.show-add-muc-modal').click();
test_utils.closeControlBox(_converse);
const modal = roomspanel.add_room_modal;
await test_utils.waitUntil(() => u.isVisible(modal.el), 1000)
await u.waitUntil(() => u.isVisible(modal.el), 1000)
const label_nick = modal.el.querySelector('label[for="nickname"]');
expect(label_nick.textContent).toBe('Nickname:');
const nick_input = modal.el.querySelector('input[name="nickname"]');
@ -4436,7 +4436,7 @@
roomspanel.el.querySelector('.show-add-muc-modal').click();
test_utils.closeControlBox(_converse);
const modal = roomspanel.add_room_modal;
await test_utils.waitUntil(() => u.isVisible(modal.el), 1000)
await u.waitUntil(() => u.isVisible(modal.el), 1000)
const label_nick = modal.el.querySelector('label[for="nickname"]');
expect(label_nick.textContent).toBe('Nickname:');
const nick_input = modal.el.querySelector('input[name="nickname"]');
@ -4453,7 +4453,7 @@
const roomspanel = _converse.chatboxviews.get('controlbox').roomspanel;
roomspanel.el.querySelector('.show-add-muc-modal').click();
const modal = roomspanel.add_room_modal;
await test_utils.waitUntil(() => u.isVisible(modal.el), 1000)
await u.waitUntil(() => u.isVisible(modal.el), 1000)
expect(modal.el.querySelector('.modal-title').textContent).toBe('Enter a new Groupchat');
spyOn(_converse.ChatRoom.prototype, 'getRoomFeatures').and.callFake(() => Promise.resolve());
roomspanel.delegateEvents(); // We need to rebind all events otherwise our spy won't be called
@ -4466,20 +4466,20 @@
nick_input.value = 'max';
modal.el.querySelector('form input[type="submit"]').click();
await test_utils.waitUntil(() => _converse.chatboxes.length);
await test_utils.waitUntil(() => sizzle('.chatroom', _converse.el).filter(u.isVisible).length === 1);
await u.waitUntil(() => _converse.chatboxes.length);
await u.waitUntil(() => sizzle('.chatroom', _converse.el).filter(u.isVisible).length === 1);
expect(_.includes(_converse.chatboxes.models.map(m => m.get('id')), 'lounge@muc.example.org')).toBe(true);
// However, you can still open MUCs with different domains
roomspanel.el.querySelector('.show-add-muc-modal').click();
await test_utils.waitUntil(() => u.isVisible(modal.el), 1000);
await u.waitUntil(() => u.isVisible(modal.el), 1000);
name_input = modal.el.querySelector('input[name="chatroom"]');
name_input.value = 'lounge@conference.example.org';
nick_input = modal.el.querySelector('input[name="nickname"]');
nick_input.value = 'max';
modal.el.querySelector('form input[type="submit"]').click();
await test_utils.waitUntil(() => _converse.chatboxes.models.filter(c => c.get('type') === 'chatroom').length === 2);
await test_utils.waitUntil(() => sizzle('.chatroom', _converse.el).filter(u.isVisible).length === 2);
await u.waitUntil(() => _converse.chatboxes.models.filter(c => c.get('type') === 'chatroom').length === 2);
await u.waitUntil(() => sizzle('.chatroom', _converse.el).filter(u.isVisible).length === 2);
expect(_.includes(_converse.chatboxes.models.map(m => m.get('id')), 'lounge@conference.example.org')).toBe(true);
done();
}));
@ -4493,7 +4493,7 @@
const roomspanel = _converse.chatboxviews.get('controlbox').roomspanel;
roomspanel.el.querySelector('.show-add-muc-modal').click();
const modal = roomspanel.add_room_modal;
await test_utils.waitUntil(() => u.isVisible(modal.el), 1000)
await u.waitUntil(() => u.isVisible(modal.el), 1000)
expect(modal.el.querySelector('.modal-title').textContent).toBe('Enter a new Groupchat');
spyOn(_converse.ChatRoom.prototype, 'getRoomFeatures').and.callFake(() => Promise.resolve());
roomspanel.delegateEvents(); // We need to rebind all events otherwise our spy won't be called
@ -4505,20 +4505,20 @@
let nick_input = modal.el.querySelector('input[name="nickname"]');
nick_input.value = 'max';
modal.el.querySelector('form input[type="submit"]').click();
await test_utils.waitUntil(() => _converse.chatboxes.length);
await test_utils.waitUntil(() => sizzle('.chatroom', _converse.el).filter(u.isVisible).length === 1);
await u.waitUntil(() => _converse.chatboxes.length);
await u.waitUntil(() => sizzle('.chatroom', _converse.el).filter(u.isVisible).length === 1);
expect(_.includes(_converse.chatboxes.models.map(m => m.get('id')), 'lounge@muc.example.org')).toBe(true);
// However, you can still open MUCs with different domains
roomspanel.el.querySelector('.show-add-muc-modal').click();
await test_utils.waitUntil(() => u.isVisible(modal.el), 1000);
await u.waitUntil(() => u.isVisible(modal.el), 1000);
name_input = modal.el.querySelector('input[name="chatroom"]');
name_input.value = 'lounge@conference';
nick_input = modal.el.querySelector('input[name="nickname"]');
nick_input.value = 'max';
modal.el.querySelector('form input[type="submit"]').click();
await test_utils.waitUntil(() => _converse.chatboxes.models.filter(c => c.get('type') === 'chatroom').length === 2);
await test_utils.waitUntil(() => sizzle('.chatroom', _converse.el).filter(u.isVisible).length === 2);
await u.waitUntil(() => _converse.chatboxes.models.filter(c => c.get('type') === 'chatroom').length === 2);
await u.waitUntil(() => sizzle('.chatroom', _converse.el).filter(u.isVisible).length === 2);
expect(_.includes(_converse.chatboxes.models.map(m => m.get('id')), 'lounge\\40conference@muc.example.org')).toBe(true);
done();
}));
@ -4536,7 +4536,7 @@
roomspanel.el.querySelector('.show-list-muc-modal').click();
test_utils.closeControlBox(_converse);
const modal = roomspanel.list_rooms_modal;
await test_utils.waitUntil(() => u.isVisible(modal.el), 1000);
await u.waitUntil(() => u.isVisible(modal.el), 1000);
spyOn(_converse.ChatRoom.prototype, 'getRoomFeatures').and.callFake(() => Promise.resolve());
roomspanel.delegateEvents(); // We need to rebind all events otherwise our spy won't be called
@ -4547,10 +4547,10 @@
expect(server_input.placeholder).toBe('conference.example.org');
const input = server_input.value = 'chat.shakespeare.lit';
modal.el.querySelector('input[type="submit"]').click();
await test_utils.waitUntil(() => _converse.chatboxes.length);
await u.waitUntil(() => _converse.chatboxes.length);
const IQ_stanzas = _converse.connection.IQ_stanzas;
const sent_stanza = await test_utils.waitUntil(
const sent_stanza = await u.waitUntil(
() => IQ_stanzas.filter(s => sizzle(`query[xmlns="${Strophe.NS.DISCO_ITEMS}"]`, s).length).pop()
);
const id = sent_stanza.getAttribute('id');
@ -4580,7 +4580,7 @@
.c('item', { jid:'street@chat.shakespeare.lit', name:'A street'}).nodeTree;
_converse.connection._dataRecv(test_utils.createRequest(iq));
await test_utils.waitUntil(() => modal.el.querySelectorAll('.available-chatrooms li').length === 11);
await u.waitUntil(() => modal.el.querySelectorAll('.available-chatrooms li').length === 11);
const rooms = modal.el.querySelectorAll('.available-chatrooms li');
expect(rooms[0].textContent.trim()).toBe("Groupchats found:");
expect(rooms[1].textContent.trim()).toBe("A Lonely Heath");
@ -4595,7 +4595,7 @@
expect(rooms[10].textContent.trim()).toBe('A street');
rooms[4].querySelector('.open-room').click();
await test_utils.waitUntil(() => _converse.chatboxes.length > 1);
await u.waitUntil(() => _converse.chatboxes.length > 1);
expect(sizzle('.chatroom', _converse.el).filter(u.isVisible).length).toBe(1); // There should now be an open chatroom
var view = _converse.chatboxviews.get('inverness@chat.shakespeare.lit');
expect(view.el.querySelector('.chat-head-chatroom').textContent.trim()).toBe("Macbeth's Castle");
@ -4613,7 +4613,7 @@
roomspanel.el.querySelector('.show-list-muc-modal').click();
test_utils.closeControlBox(_converse);
const modal = roomspanel.list_rooms_modal;
await test_utils.waitUntil(() => u.isVisible(modal.el), 1000);
await u.waitUntil(() => u.isVisible(modal.el), 1000);
const server_input = modal.el.querySelector('input[name="server"]');
expect(server_input.value).toBe('muc.example.org');
done();
@ -4630,14 +4630,14 @@
roomspanel.el.querySelector('.show-list-muc-modal').click();
test_utils.closeControlBox(_converse);
const modal = roomspanel.list_rooms_modal;
await test_utils.waitUntil(() => u.isVisible(modal.el), 1000);
await u.waitUntil(() => u.isVisible(modal.el), 1000);
spyOn(_converse.ChatRoom.prototype, 'getRoomFeatures').and.callFake(() => Promise.resolve());
roomspanel.delegateEvents(); // We need to rebind all events otherwise our spy won't be called
expect(modal.el.querySelector('input[name="server"]')).toBe(null);
expect(modal.el.querySelector('input[type="submit"]')).toBe(null);
await test_utils.waitUntil(() => _converse.chatboxes.length);
const sent_stanza = await test_utils.waitUntil(() =>
await u.waitUntil(() => _converse.chatboxes.length);
const sent_stanza = await u.waitUntil(() =>
_converse.connection.sent_stanzas.filter(
s => sizzle(`query[xmlns="http://jabber.org/protocol/disco#items"]`, s).length).pop()
);
@ -4658,7 +4658,7 @@
.c('item', { jid:'forres@chat.shakespeare.lit', name:'The Palace'}).up()
_converse.connection._dataRecv(test_utils.createRequest(iq));
await test_utils.waitUntil(() => modal.el.querySelectorAll('.available-chatrooms li').length === 4);
await u.waitUntil(() => modal.el.querySelectorAll('.available-chatrooms li').length === 4);
const rooms = modal.el.querySelectorAll('.available-chatrooms li');
expect(rooms[0].textContent.trim()).toBe("Groupchats found:");
expect(rooms[1].textContent.trim()).toBe("A Lonely Heath");
@ -4697,7 +4697,7 @@
to: 'romeo@montague.lit',
type: 'groupchat'
}).c('body').t(message).tree());
await test_utils.waitUntil(() => view.model.messages.length);
await u.waitUntil(() => view.model.messages.length);
expect(roomspanel.el.querySelectorAll('.available-room').length).toBe(1);
expect(roomspanel.el.querySelectorAll('.msgs-indicator').length).toBe(1);
expect(roomspanel.el.querySelector('.msgs-indicator').textContent).toBe('1');
@ -4708,7 +4708,7 @@
'to': 'romeo@montague.lit',
'type': 'groupchat'
}).c('body').t(message).tree());
await test_utils.waitUntil(() => view.model.messages.length > 1);
await u.waitUntil(() => view.model.messages.length > 1);
expect(roomspanel.el.querySelectorAll('.available-room').length).toBe(1);
expect(roomspanel.el.querySelectorAll('.msgs-indicator').length).toBe(1);
expect(roomspanel.el.querySelector('.msgs-indicator').textContent).toBe('2');
@ -4829,7 +4829,7 @@
}).c('body').c('composing', {'xmlns': Strophe.NS.CHATSTATES}).tree();
await view.model.onMessage(msg);
await test_utils.waitUntil(() => view.el.querySelectorAll('.chat-state-notification').length);
await u.waitUntil(() => view.el.querySelectorAll('.chat-state-notification').length);
// Check that the notification appears inside the chatbox in the DOM
let events = view.el.querySelectorAll('.chat-event');
@ -4879,7 +4879,7 @@
expect(events[1].textContent).toEqual('newguy has entered the groupchat');
expect(events[2].textContent).toEqual('nomorenicks has entered the groupchat');
await test_utils.waitUntil(() => (view.el.querySelectorAll('.chat-state-notification').length === 2));
await u.waitUntil(() => (view.el.querySelectorAll('.chat-state-notification').length === 2));
notifications = view.el.querySelectorAll('.chat-state-notification');
expect(notifications.length).toBe(2);
expect(notifications[0].textContent).toEqual('nomorenicks is typing');
@ -5006,7 +5006,7 @@
expect(events[1].textContent).toEqual('newguy has entered the groupchat');
expect(events[2].textContent).toEqual('nomorenicks has entered the groupchat');
await test_utils.waitUntil(() => view.el.querySelectorAll('.chat-state-notification').length);
await u.waitUntil(() => view.el.querySelectorAll('.chat-state-notification').length);
let notifications = view.el.querySelectorAll('.chat-state-notification');
expect(notifications.length).toBe(1);
expect(notifications[0].textContent).toEqual('newguy is typing');
@ -5044,7 +5044,7 @@
expect(events[1].textContent).toEqual('newguy has entered the groupchat');
expect(events[2].textContent).toEqual('nomorenicks has entered the groupchat');
await test_utils.waitUntil(() => view.el.querySelectorAll('.chat-state-notification').length === 2);
await u.waitUntil(() => view.el.querySelectorAll('.chat-state-notification').length === 2);
notifications = view.el.querySelectorAll('.chat-state-notification');
// We check for the messages' text without assuming order,
// because it can be variable since getLastMessageDate
@ -5067,7 +5067,7 @@
expect(events[1].textContent).toEqual('newguy has entered the groupchat');
expect(events[2].textContent).toEqual('nomorenicks has entered the groupchat');
await test_utils.waitUntil(() => {
await u.waitUntil(() => {
return _.map(
view.el.querySelectorAll('.chat-state-notification'), 'textContent')
.join(' ').includes('stopped typing')

View File

@ -2,9 +2,10 @@
define(["jasmine", "mock", "test-utils"], factory);
} (this, function (jasmine, mock, test_utils) {
"use strict";
const Strophe = converse.env.Strophe,
_ = converse.env._,
$msg = converse.env.$msg;
const Strophe = converse.env.Strophe;
const _ = converse.env._;
const $msg = converse.env.$msg;
const u = converse.env.utils;
describe("Notifications", function () {
// Implement the protocol defined in https://xmpp.org/extensions/xep-0313.html#config
@ -35,7 +36,7 @@
}).c('body').t(message).up()
.c('active', {'xmlns': 'http://jabber.org/protocol/chatstates'}).tree();
await _converse.chatboxes.onMessage(msg); // This will emit 'message'
await test_utils.waitUntil(() => _converse.api.chatviews.get(sender_jid));
await u.waitUntil(() => _converse.api.chatviews.get(sender_jid));
expect(_converse.areDesktopNotificationsEnabled).toHaveBeenCalled();
expect(_converse.showMessageNotification).toHaveBeenCalled();
done();
@ -102,7 +103,7 @@
.c('x', {'xmlns': 'jabber:x:oob'})
.c('url').t('imap://romeo@example.com/INBOX;UIDVALIDITY=385759043/;UID=18');
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => _converse.chatboxviews.keys().length);
await u.waitUntil(() => _converse.chatboxviews.keys().length);
const view = _converse.chatboxviews.get('notify.example.com');
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
expect(
@ -188,7 +189,7 @@
type: 'groupchat'
}).c('body').t(text);
await view.model.onMessage(message.nodeTree);
await test_utils.waitUntil(() => _converse.playSoundNotification.calls.count());
await u.waitUntil(() => _converse.playSoundNotification.calls.count());
expect(_converse.playSoundNotification).toHaveBeenCalled();
text = "This message won't play a sound";

View File

@ -6,11 +6,11 @@
async function deviceListFetched (_converse, jid) {
const stanza = await test_utils.waitUntil(() => _.filter(
const stanza = await u.waitUntil(() => _.filter(
_converse.connection.IQ_stanzas,
iq => iq.querySelector(`iq[to="${jid}"] items[node="eu.siacs.conversations.axolotl.devicelist"]`)
).pop());
await test_utils.waitUntil(() => _converse.devicelists.get(jid));
await u.waitUntil(() => _converse.devicelists.get(jid));
return stanza;
}
@ -41,7 +41,7 @@
[{'category': 'pubsub', 'type': 'pep'}],
['http://jabber.org/protocol/pubsub#publish-options']
);
let iq_stanza = await test_utils.waitUntil(() => deviceListFetched(_converse, _converse.bare_jid));
let iq_stanza = await u.waitUntil(() => deviceListFetched(_converse, _converse.bare_jid));
let stanza = $iq({
'from': _converse.bare_jid,
'id': iq_stanza.getAttribute('id'),
@ -53,7 +53,7 @@
.c('list', {'xmlns': "eu.siacs.conversations.axolotl"})
.c('device', {'id': '482886413b977930064a5888b92134fe'});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
iq_stanza = await test_utils.waitUntil(() => ownDeviceHasBeenPublished(_converse))
iq_stanza = await u.waitUntil(() => ownDeviceHasBeenPublished(_converse))
stanza = $iq({
'from': _converse.bare_jid,
@ -61,7 +61,7 @@
'to': _converse.bare_jid,
'type': 'result'});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
iq_stanza = await test_utils.waitUntil(() => bundleHasBeenPublished(_converse))
iq_stanza = await u.waitUntil(() => bundleHasBeenPublished(_converse))
stanza = $iq({
'from': _converse.bare_jid,
@ -101,9 +101,9 @@
test_utils.createContacts(_converse, 'current', 1);
_converse.api.trigger('rosterContactsFetched');
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
await test_utils.waitUntil(() => initializedOMEMO(_converse));
await u.waitUntil(() => initializedOMEMO(_converse));
await test_utils.openChatBoxFor(_converse, contact_jid);
let iq_stanza = await test_utils.waitUntil(() => deviceListFetched(_converse, contact_jid));
let iq_stanza = await u.waitUntil(() => deviceListFetched(_converse, contact_jid));
let stanza = $iq({
'from': contact_jid,
'id': iq_stanza.getAttribute('id'),
@ -115,9 +115,9 @@
.c('list', {'xmlns': "eu.siacs.conversations.axolotl"})
.c('device', {'id': '555'});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => _converse.omemo_store);
await u.waitUntil(() => _converse.omemo_store);
const devicelist = _converse.devicelists.get({'jid': contact_jid});
await test_utils.waitUntil(() => devicelist.devices.length === 1);
await u.waitUntil(() => devicelist.devices.length === 1);
const view = _converse.chatboxviews.get(contact_jid);
view.model.set('omemo_active', true);
@ -129,7 +129,7 @@
preventDefault: _.noop,
keyCode: 13 // Enter
});
iq_stanza = await test_utils.waitUntil(() => bundleFetched(_converse, contact_jid, '555'));
iq_stanza = await u.waitUntil(() => bundleFetched(_converse, contact_jid, '555'));
stanza = $iq({
'from': contact_jid,
'id': iq_stanza.getAttribute('id'),
@ -148,7 +148,7 @@
.c('preKeyPublic', {'preKeyId': '2'}).t(btoa('1002')).up()
.c('preKeyPublic', {'preKeyId': '3'}).t(btoa('1003'));
_converse.connection._dataRecv(test_utils.createRequest(stanza));
iq_stanza = await test_utils.waitUntil(() => bundleFetched(_converse, _converse.bare_jid, '482886413b977930064a5888b92134fe'));
iq_stanza = await u.waitUntil(() => bundleFetched(_converse, _converse.bare_jid, '482886413b977930064a5888b92134fe'));
stanza = $iq({
'from': _converse.bare_jid,
'id': iq_stanza.getAttribute('id'),
@ -169,7 +169,7 @@
spyOn(_converse.connection, 'send').and.callFake(stanza => { sent_stanza = stanza });
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => sent_stanza);
await u.waitUntil(() => sent_stanza);
expect(sent_stanza.toLocaleString()).toBe(
`<message from="romeo@montague.lit/orchard" id="${sent_stanza.nodeTree.getAttribute("id")}" `+
`to="mercutio@montague.lit" `+
@ -225,7 +225,7 @@
.c('payload').t(obj.payload);
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
await test_utils.waitUntil(() => view.model.messages.length > 1);
await u.waitUntil(() => view.model.messages.length > 1);
expect(view.model.messages.length).toBe(3);
expect(view.el.querySelectorAll('.chat-msg__body')[2].textContent.trim())
.toBe('Another received encrypted message without fallback');
@ -251,7 +251,7 @@
];
await test_utils.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo', features);
const view = _converse.chatboxviews.get('lounge@montague.lit');
await test_utils.waitUntil(() => initializedOMEMO(_converse));
await u.waitUntil(() => initializedOMEMO(_converse));
const toolbar = view.el.querySelector('.chat-toolbar');
let toggle = toolbar.querySelector('.toggle-omemo');
@ -273,7 +273,7 @@
_converse.connection._dataRecv(test_utils.createRequest(stanza));
// Wait for Converse to fetch newguy's device list
let iq_stanza = await test_utils.waitUntil(() => deviceListFetched(_converse, contact_jid));
let iq_stanza = await u.waitUntil(() => deviceListFetched(_converse, contact_jid));
expect(Strophe.serialize(iq_stanza)).toBe(
`<iq from="romeo@montague.lit" id="${iq_stanza.getAttribute("id")}" to="${contact_jid}" type="get" xmlns="jabber:client">`+
`<pubsub xmlns="http://jabber.org/protocol/pubsub">`+
@ -293,10 +293,10 @@
.c('list', {'xmlns': "eu.siacs.conversations.axolotl"})
.c('device', {'id': '4e30f35051b7b8b42abe083742187228'}).up()
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => _converse.omemo_store);
await u.waitUntil(() => _converse.omemo_store);
expect(_converse.devicelists.length).toBe(2);
await test_utils.waitUntil(() => deviceListFetched(_converse, contact_jid));
await u.waitUntil(() => deviceListFetched(_converse, contact_jid));
const devicelist = _converse.devicelists.get(contact_jid);
expect(devicelist.devices.length).toBe(1);
expect(devicelist.devices.at(0).get('id')).toBe('4e30f35051b7b8b42abe083742187228');
@ -313,7 +313,7 @@
preventDefault: _.noop,
keyCode: 13 // Enter
});
iq_stanza = await test_utils.waitUntil(() => bundleFetched(_converse, contact_jid, '4e30f35051b7b8b42abe083742187228'), 1000);
iq_stanza = await u.waitUntil(() => bundleFetched(_converse, contact_jid, '4e30f35051b7b8b42abe083742187228'), 1000);
console.log("Bundle fetched 4e30f35051b7b8b42abe083742187228");
stanza = $iq({
'from': contact_jid,
@ -334,7 +334,7 @@
.c('preKeyPublic', {'preKeyId': '3'}).t(btoa('1003'));
_converse.connection._dataRecv(test_utils.createRequest(stanza));
iq_stanza = await test_utils.waitUntil(() => bundleFetched(_converse, _converse.bare_jid, '482886413b977930064a5888b92134fe'), 1000);
iq_stanza = await u.waitUntil(() => bundleFetched(_converse, _converse.bare_jid, '482886413b977930064a5888b92134fe'), 1000);
console.log("Bundle fetched 482886413b977930064a5888b92134fe");
stanza = $iq({
'from': _converse.bare_jid,
@ -356,7 +356,7 @@
spyOn(_converse.connection, 'send');
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => _converse.connection.send.calls.count(), 1000);
await u.waitUntil(() => _converse.connection.send.calls.count(), 1000);
const sent_stanza = _converse.connection.send.calls.all()[0].args[0];
expect(Strophe.serialize(sent_stanza)).toBe(
@ -390,9 +390,9 @@
test_utils.createContacts(_converse, 'current', 1);
_converse.api.trigger('rosterContactsFetched');
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
await test_utils.waitUntil(() => initializedOMEMO(_converse));
await u.waitUntil(() => initializedOMEMO(_converse));
await test_utils.openChatBoxFor(_converse, contact_jid);
let iq_stanza = await test_utils.waitUntil(() => deviceListFetched(_converse, contact_jid));
let iq_stanza = await u.waitUntil(() => deviceListFetched(_converse, contact_jid));
const stanza = $iq({
'from': contact_jid,
'id': iq_stanza.getAttribute('id'),
@ -404,9 +404,9 @@
.c('list', {'xmlns': "eu.siacs.conversations.axolotl"})
.c('device', {'id': '555'});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => _converse.omemo_store);
await u.waitUntil(() => _converse.omemo_store);
const devicelist = _converse.devicelists.get({'jid': contact_jid});
await test_utils.waitUntil(() => devicelist.devices.length === 1);
await u.waitUntil(() => devicelist.devices.length === 1);
const view = _converse.chatboxviews.get(contact_jid);
view.model.set('omemo_active', true);
@ -461,7 +461,7 @@
preventDefault: _.noop,
keyCode: 13 // Enter
});
iq_stanza = await test_utils.waitUntil(() => bundleFetched(_converse, _converse.bare_jid, '988349631'));
iq_stanza = await u.waitUntil(() => bundleFetched(_converse, _converse.bare_jid, '988349631'));
expect(Strophe.serialize(iq_stanza)).toBe(
`<iq from="romeo@montague.lit" id="${iq_stanza.getAttribute("id")}" to="${_converse.bare_jid}" type="get" xmlns="jabber:client">`+
`<pubsub xmlns="http://jabber.org/protocol/pubsub">`+
@ -490,7 +490,7 @@
];
await test_utils.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo', features);
const view = _converse.chatboxviews.get('lounge@montague.lit');
await test_utils.waitUntil(() => initializedOMEMO(_converse));
await u.waitUntil(() => initializedOMEMO(_converse));
const contact_jid = 'newguy@montague.lit';
let stanza = $pres({
@ -518,7 +518,7 @@
preventDefault: _.noop,
keyCode: 13 // Enter
});
let iq_stanza = await test_utils.waitUntil(() => deviceListFetched(_converse, contact_jid));
let iq_stanza = await u.waitUntil(() => deviceListFetched(_converse, contact_jid));
expect(Strophe.serialize(iq_stanza)).toBe(
`<iq from="romeo@montague.lit" id="${iq_stanza.getAttribute("id")}" to="${contact_jid}" type="get" xmlns="jabber:client">`+
`<pubsub xmlns="http://jabber.org/protocol/pubsub">`+
@ -538,15 +538,15 @@
.c('device', {'id': '4e30f35051b7b8b42abe083742187228'}).up()
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => _converse.omemo_store);
await u.waitUntil(() => _converse.omemo_store);
expect(_converse.devicelists.length).toBe(2);
const devicelist = _converse.devicelists.get(contact_jid);
await test_utils.waitUntil(() => deviceListFetched(_converse, contact_jid));
await u.waitUntil(() => deviceListFetched(_converse, contact_jid));
expect(devicelist.devices.length).toBe(1);
expect(devicelist.devices.at(0).get('id')).toBe('4e30f35051b7b8b42abe083742187228');
iq_stanza = await test_utils.waitUntil(() => bundleFetched(_converse, _converse.bare_jid, '482886413b977930064a5888b92134fe'));
iq_stanza = await u.waitUntil(() => bundleFetched(_converse, _converse.bare_jid, '482886413b977930064a5888b92134fe'));
stanza = $iq({
'from': _converse.bare_jid,
'id': iq_stanza.getAttribute('id'),
@ -564,7 +564,7 @@
.c('preKeyPublic', {'preKeyId': '1'}).t(btoa('1991')).up()
.c('preKeyPublic', {'preKeyId': '2'}).t(btoa('1992')).up()
.c('preKeyPublic', {'preKeyId': '3'}).t(btoa('1993'));
iq_stanza = await test_utils.waitUntil(() => bundleFetched(_converse, contact_jid, '4e30f35051b7b8b42abe083742187228'));
iq_stanza = await u.waitUntil(() => bundleFetched(_converse, contact_jid, '4e30f35051b7b8b42abe083742187228'));
/* <iq xmlns="jabber:client" to="jc@opkode.com/converse.js-34183907" type="error" id="945c8ab3-b561-4d8a-92da-77c226bb1689:sendIQ" from="joris@konuro.net">
* <pubsub xmlns="http://jabber.org/protocol/pubsub">
@ -588,7 +588,7 @@
.c('not-authorized', {'xmlns': "urn:ietf:params:xml:ns:xmpp-stanzas"});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => document.querySelectorAll('.alert-danger').length, 2000);
await u.waitUntil(() => document.querySelectorAll('.alert-danger').length, 2000);
const header = document.querySelector('.alert-danger .modal-title');
expect(header.textContent).toBe("Error");
expect(u.ancestor(header, '.modal-content').querySelector('.modal-body p').textContent.trim())
@ -611,7 +611,7 @@
_converse.api.trigger('rosterContactsFetched');
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
await test_utils.waitUntil(() => initializedOMEMO(_converse));
await u.waitUntil(() => initializedOMEMO(_converse));
const obj = await _converse.ChatBox.prototype.encryptMessage('This is an encrypted message from the contact');
// XXX: Normally the key will be encrypted via libsignal.
// However, we're mocking libsignal in the tests, so we include
@ -642,7 +642,7 @@
return generateMissingPreKeys.apply(_converse.omemo_store, arguments);
});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
let iq_stanza = await test_utils.waitUntil(() => _converse.chatboxviews.get(contact_jid));
let iq_stanza = await u.waitUntil(() => _converse.chatboxviews.get(contact_jid));
iq_stanza = await deviceListFetched(_converse, contact_jid);
stanza = $iq({
'from': contact_jid,
@ -660,9 +660,9 @@
// stanzas.
_converse.connection.IQ_stanzas = [];
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => _converse.omemo_store);
await u.waitUntil(() => _converse.omemo_store);
iq_stanza = await test_utils.waitUntil(() => bundleHasBeenPublished(_converse));
iq_stanza = await u.waitUntil(() => bundleHasBeenPublished(_converse));
expect(Strophe.serialize(iq_stanza)).toBe(
`<iq from="romeo@montague.lit" id="${iq_stanza.getAttribute("id")}" type="set" xmlns="jabber:client">`+
`<pubsub xmlns="http://jabber.org/protocol/pubsub">`+
@ -716,7 +716,7 @@
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
// Wait until own devices are fetched
let iq_stanza = await test_utils.waitUntil(() => deviceListFetched(_converse, _converse.bare_jid));
let iq_stanza = await u.waitUntil(() => deviceListFetched(_converse, _converse.bare_jid));
expect(Strophe.serialize(iq_stanza)).toBe(
`<iq from="romeo@montague.lit" id="${iq_stanza.getAttribute("id")}" to="romeo@montague.lit" type="get" xmlns="jabber:client">`+
`<pubsub xmlns="http://jabber.org/protocol/pubsub">`+
@ -735,21 +735,21 @@
.c('list', {'xmlns': "eu.siacs.conversations.axolotl"})
.c('device', {'id': '555'});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => _converse.omemo_store);
await u.waitUntil(() => _converse.omemo_store);
expect(_converse.chatboxes.length).toBe(1);
expect(_converse.devicelists.length).toBe(1);
const devicelist = _converse.devicelists.get(_converse.bare_jid);
expect(devicelist.devices.length).toBe(2);
expect(devicelist.devices.at(0).get('id')).toBe('555');
expect(devicelist.devices.at(1).get('id')).toBe('123456789');
iq_stanza = await test_utils.waitUntil(() => ownDeviceHasBeenPublished(_converse));
iq_stanza = await u.waitUntil(() => ownDeviceHasBeenPublished(_converse));
stanza = $iq({
'from': _converse.bare_jid,
'id': iq_stanza.getAttribute('id'),
'to': _converse.bare_jid,
'type': 'result'});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
iq_stanza = await test_utils.waitUntil(() => bundleHasBeenPublished(_converse));
iq_stanza = await u.waitUntil(() => bundleHasBeenPublished(_converse));
stanza = $iq({
'from': _converse.bare_jid,
@ -835,7 +835,7 @@
.c('device', {'id': '444'})
_converse.connection._dataRecv(test_utils.createRequest(stanza));
iq_stanza = await test_utils.waitUntil(() => ownDeviceHasBeenPublished(_converse));
iq_stanza = await u.waitUntil(() => ownDeviceHasBeenPublished(_converse));
// Check that our own device is added again, but that removed
// devices are not added.
expect(Strophe.serialize(iq_stanza)).toBe(
@ -888,7 +888,7 @@
test_utils.createContacts(_converse, 'current');
const contact_jid = mock.cur_names[3].replace(/ /g,'.').toLowerCase() + '@montague.lit';
let iq_stanza = await test_utils.waitUntil(() => deviceListFetched(_converse, _converse.bare_jid));
let iq_stanza = await u.waitUntil(() => deviceListFetched(_converse, _converse.bare_jid));
expect(Strophe.serialize(iq_stanza)).toBe(
`<iq from="romeo@montague.lit" id="${iq_stanza.getAttribute("id")}" to="romeo@montague.lit" type="get" xmlns="jabber:client">`+
`<pubsub xmlns="http://jabber.org/protocol/pubsub">`+
@ -907,20 +907,20 @@
.c('list', {'xmlns': "eu.siacs.conversations.axolotl"})
.c('device', {'id': '555'});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await await test_utils.waitUntil(() => _converse.omemo_store);
await await u.waitUntil(() => _converse.omemo_store);
expect(_converse.devicelists.length).toBe(1);
let devicelist = _converse.devicelists.get(_converse.bare_jid);
expect(devicelist.devices.length).toBe(2);
expect(devicelist.devices.at(0).get('id')).toBe('555');
expect(devicelist.devices.at(1).get('id')).toBe('123456789');
iq_stanza = await test_utils.waitUntil(() => ownDeviceHasBeenPublished(_converse));
iq_stanza = await u.waitUntil(() => ownDeviceHasBeenPublished(_converse));
stanza = $iq({
'from': _converse.bare_jid,
'id': iq_stanza.getAttribute('id'),
'to': _converse.bare_jid,
'type': 'result'});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
iq_stanza = await test_utils.waitUntil(() => bundleHasBeenPublished(_converse));
iq_stanza = await u.waitUntil(() => bundleHasBeenPublished(_converse));
stanza = $iq({
'from': _converse.bare_jid,
'id': iq_stanza.getAttribute('id'),
@ -1041,7 +1041,7 @@
test_utils.createContacts(_converse, 'current', 1);
_converse.api.trigger('rosterContactsFetched');
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
let iq_stanza = await test_utils.waitUntil(() => deviceListFetched(_converse, _converse.bare_jid));
let iq_stanza = await u.waitUntil(() => deviceListFetched(_converse, _converse.bare_jid));
let stanza = $iq({
'from': contact_jid,
'id': iq_stanza.getAttribute('id'),
@ -1063,7 +1063,7 @@
'type': 'result'});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
iq_stanza = await test_utils.waitUntil(() => bundleHasBeenPublished(_converse));
iq_stanza = await u.waitUntil(() => bundleHasBeenPublished(_converse));
expect(Strophe.serialize(iq_stanza)).toBe(
`<iq from="romeo@montague.lit" id="${iq_stanza.getAttribute("id")}" type="set" xmlns="jabber:client">`+
`<pubsub xmlns="http://jabber.org/protocol/pubsub">`+
@ -1119,7 +1119,7 @@
_converse.api.trigger('rosterContactsFetched');
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
let iq_stanza = await test_utils.waitUntil(() => deviceListFetched(_converse, _converse.bare_jid));
let iq_stanza = await u.waitUntil(() => deviceListFetched(_converse, _converse.bare_jid));
expect(Strophe.serialize(iq_stanza)).toBe(
`<iq from="romeo@montague.lit" id="${iq_stanza.getAttribute("id")}" to="romeo@montague.lit" type="get" xmlns="jabber:client">`+
`<pubsub xmlns="http://jabber.org/protocol/pubsub">`+
@ -1138,14 +1138,14 @@
.c('list', {'xmlns': "eu.siacs.conversations.axolotl"})
.c('device', {'id': '482886413b977930064a5888b92134fe'});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => _converse.omemo_store);
await u.waitUntil(() => _converse.omemo_store);
expect(_converse.devicelists.length).toBe(1);
let devicelist = _converse.devicelists.get(_converse.bare_jid);
expect(devicelist.devices.length).toBe(2);
expect(devicelist.devices.at(0).get('id')).toBe('482886413b977930064a5888b92134fe');
expect(devicelist.devices.at(1).get('id')).toBe('123456789');
// Check that own device was published
iq_stanza = await test_utils.waitUntil(() => ownDeviceHasBeenPublished(_converse));
iq_stanza = await u.waitUntil(() => ownDeviceHasBeenPublished(_converse));
expect(Strophe.serialize(iq_stanza)).toBe(
`<iq from="romeo@montague.lit" id="${iq_stanza.getAttribute(`id`)}" type="set" xmlns="jabber:client">`+
`<pubsub xmlns="http://jabber.org/protocol/pubsub">`+
@ -1177,7 +1177,7 @@
'type': 'result'});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
const iq_el = await test_utils.waitUntil(() => bundleHasBeenPublished(_converse));
const iq_el = await u.waitUntil(() => bundleHasBeenPublished(_converse));
expect(iq_el.getAttributeNames().sort().join()).toBe(["from", "type", "xmlns", "id"].sort().join());
expect(iq_el.querySelector('prekeys').childNodes.length).toBe(100);
@ -1196,7 +1196,7 @@
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await _converse.api.waitUntil('OMEMOInitialized', 1000);
await test_utils.openChatBoxFor(_converse, contact_jid);
iq_stanza = await test_utils.waitUntil(() => deviceListFetched(_converse, contact_jid));
iq_stanza = await u.waitUntil(() => deviceListFetched(_converse, contact_jid));
expect(Strophe.serialize(iq_stanza)).toBe(
`<iq from="romeo@montague.lit" id="${iq_stanza.getAttribute("id")}" to="${contact_jid}" type="get" xmlns="jabber:client">`+
`<pubsub xmlns="http://jabber.org/protocol/pubsub">`+
@ -1219,7 +1219,7 @@
.c('device', {'id': 'ae890ac52d0df67ed7cfdf51b644e901'});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
devicelist = _converse.devicelists.get(contact_jid);
await test_utils.waitUntil(() => devicelist.devices.length);
await u.waitUntil(() => devicelist.devices.length);
expect(_converse.devicelists.length).toBe(2);
devicelist = _converse.devicelists.get(contact_jid);
expect(devicelist.devices.length).toBe(4);
@ -1227,7 +1227,7 @@
expect(devicelist.devices.at(1).get('id')).toBe('3300659945416e274474e469a1f0154c');
expect(devicelist.devices.at(2).get('id')).toBe('4e30f35051b7b8b42abe083742187228');
expect(devicelist.devices.at(3).get('id')).toBe('ae890ac52d0df67ed7cfdf51b644e901');
await test_utils.waitUntil(() => _converse.chatboxviews.get(contact_jid).el.querySelector('.chat-toolbar'));
await u.waitUntil(() => _converse.chatboxviews.get(contact_jid).el.querySelector('.chat-toolbar'));
const view = _converse.chatboxviews.get(contact_jid);
const toolbar = view.el.querySelector('.chat-toolbar');
expect(view.model.get('omemo_active')).toBe(undefined);
@ -1242,7 +1242,7 @@
expect(view.toggleOMEMO).toHaveBeenCalled();
expect(view.model.get('omemo_active')).toBe(true);
await test_utils.waitUntil(() => u.hasClass('fa-lock', toolbar.querySelector('.toggle-omemo')));
await u.waitUntil(() => u.hasClass('fa-lock', toolbar.querySelector('.toggle-omemo')));
toggle = toolbar.querySelector('.toggle-omemo');
expect(u.hasClass('fa-unlock', toggle)).toBe(false);
expect(u.hasClass('fa-lock', toggle)).toBe(true);
@ -1293,7 +1293,7 @@
];
await test_utils.openAndEnterChatRoom(_converse, 'lounge@montague.lit', 'romeo', features);
const view = _converse.chatboxviews.get('lounge@montague.lit');
await test_utils.waitUntil(() => initializedOMEMO(_converse));
await u.waitUntil(() => initializedOMEMO(_converse));
const toolbar = view.el.querySelector('.chat-toolbar');
let toggle = toolbar.querySelector('.toggle-omemo');
@ -1325,7 +1325,7 @@
}).tree();
_converse.connection._dataRecv(test_utils.createRequest(stanza));
let iq_stanza = await test_utils.waitUntil(() => deviceListFetched(_converse, contact_jid));
let iq_stanza = await u.waitUntil(() => deviceListFetched(_converse, contact_jid));
expect(Strophe.serialize(iq_stanza)).toBe(
`<iq from="romeo@montague.lit" id="${iq_stanza.getAttribute("id")}" to="${contact_jid}" type="get" xmlns="jabber:client">`+
`<pubsub xmlns="http://jabber.org/protocol/pubsub">`+
@ -1345,10 +1345,10 @@
.c('device', {'id': '4e30f35051b7b8b42abe083742187228'}).up()
.c('device', {'id': 'ae890ac52d0df67ed7cfdf51b644e901'});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => _converse.omemo_store);
await u.waitUntil(() => _converse.omemo_store);
expect(_converse.devicelists.length).toBe(2);
await test_utils.waitUntil(() => deviceListFetched(_converse, contact_jid));
await u.waitUntil(() => deviceListFetched(_converse, contact_jid));
const devicelist = _converse.devicelists.get(contact_jid);
expect(devicelist.devices.length).toBe(2);
expect(devicelist.devices.at(0).get('id')).toBe('4e30f35051b7b8b42abe083742187228');
@ -1365,13 +1365,13 @@
// Test that the button gets disabled when the room becomes
// anonymous or semi-anonymous
view.model.features.save({'nonanonymous': false, 'semianonymous': true});
await test_utils.waitUntil(() => !view.model.get('omemo_supported'));
await u.waitUntil(() => !view.model.get('omemo_supported'));
toggle = toolbar.querySelector('.toggle-omemo');
expect(_.isNull(toggle)).toBe(true);
expect(view.model.get('omemo_supported')).toBe(false);
view.model.features.save({'nonanonymous': true, 'semianonymous': false});
await test_utils.waitUntil(() => view.model.get('omemo_supported'));
await u.waitUntil(() => view.model.get('omemo_supported'));
toggle = toolbar.querySelector('.toggle-omemo');
expect(_.isNull(toggle)).toBe(false);
expect(u.hasClass('fa-unlock', toggle)).toBe(true);
@ -1380,12 +1380,12 @@
// Test that the button gets disabled when the room becomes open
view.model.features.save({'membersonly': false, 'open': true});
await test_utils.waitUntil(() => !view.model.get('omemo_supported'));
await u.waitUntil(() => !view.model.get('omemo_supported'));
toggle = toolbar.querySelector('.toggle-omemo');
expect(_.isNull(toggle)).toBe(true);
view.model.features.save({'membersonly': true, 'open': false});
await test_utils.waitUntil(() => view.model.get('omemo_supported'));
await u.waitUntil(() => view.model.get('omemo_supported'));
toggle = toolbar.querySelector('.toggle-omemo');
expect(_.isNull(toggle)).toBe(false);
expect(u.hasClass('fa-unlock', toggle)).toBe(true);
@ -1411,7 +1411,7 @@
'role': 'participant'
}).tree();
_converse.connection._dataRecv(test_utils.createRequest(stanza));
iq_stanza = await test_utils.waitUntil(() => deviceListFetched(_converse, contact_jid));
iq_stanza = await u.waitUntil(() => deviceListFetched(_converse, contact_jid));
expect(Strophe.serialize(iq_stanza)).toBe(
`<iq from="romeo@montague.lit" id="${iq_stanza.getAttribute("id")}" to="${contact_jid}" type="get" xmlns="jabber:client">`+
`<pubsub xmlns="http://jabber.org/protocol/pubsub">`+
@ -1428,7 +1428,7 @@
.c('item-not-found', {'xmlns': "urn:ietf:params:xml:ns:xmpp-stanzas"});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => !view.model.get('omemo_supported'));
await u.waitUntil(() => !view.model.get('omemo_supported'));
expect(view.el.querySelector('.chat-error').textContent).toBe(
"oldguy doesn't appear to have a client that supports OMEMO. "+
@ -1473,8 +1473,8 @@
const show_modal_button = view.el.querySelector('.show-user-details-modal');
show_modal_button.click();
const modal = view.user_details_modal;
await test_utils.waitUntil(() => u.isVisible(modal.el), 1000);
let iq_stanza = await test_utils.waitUntil(() => deviceListFetched(_converse, contact_jid));
await u.waitUntil(() => u.isVisible(modal.el), 1000);
let iq_stanza = await u.waitUntil(() => deviceListFetched(_converse, contact_jid));
expect(Strophe.serialize(iq_stanza)).toBe(
`<iq from="romeo@montague.lit" id="${iq_stanza.getAttribute("id")}" to="mercutio@montague.lit" type="get" xmlns="jabber:client">`+
`<pubsub xmlns="http://jabber.org/protocol/pubsub"><items node="eu.siacs.conversations.axolotl.devicelist"/></pubsub>`+
@ -1490,8 +1490,8 @@
.c('list', {'xmlns': "eu.siacs.conversations.axolotl"})
.c('device', {'id': '555'});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => u.isVisible(modal.el), 1000);
iq_stanza = await test_utils.waitUntil(() => bundleFetched(_converse, contact_jid, '555'));
await u.waitUntil(() => u.isVisible(modal.el), 1000);
iq_stanza = await u.waitUntil(() => bundleFetched(_converse, contact_jid, '555'));
expect(Strophe.serialize(iq_stanza)).toBe(
`<iq from="romeo@montague.lit" id="${iq_stanza.getAttribute("id")}" to="mercutio@montague.lit" type="get" xmlns="jabber:client">`+
`<pubsub xmlns="http://jabber.org/protocol/pubsub">`+
@ -1517,7 +1517,7 @@
.c('preKeyPublic', {'preKeyId': '3'}).t(btoa('1003'));
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => modal.el.querySelectorAll('.fingerprints .fingerprint').length);
await u.waitUntil(() => modal.el.querySelectorAll('.fingerprints .fingerprint').length);
expect(modal.el.querySelectorAll('.fingerprints .fingerprint').length).toBe(1);
const el = modal.el.querySelector('.fingerprints .fingerprint');
expect(el.textContent.trim()).toBe(

View File

@ -86,7 +86,7 @@
const cbview = _converse.chatboxviews.get('controlbox');
cbview.el.querySelector('.change-status').click()
const modal = _converse.xmppstatusview.status_modal;
await test_utils.waitUntil(() => u.isVisible(modal.el), 1000);
await u.waitUntil(() => u.isVisible(modal.el), 1000);
const msg = 'My custom status';
modal.el.querySelector('input[name="status_message"]').value = msg;
modal.el.querySelector('[type="submit"]').click();
@ -98,9 +98,9 @@
`<c hash="sha-1" node="https://conversejs.org" ver="Hxbsr5fazs62i+O0GxIXf2OEDNs=" xmlns="http://jabber.org/protocol/caps"/>`+
`</presence>`)
await test_utils.waitUntil(() => modal.el.getAttribute('aria-hidden') === "true");
await u.waitUntil(() => modal.el.getAttribute('aria-hidden') === "true");
cbview.el.querySelector('.change-status').click()
await test_utils.waitUntil(() => modal.el.getAttribute('aria-hidden') === "false", 1000);
await u.waitUntil(() => modal.el.getAttribute('aria-hidden') === "false", 1000);
modal.el.querySelector('label[for="radio-busy"]').click(); // Change status to "dnd"
modal.el.querySelector('[type="submit"]').click();
expect(_converse.connection.send.calls.mostRecent().args[0].toLocaleString())

View File

@ -64,7 +64,7 @@
});
_converse.roster.onReceivedFromServer(stanza.tree());
return test_utils.waitUntil(function () {
return u.waitUntil(function () {
var $group = _converse.rosterview.$el.find('.roster-group')
return $group.length && u.isVisible($group[0]);
}).then(function () {
@ -75,7 +75,7 @@
count += 1;
}
});
return test_utils.waitUntil(function () {
return u.waitUntil(function () {
return _converse.rosterview.$el.find('li.online').length
})
}).then(done);
@ -109,7 +109,7 @@
});
_converse.roster.onReceivedFromServer(stanza.tree());
return test_utils.waitUntil(function () {
return u.waitUntil(function () {
var $group = _converse.rosterview.$el.find('.roster-group')
return $group.length && u.isVisible($group[0]);
}).then(function () {
@ -124,7 +124,7 @@
}
});
});
return test_utils.waitUntil(function () {
return u.waitUntil(function () {
return _converse.rosterview.$el.find('li.online').length
})
}).then(done);

View File

@ -56,7 +56,7 @@
let contact, sent_stanza, IQ_id, stanza;
await test_utils.waitUntilDiscoConfirmed(_converse, 'montague.lit', [], ['vcard-temp']);
await test_utils.waitUntil(() => _converse.xmppstatus.vcard.get('fullname'), 300);
await u.waitUntil(() => _converse.xmppstatus.vcard.get('fullname'), 300);
/* The process by which a user subscribes to a contact, including
* the interaction between roster items and subscription states.
*/
@ -76,7 +76,7 @@
cbview.el.querySelector('.add-contact').click()
const modal = _converse.rosterview.add_contact_modal;
await test_utils.waitUntil(() => u.isVisible(modal.el), 1000);
await u.waitUntil(() => u.isVisible(modal.el), 1000);
spyOn(modal, "addContactFromForm").and.callThrough();
modal.delegateEvents();
@ -160,7 +160,7 @@
stanza = $iq({'type': 'result', 'id':IQ_id});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => _converse.roster.create.calls.count());
await u.waitUntil(() => _converse.roster.create.calls.count());
// A contact should now have been created
expect(_converse.roster.get('contact@example.org') instanceof _converse.RosterContact).toBeTruthy();
@ -173,7 +173,7 @@
*
* <presence to='contact@example.org' type='subscribe'/>
*/
const sent_presence = await test_utils.waitUntil(() => sent_stanzas.filter(s => s.match('presence')).pop());
const sent_presence = await u.waitUntil(() => sent_stanzas.filter(s => s.match('presence')).pop());
expect(contact.subscribe).toHaveBeenCalled();
expect(sent_presence).toBe( // Strophe adds the xmlns attr (although not in spec)
`<presence to="contact@example.org" type="subscribe" xmlns="jabber:client">`+
@ -211,7 +211,7 @@
expect(_converse.roster.updateContact).toHaveBeenCalled();
// Check that the user is now properly shown as a pending
// contact in the roster.
await test_utils.waitUntil(() => {
await u.waitUntil(() => {
const header = sizzle('a:contains("Pending contacts")', _converse.rosterview.el).pop();
const contacts = _.filter(header.parentElement.querySelectorAll('li'), u.isVisible);
return contacts.length;
@ -280,7 +280,7 @@
// The contact should now be visible as an existing
// contact (but still offline).
await test_utils.waitUntil(() => {
await u.waitUntil(() => {
const header = sizzle('a:contains("My contacts")', _converse.rosterview.el);
return sizzle('li', header[0].parentNode).filter(l => u.isVisible(l)).length;
}, 600);
@ -471,7 +471,7 @@
IQ_id = sendIQ.bind(this)(iq, callback, errback);
});
const header = sizzle('a:contains("My contacts")', _converse.rosterview.el).pop();
await test_utils.waitUntil(() => header.parentElement.querySelectorAll('li').length);
await u.waitUntil(() => header.parentElement.querySelectorAll('li').length);
// remove the first user
header.parentElement.querySelector('li .remove-xmpp-contact').click();
@ -508,7 +508,7 @@
const stanza = $iq({'type': 'result', 'id':IQ_id});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
// Our contact has now been removed
await test_utils.waitUntil(() => typeof _converse.roster.get(jid) === "undefined");
await u.waitUntil(() => typeof _converse.roster.get(jid) === "undefined");
done();
}));
@ -533,7 +533,7 @@
'xmlns': Strophe.NS.NICK,
}).t('Clint Contact');
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => {
await u.waitUntil(() => {
const header = sizzle('a:contains("Contact requests")', _converse.rosterview.el).pop();
const contacts = _.filter(header.parentElement.querySelectorAll('li'), u.isVisible);
return contacts.length;

View File

@ -31,7 +31,7 @@
_converse.bare_jid,
[{'category': 'account', 'type':'registered'}],
['urn:xmpp:push:0'], [], 'info');
const stanza = await test_utils.waitUntil(() =>
const stanza = await u.waitUntil(() =>
_.filter(IQ_stanzas, iq => iq.querySelector('iq[type="set"] enable[xmlns="urn:xmpp:push:0"]')).pop()
);
expect(Strophe.serialize(stanza)).toEqual(
@ -44,7 +44,7 @@
'type': 'result',
'id': stanza.getAttribute('id')
})));
await test_utils.waitUntil(() => _converse.session.get('push_enabled'));
await u.waitUntil(() => _converse.session.get('push_enabled'));
done();
}));
@ -68,7 +68,7 @@
_converse, _converse.bare_jid, [],
['urn:xmpp:push:0']);
let iq = await test_utils.waitUntil(() => _.filter(
let iq = await u.waitUntil(() => _.filter(
IQ_stanzas,
iq => sizzle(`iq[type="set"] enable[xmlns="${Strophe.NS.PUSH}"]`, iq).length
).pop());
@ -81,7 +81,7 @@
const result = u.toStanza(`<iq type="result" id="${iq.getAttribute('id')}" to="romeo@montague.lit" />`);
_converse.connection._dataRecv(test_utils.createRequest(result));
await test_utils.waitUntil(() => _converse.session.get('push_enabled'));
await u.waitUntil(() => _converse.session.get('push_enabled'));
expect(_converse.session.get('push_enabled').length).toBe(1);
expect(_.includes(_converse.session.get('push_enabled'), 'romeo@montague.lit')).toBe(true);
@ -90,7 +90,7 @@
_converse, 'chat.shakespeare.lit',
[{'category': 'account', 'type':'registered'}],
['urn:xmpp:push:0'], [], 'info');
iq = await test_utils.waitUntil(() => _.filter(
iq = await u.waitUntil(() => _.filter(
IQ_stanzas,
iq => sizzle(`iq[type="set"][to="chat.shakespeare.lit"] enable[xmlns="${Strophe.NS.PUSH}"]`, iq).length
).pop());
@ -105,7 +105,7 @@
'type': 'result',
'id': iq.getAttribute('id')
})));
await test_utils.waitUntil(() => _.includes(_converse.session.get('push_enabled'), 'chat.shakespeare.lit'));
await u.waitUntil(() => _.includes(_converse.session.get('push_enabled'), 'chat.shakespeare.lit'));
done();
}));
@ -127,7 +127,7 @@
_converse.bare_jid,
[{'category': 'account', 'type':'registered'}],
['urn:xmpp:push:0'], [], 'info');
const stanza = await test_utils.waitUntil(
const stanza = await u.waitUntil(
() => _.filter(IQ_stanzas, iq => iq.querySelector('iq[type="set"] disable[xmlns="urn:xmpp:push:0"]')).pop()
);
expect(Strophe.serialize(stanza)).toEqual(
@ -140,7 +140,7 @@
'type': 'result',
'id': stanza.getAttribute('id')
})));
await test_utils.waitUntil(() => _converse.session.get('push_enabled'))
await u.waitUntil(() => _converse.session.get('push_enabled'))
done();
}));
@ -168,7 +168,7 @@
[{'category': 'account', 'type':'registered'}],
['urn:xmpp:push:0'], [], 'info');
const stanza = await test_utils.waitUntil(
const stanza = await u.waitUntil(
() => _.filter(IQ_stanzas, iq => iq.querySelector('iq[type="set"] enable[xmlns="urn:xmpp:push:0"]')).pop()
);
expect(Strophe.serialize(stanza)).toEqual(
@ -186,7 +186,7 @@
'type': 'result',
'id': stanza.getAttribute('id')
})));
await test_utils.waitUntil(() => _converse.session.get('push_enabled'))
await u.waitUntil(() => _converse.session.get('push_enabled'))
done();
}));
});

View File

@ -15,7 +15,7 @@
allow_registration: false },
async function (done, _converse) {
await test_utils.waitUntil(() => _converse.chatboxviews.get('controlbox'));
await u.waitUntil(() => _converse.chatboxviews.get('controlbox'));
test_utils.openControlBox();
const cbview = _converse.chatboxviews.get('controlbox');
expect(cbview.el.querySelectorAll('a.register-account').length).toBe(0);
@ -29,7 +29,7 @@
allow_registration: true },
async function (done, _converse) {
await test_utils.waitUntil(() => _.get(_converse.chatboxviews.get('controlbox'), 'registerpanel'), 300);
await u.waitUntil(() => _.get(_converse.chatboxviews.get('controlbox'), 'registerpanel'), 300);
const cbview = _converse.chatboxviews.get('controlbox');
test_utils.openControlBox();
const panels = cbview.el.querySelector('.controlbox-panes');
@ -38,7 +38,7 @@
const register_link = cbview.el.querySelector('a.register-account');
expect(register_link.textContent).toBe("Create an account");
register_link.click();
await test_utils.waitUntil(() => u.isVisible(registration));
await u.waitUntil(() => u.isVisible(registration));
expect(u.isVisible(login)).toBe(false);
done();
}));
@ -50,7 +50,7 @@
allow_registration: true },
async function (done, _converse) {
await test_utils.waitUntil(() => _.get(_converse.chatboxviews.get('controlbox'), 'registerpanel'));
await u.waitUntil(() => _.get(_converse.chatboxviews.get('controlbox'), 'registerpanel'));
test_utils.openControlBox();
const cbview = _converse.chatboxviews.get('controlbox');
const registerview = cbview.registerpanel;
@ -86,7 +86,7 @@
allow_registration: true },
async function (done, _converse) {
await test_utils.waitUntil(() => _.get(_converse.chatboxviews.get('controlbox'), 'registerpanel'));
await u.waitUntil(() => _.get(_converse.chatboxviews.get('controlbox'), 'registerpanel'));
test_utils.openControlBox();
const cbview = _converse.chatboxviews.get('controlbox');
cbview.el.querySelector('.toggle-register-login').click();
@ -142,7 +142,7 @@
allow_registration: true },
async function (done, _converse) {
await test_utils.waitUntil(() => _.get(_converse.chatboxviews.get('controlbox'), 'registerpanel'));
await u.waitUntil(() => _.get(_converse.chatboxviews.get('controlbox'), 'registerpanel'));
test_utils.openControlBox();
const cbview = _converse.chatboxviews.get('controlbox');
cbview.el.querySelector('.toggle-register-login').click();
@ -199,7 +199,7 @@
allow_registration: true },
async function (done, _converse) {
await test_utils.waitUntil(() => _.get(_converse.chatboxviews.get('controlbox'), 'registerpanel'));
await u.waitUntil(() => _.get(_converse.chatboxviews.get('controlbox'), 'registerpanel'));
test_utils.openControlBox();
const cbview = _converse.chatboxviews.get('controlbox');
cbview.el.querySelector('.toggle-register-login').click();
@ -273,7 +273,7 @@
allow_registration: true },
async function (done, _converse) {
await test_utils.waitUntil(() => _.get(_converse.chatboxviews.get('controlbox'), 'registerpanel'));
await u.waitUntil(() => _.get(_converse.chatboxviews.get('controlbox'), 'registerpanel'));
test_utils.openControlBox();
const cbview = _converse.chatboxviews.get('controlbox');
cbview.el.querySelector('.toggle-register-login').click();

View File

@ -27,7 +27,7 @@
preventDefault: _.noop,
keyCode: 13
});
let stanza = await test_utils.waitUntil(() => _.filter(
let stanza = await u.waitUntil(() => _.filter(
_converse.connection.IQ_stanzas,
iq => sizzle(`iq[to="${muc_jid}"][type="get"] query[xmlns="jabber:iq:register"]`, iq).length
).pop());
@ -48,7 +48,7 @@
'var': 'muc#register_roomnick'
}).c('required');
_converse.connection._dataRecv(test_utils.createRequest(result));
stanza = await test_utils.waitUntil(() => _.filter(
stanza = await u.waitUntil(() => _.filter(
_converse.connection.IQ_stanzas,
iq => sizzle(`iq[to="${muc_jid}"][type="set"] query[xmlns="jabber:iq:register"]`, iq).length
).pop());
@ -79,7 +79,7 @@
await test_utils.openAndEnterChatRoom(_converse, muc_jid, 'romeo');
const view = _converse.chatboxviews.get(muc_jid);
let stanza = await test_utils.waitUntil(() => _.filter(
let stanza = await u.waitUntil(() => _.filter(
_converse.connection.IQ_stanzas,
iq => sizzle(`iq[to="coven@chat.shakespeare.lit"][type="get"] query[xmlns="jabber:iq:register"]`, iq).length
).pop());
@ -101,7 +101,7 @@
'var': 'muc#register_roomnick'
}).c('required');
_converse.connection._dataRecv(test_utils.createRequest(result));
stanza = await test_utils.waitUntil(() => _.filter(
stanza = await u.waitUntil(() => _.filter(
_converse.connection.IQ_stanzas,
iq => sizzle(`iq[to="coven@chat.shakespeare.lit"][type="set"] query[xmlns="jabber:iq:register"]`, iq).length
).pop());

View File

@ -10,7 +10,7 @@
it("is shown in controlbox", mock.initConverse(
null, ['rosterGroupsFetched', 'chatBoxesFetched'],
{ allow_bookmarks: false // Makes testing easier, otherwise we
// have to mock stanza traffic.
// have to mock stanza traffic.
}, async function (done, _converse) {
test_utils.openControlBox();
@ -22,13 +22,13 @@
expect(_.isUndefined(_converse.rooms_list_view)).toBeFalsy();
const lview = _converse.rooms_list_view
await test_utils.waitUntil(() => lview.el.querySelectorAll(".open-room").length);
await u.waitUntil(() => lview.el.querySelectorAll(".open-room").length);
let room_els = lview.el.querySelectorAll(".open-room");
expect(room_els.length).toBe(1);
expect(room_els[0].innerText).toBe('room@conference.shakespeare.lit');
await test_utils.openChatRoom(_converse, 'lounge', 'montague.lit', 'romeo');
await test_utils.waitUntil(() => lview.el.querySelectorAll(".open-room").length > 1);
await u.waitUntil(() => lview.el.querySelectorAll(".open-room").length > 1);
room_els = _converse.rooms_list_view.el.querySelectorAll(".open-room");
expect(room_els.length).toBe(2);
@ -38,7 +38,7 @@
expect(room_els.length).toBe(1);
expect(room_els[0].innerText).toBe('lounge@montague.lit');
list = controlbox.el.querySelector('div.rooms-list-container');
test_utils.waitUntil(() => _.includes(list.classList, 'hidden'));
u.waitUntil(() => _.includes(list.classList, 'hidden'));
view = _converse.chatboxviews.get('lounge@montague.lit');
view.close();
@ -80,7 +80,7 @@
[`${Strophe.NS.PUBSUB}#publish-options`]
);
const call = await test_utils.waitUntil(() =>
const call = await u.waitUntil(() =>
_.filter(
_converse.connection.send.calls.all(),
c => sizzle('items[node="storage:bookmarks"]', c.args[0]).length
@ -119,24 +119,22 @@
describe("A groupchat shown in the groupchats list", function () {
it("is highlighted if its currently open", mock.initConverse(
null, ['rosterGroupsFetched', 'chatBoxesFetched'],
null, ['rosterGroupsFetched', 'chatBoxesFetched', 'emojisInitialized'],
{ view_mode: 'fullscreen',
allow_bookmarks: false // Makes testing easier, otherwise we have to mock stanza traffic.
}, async function (done, _converse) {
let item;
await _converse.api.rooms.open('coven@chat.shakespeare.lit', {'nick': 'some1'});
const lview = _converse.rooms_list_view
await test_utils.waitUntil(() => lview.el.querySelectorAll(".open-room").length);
await u.waitUntil(() => lview.el.querySelectorAll(".open-room").length);
let room_els = lview.el.querySelectorAll(".available-chatroom");
expect(room_els.length).toBe(1);
item = room_els[0];
let item = room_els[0];
expect(u.hasClass('open', item)).toBe(true);
expect(item.textContent.trim()).toBe('coven@chat.shakespeare.lit');
await _converse.api.rooms.open('balcony@chat.shakespeare.lit', {'nick': 'some1'});
await test_utils.waitUntil(() => lview.el.querySelectorAll(".open-room").length > 1);
await u.waitUntil(() => lview.el.querySelectorAll(".open-room").length > 1);
room_els = lview.el.querySelectorAll(".open-room");
expect(room_els.length).toBe(2);
@ -160,7 +158,7 @@
const room_jid = 'coven@chat.shakespeare.lit';
test_utils.openControlBox();
await _converse.api.rooms.open(room_jid, {'nick': 'some1'});
const last_stanza = await test_utils.waitUntil(() => _.filter(
const last_stanza = await u.waitUntil(() => _.filter(
IQ_stanzas,
iq => iq.querySelector(
`iq[to="${room_jid}"] query[xmlns="http://jabber.org/protocol/disco#info"]`
@ -195,7 +193,7 @@
.c('field', {'type':'text-single', 'var':'muc#roominfo_occupants', 'label':'Number of occupants'})
.c('value').t(0);
_converse.connection._dataRecv(test_utils.createRequest(features_stanza));
await test_utils.waitUntil(() => view.model.get('connection_status') === converse.ROOMSTATUS.CONNECTING)
await u.waitUntil(() => view.model.get('connection_status') === converse.ROOMSTATUS.CONNECTING)
let presence = $pres({
to: _converse.connection.jid,
from: 'coven@chat.shakespeare.lit/some1',
@ -209,14 +207,14 @@
.c('status').attrs({code:'110'});
_converse.connection._dataRecv(test_utils.createRequest(presence));
await test_utils.waitUntil(() => _converse.rooms_list_view.el.querySelectorAll(".open-room").length, 500);
await u.waitUntil(() => _converse.rooms_list_view.el.querySelectorAll(".open-room").length, 500);
const room_els = _converse.rooms_list_view.el.querySelectorAll(".open-room");
expect(room_els.length).toBe(1);
const info_el = _converse.rooms_list_view.el.querySelector(".room-info");
info_el.click();
const modal = view.model.room_details_modal;
await test_utils.waitUntil(() => u.isVisible(modal.el), 1000);
await u.waitUntil(() => u.isVisible(modal.el), 1000);
let els = modal.el.querySelectorAll('p.room-info');
expect(els[0].textContent).toBe("Name: A Dark Cave")
expect(els[1].textContent).toBe("Groupchat address (JID): coven@chat.shakespeare.lit")
@ -269,7 +267,7 @@
await test_utils.openChatRoom(_converse, 'lounge', 'conference.shakespeare.lit', 'JC');
expect(_converse.chatboxes.length).toBe(2);
const lview = _converse.rooms_list_view
await test_utils.waitUntil(() => lview.el.querySelectorAll(".open-room").length);
await u.waitUntil(() => lview.el.querySelectorAll(".open-room").length);
let room_els = lview.el.querySelectorAll(".open-room");
expect(room_els.length).toBe(1);
const close_el = _converse.rooms_list_view.el.querySelector(".close-room");
@ -290,7 +288,7 @@
test_utils.openControlBox();
const room_jid = 'kitchen@conference.shakespeare.lit';
await test_utils.waitUntil(() => !_.isUndefined(_converse.rooms_list_view), 500);
await u.waitUntil(() => !_.isUndefined(_converse.rooms_list_view), 500);
await test_utils.openAndEnterChatRoom(_converse, 'kitchen@conference.shakespeare.lit', 'romeo');
const view = _converse.chatboxviews.get(room_jid);
view.model.set({'minimized': true});
@ -305,7 +303,7 @@
}).c('body').t('foo').tree());
const lview = _converse.rooms_list_view
await test_utils.waitUntil(() => lview.el.querySelectorAll(".available-chatroom").length, 500);
await u.waitUntil(() => lview.el.querySelectorAll(".available-chatroom").length, 500);
// If the user isn't mentioned, the counter doesn't get incremented, but the text of the groupchat is bold
let room_el = lview.el.querySelector(".available-chatroom");
@ -320,7 +318,7 @@
type: 'groupchat'
}).c('body').t('romeo: Your attention is required').tree()
);
await test_utils.waitUntil(() => _converse.rooms_list_view.el.querySelectorAll(".msgs-indicator").length);
await u.waitUntil(() => _converse.rooms_list_view.el.querySelectorAll(".msgs-indicator").length);
spyOn(view.model, 'incrementUnreadMsgCounter').and.callThrough();
let indicator_el = _converse.rooms_list_view.el.querySelector(".msgs-indicator");
expect(indicator_el.textContent).toBe('1');
@ -332,7 +330,7 @@
type: 'groupchat'
}).c('body').t('romeo: and another thing...').tree()
);
await test_utils.waitUntil(() => view.model.incrementUnreadMsgCounter.calls.count());
await u.waitUntil(() => view.model.incrementUnreadMsgCounter.calls.count());
indicator_el = _converse.rooms_list_view.el.querySelector(".msgs-indicator");
expect(indicator_el.textContent).toBe('2');

View File

@ -9,7 +9,6 @@
const sizzle = converse.env.sizzle;
const u = converse.env.utils;
const checkHeaderToggling = async function (group) {
const toggle = group.querySelector('a.group-toggle');
expect(u.isVisible(group)).toBeTruthy();
@ -18,11 +17,11 @@
expect(u.hasClass('fa-caret-down', toggle.firstElementChild)).toBeTruthy();
toggle.click();
await test_utils.waitUntil(() => group.querySelectorAll('ul.collapsed').length === 1);
await u.waitUntil(() => group.querySelectorAll('ul.collapsed').length === 1);
expect(u.hasClass('fa-caret-right', toggle.firstElementChild)).toBeTruthy();
expect(u.hasClass('fa-caret-down', toggle.firstElementChild)).toBeFalsy();
toggle.click();
await test_utils.waitUntil(() => group.querySelectorAll('li').length === _.filter(group.querySelectorAll('li'), u.isVisible).length);
await u.waitUntil(() => group.querySelectorAll('li').length === _.filter(group.querySelectorAll('li'), u.isVisible).length);
expect(u.hasClass('fa-caret-right', toggle.firstElementChild)).toBeFalsy();
expect(u.hasClass('fa-caret-down', toggle.firstElementChild)).toBeTruthy();
};
@ -37,7 +36,7 @@
spyOn(_converse.api, "trigger").and.callThrough();
const IQs = _converse.connection.IQ_stanzas;
const stanza = await test_utils.waitUntil(
const stanza = await u.waitUntil(
() => _.filter(IQs, iq => iq.querySelector('iq query[xmlns="jabber:iq:roster"]')).pop());
expect(_converse.api.trigger.calls.all().map(c => c.args[0]).includes('rosterContactsFetched')).toBeFalsy();
@ -54,7 +53,7 @@
}).c('item', {'jid': 'nurse@example.com'}).up()
.c('item', {'jid': 'romeo@example.com'})
_converse.connection._dataRecv(test_utils.createRequest(result));
await test_utils.waitUntil(() => _converse.api.trigger.calls.all().map(c => c.args[0]).includes('rosterContactsFetched'));
await u.waitUntil(() => _converse.api.trigger.calls.all().map(c => c.args[0]).includes('rosterContactsFetched'));
done();
}));
@ -64,7 +63,7 @@
async function (done, _converse) {
const IQ_stanzas = _converse.connection.IQ_stanzas;
let stanza = await test_utils.waitUntil(
let stanza = await u.waitUntil(
() => _.filter(IQ_stanzas, iq => iq.querySelector('iq query[xmlns="jabber:iq:roster"]')).pop()
);
expect(_converse.roster.data.get('version')).toBeUndefined();
@ -83,7 +82,7 @@
.c('item', {'jid': 'romeo@example.com'})
_converse.connection._dataRecv(test_utils.createRequest(result));
await test_utils.waitUntil(() => _converse.roster.models.length > 1);
await u.waitUntil(() => _converse.roster.models.length > 1);
expect(_converse.roster.data.get('version')).toBe('ver7');
expect(_converse.roster.models.length).toBe(2);
@ -132,7 +131,7 @@
return el.isConnected && flyout.offsetHeight < panel.scrollHeight;
}
const el = _converse.rosterview.roster_el;
await test_utils.waitUntil(() => hasScrollBar(el) ? u.isVisible(filter) : !u.isVisible(filter), 900);
await u.waitUntil(() => hasScrollBar(el) ? u.isVisible(filter) : !u.isVisible(filter), 900);
done();
}));
@ -147,11 +146,11 @@
const roster = _converse.rosterview.roster_el;
_converse.rosterview.filter_view.delegateEvents();
const contacts = await test_utils.waitUntil(() => (sizzle('li', roster).filter(u.isVisible).length === 15), 600);
const contacts = await u.waitUntil(() => (sizzle('li', roster).filter(u.isVisible).length === 15), 600);
expect(sizzle('ul.roster-group-contacts', roster).filter(u.isVisible).length).toBe(5);
filter.value = "juliet";
u.triggerEvent(filter, "keydown", "KeyboardEvent");
await test_utils.waitUntil(() => (sizzle('li', roster).filter(u.isVisible).length === 1), 600);
await u.waitUntil(() => (sizzle('li', roster).filter(u.isVisible).length === 1), 600);
// Only one roster contact is now visible
let visible_contacts = sizzle('li', roster).filter(u.isVisible);
expect(visible_contacts.length).toBe(1);
@ -164,7 +163,7 @@
filter = _converse.rosterview.el.querySelector('.roster-filter');
filter.value = "j";
u.triggerEvent(filter, "keydown", "KeyboardEvent");
await test_utils.waitUntil(() => (sizzle('li', roster).filter(u.isVisible).length === 2), 700);
await u.waitUntil(() => (sizzle('li', roster).filter(u.isVisible).length === 2), 700);
visible_contacts = sizzle('li', roster).filter(u.isVisible);
expect(visible_contacts.length).toBe(2);
@ -177,14 +176,14 @@
filter = _converse.rosterview.el.querySelector('.roster-filter');
filter.value = "xxx";
u.triggerEvent(filter, "keydown", "KeyboardEvent");
await test_utils.waitUntil(() => (sizzle('li', roster).filter(u.isVisible).length === 0), 600);
await u.waitUntil(() => (sizzle('li', roster).filter(u.isVisible).length === 0), 600);
visible_groups = sizzle('.roster-group', roster).filter(u.isVisible).map(el => el.querySelector('a.group-toggle'));
expect(visible_groups.length).toBe(0);
filter = _converse.rosterview.el.querySelector('.roster-filter');
filter.value = "";
u.triggerEvent(filter, "keydown", "KeyboardEvent");
await test_utils.waitUntil(() => (sizzle('li', roster).filter(u.isVisible).length === 15), 600);
await u.waitUntil(() => (sizzle('li', roster).filter(u.isVisible).length === 15), 600);
expect(sizzle('ul.roster-group-contacts', roster).filter(u.isVisible).length).toBe(5);
done();
}));
@ -201,10 +200,10 @@
const roster = _converse.rosterview.roster_el;
_converse.rosterview.filter_view.delegateEvents();
await test_utils.waitUntil(() => (sizzle('li', roster).filter(u.isVisible).length === 15), 600);
await u.waitUntil(() => (sizzle('li', roster).filter(u.isVisible).length === 15), 600);
filter.value = "la";
u.triggerEvent(filter, "keydown", "KeyboardEvent");
await test_utils.waitUntil(() => (sizzle('li', roster).filter(u.isVisible).length === 3), 600);
await u.waitUntil(() => (sizzle('li', roster).filter(u.isVisible).length === 3), 600);
// Five roster contact is now visible
const visible_contacts = sizzle('li', roster).filter(u.isVisible);
@ -222,7 +221,7 @@
groups: ['newgroup'],
fullname: 'Valentine'
});
await test_utils.waitUntil(() => sizzle('.roster-group[data-group="newgroup"] li', roster).length, 300);
await u.waitUntil(() => sizzle('.roster-group[data-group="newgroup"] li', roster).length, 300);
visible_groups = sizzle('.roster-group', roster).filter(u.isVisible).map(el => el.querySelector('a.group-toggle'));
// The "newgroup" group doesn't appear
expect(visible_groups.length).toBe(3);
@ -246,14 +245,14 @@
var button = _converse.rosterview.el.querySelector('span[data-type="groups"]');
button.click();
const contacts = await test_utils.waitUntil(() => (sizzle('li', roster).filter(u.isVisible).length === 15), 600);
const contacts = await u.waitUntil(() => (sizzle('li', roster).filter(u.isVisible).length === 15), 600);
expect(sizzle('.roster-group', roster).filter(u.isVisible).length).toBe(5);
var filter = _converse.rosterview.el.querySelector('.roster-filter');
filter.value = "colleagues";
u.triggerEvent(filter, "keydown", "KeyboardEvent");
await test_utils.waitUntil(() => (sizzle('div.roster-group:not(.collapsed)', roster).length === 1), 600);
await u.waitUntil(() => (sizzle('div.roster-group:not(.collapsed)', roster).length === 1), 600);
expect(sizzle('div.roster-group:not(.collapsed)', roster).pop().firstElementChild.textContent.trim()).toBe('colleagues');
expect(sizzle('div.roster-group:not(.collapsed) li', roster).filter(u.isVisible).length).toBe(3);
// Check that all contacts under the group are shown
@ -263,13 +262,13 @@
filter.value = "xxx";
u.triggerEvent(filter, "keydown", "KeyboardEvent");
await test_utils.waitUntil(() => (roster.querySelectorAll('div.roster-group.collapsed').length === 5), 700);
await u.waitUntil(() => (roster.querySelectorAll('div.roster-group.collapsed').length === 5), 700);
expect(roster.querySelectorAll('div.roster-group:not(.collapsed) a').length).toBe(0);
filter = _converse.rosterview.el.querySelector('.roster-filter');
filter.value = ""; // Check that groups are shown again, when the filter string is cleared.
u.triggerEvent(filter, "keydown", "KeyboardEvent");
await test_utils.waitUntil(() => (roster.querySelectorAll('div.roster-group.collapsed').length === 0), 700);
await u.waitUntil(() => (roster.querySelectorAll('div.roster-group.collapsed').length === 0), 700);
expect(sizzle('div.roster-group:not(collapsed)', roster).length).toBe(5);
expect(sizzle('div.roster-group:not(collapsed) li', roster).length).toBe(15);
done();
@ -291,7 +290,7 @@
expect(u.hasClass('hidden', _converse.rosterview.el.querySelector('.roster-filter-form .clear-input'))).toBeTruthy();
const isHidden = _.partial(u.hasClass, 'hidden');
await test_utils.waitUntil(() => !isHidden(_converse.rosterview.el.querySelector('.roster-filter-form .clear-input')), 900);
await u.waitUntil(() => !isHidden(_converse.rosterview.el.querySelector('.roster-filter-form .clear-input')), 900);
_converse.rosterview.el.querySelector('.clear-input').click();
expect(document.querySelector('.roster-filter').value).toBe("");
done();
@ -313,20 +312,20 @@
const button = _converse.rosterview.el.querySelector('span[data-type="state"]');
button.click();
const roster = _converse.rosterview.roster_el;
await test_utils.waitUntil(() => sizzle('li', roster).filter(u.isVisible).length === 15, 900);
await u.waitUntil(() => sizzle('li', roster).filter(u.isVisible).length === 15, 900);
const filter = _converse.rosterview.el.querySelector('.state-type');
expect(sizzle('ul.roster-group-contacts', roster).filter(u.isVisible).length).toBe(5);
filter.value = "online";
u.triggerEvent(filter, 'change');
await test_utils.waitUntil(() => sizzle('li', roster).filter(u.isVisible).length === 1, 900);
await u.waitUntil(() => sizzle('li', roster).filter(u.isVisible).length === 1, 900);
expect(sizzle('li', roster).filter(u.isVisible).pop().textContent.trim()).toBe('Lord Montague');
await test_utils.waitUntil(() => sizzle('ul.roster-group-contacts', roster).filter(u.isVisible).length === 1, 900);
await u.waitUntil(() => sizzle('ul.roster-group-contacts', roster).filter(u.isVisible).length === 1, 900);
const ul = sizzle('ul.roster-group-contacts', roster).filter(u.isVisible).pop();
expect(ul.parentElement.firstElementChild.textContent.trim()).toBe('friends & acquaintences');
filter.value = "dnd";
u.triggerEvent(filter, 'change');
await test_utils.waitUntil(() => sizzle('li', roster).filter(u.isVisible).pop().textContent.trim() === 'Friar Laurence', 900);
await u.waitUntil(() => sizzle('li', roster).filter(u.isVisible).pop().textContent.trim() === 'Friar Laurence', 900);
expect(sizzle('ul.roster-group-contacts', roster).filter(u.isVisible).length).toBe(1);
done();
}));
@ -348,7 +347,7 @@
test_utils.createGroupedContacts(_converse);
// Check that the groups appear alphabetically and that
// requesting and pending contacts are last.
await test_utils.waitUntil(() => sizzle('.roster-group a.group-toggle', _converse.rosterview.el).length);
await u.waitUntil(() => sizzle('.roster-group a.group-toggle', _converse.rosterview.el).length);
const group_titles = _.map(
sizzle('.roster-group a.group-toggle', _converse.rosterview.el),
o => o.textContent.trim()
@ -393,7 +392,7 @@
// Check that the groups appear alphabetically and that
// requesting and pending contacts are last.
let group_titles = await test_utils.waitUntil(() => {
let group_titles = await u.waitUntil(() => {
const toggles = sizzle('.roster-group a.group-toggle', _converse.rosterview.el);
if (_.reduce(toggles, (result, t) => result && u.isVisible(t), true)) {
return _.map(toggles, o => o.textContent.trim());
@ -405,7 +404,7 @@
const contact = _converse.roster.get('groupchanger@montague.lit');
contact.set({'groups': ['secondgroup']});
group_titles = await test_utils.waitUntil(() => {
group_titles = await u.waitUntil(() => {
const toggles = sizzle('.roster-group[data-group="secondgroup"] a.group-toggle', _converse.rosterview.el);
if (_.reduce(toggles, (result, t) => result && u.isVisible(t), true)) {
return _.map(toggles, o => o.textContent.trim());
@ -435,7 +434,7 @@
fullname: mock.cur_names[i]
});
}
await test_utils.waitUntil(() => (sizzle('li', _converse.rosterview.el).filter(u.isVisible).length === 30), 600);
await u.waitUntil(() => (sizzle('li', _converse.rosterview.el).filter(u.isVisible).length === 30), 600);
// Check that usernames appear alphabetically per group
_.each(groups, function (name) {
const contacts = sizzle('.roster-group[data-group="'+name+'"] ul li', _converse.rosterview.el);
@ -476,9 +475,9 @@
const toggle = view.el.querySelector('a.group-toggle');
expect(view.model.get('state')).toBe('opened');
toggle.click();
await test_utils.waitUntil(() => view.model.get('state') === 'closed');
await u.waitUntil(() => view.model.get('state') === 'closed');
toggle.click();
await test_utils.waitUntil(() => view.model.get('state') === 'opened');
await u.waitUntil(() => view.model.get('state') === 'opened');
done();
}));
});
@ -497,7 +496,7 @@
async function (done, _converse) {
_addContacts(_converse);
await test_utils.waitUntil(() => sizzle('.roster-group', _converse.rosterview.el).filter(u.isVisible).map(e => e.querySelector('li')).length, 1000);
await u.waitUntil(() => sizzle('.roster-group', _converse.rosterview.el).filter(u.isVisible).map(e => e.querySelector('li')).length, 1000);
await checkHeaderToggling.apply(
_converse,
[_converse.rosterview.get('Pending contacts').el]
@ -531,7 +530,7 @@
test_utils.openControlBox();
spyOn(_converse.rosterview, 'update').and.callThrough();
_addContacts(_converse);
await test_utils.waitUntil(() => sizzle('li', _converse.rosterview.el).filter(u.isVisible).length, 500)
await u.waitUntil(() => sizzle('li', _converse.rosterview.el).filter(u.isVisible).length, 500)
expect(u.isVisible(_converse.rosterview.el)).toEqual(true);
expect(_converse.rosterview.update).toHaveBeenCalled();
expect(_converse.rosterview.el.querySelectorAll('li').length).toBe(3);
@ -546,7 +545,7 @@
spyOn(_converse.rosterview, 'update').and.callThrough();
_addContacts(_converse);
await test_utils.waitUntil(() => sizzle('li', _converse.rosterview.el).filter(u.isVisible).length, 500)
await u.waitUntil(() => sizzle('li', _converse.rosterview.el).filter(u.isVisible).length, 500)
expect(_converse.rosterview.update).toHaveBeenCalled();
expect(u.isVisible(_converse.rosterview.el)).toBe(true);
expect(sizzle('li', _converse.rosterview.el).filter(u.isVisible).length).toBe(3);
@ -567,14 +566,14 @@
spyOn(window, 'confirm').and.returnValue(true);
spyOn(contact, 'unauthorize').and.callFake(function () { return contact; });
spyOn(contact, 'removeFromRoster').and.callThrough();
await test_utils.waitUntil(() => sizzle(".pending-contact-name:contains('"+name+"')", _converse.rosterview.el).length, 700);
await u.waitUntil(() => sizzle(".pending-contact-name:contains('"+name+"')", _converse.rosterview.el).length, 700);
var sendIQ = _converse.connection.sendIQ;
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
sent_IQ = iq;
callback();
});
sizzle(`.remove-xmpp-contact[title="Click to remove ${name} as a contact"]`, _converse.rosterview.el).pop().click();
await test_utils.waitUntil(() => (sizzle(".pending-contact-name:contains('"+name+"')", _converse.rosterview.el).length === 0), 1000);
await u.waitUntil(() => (sizzle(".pending-contact-name:contains('"+name+"')", _converse.rosterview.el).length === 0), 1000);
expect(window.confirm).toHaveBeenCalled();
expect(contact.removeFromRoster).toHaveBeenCalled();
expect(sent_IQ.toLocaleString()).toBe(
@ -600,7 +599,7 @@
fullname: name
});
spyOn(window, 'confirm').and.returnValue(true);
await test_utils.waitUntil(() => {
await u.waitUntil(() => {
const el = _converse.rosterview.get('Pending contacts').el;
return u.isVisible(el) && _.filter(el.querySelectorAll('li'), li => u.isVisible(li)).length;
}, 700)
@ -620,7 +619,7 @@
const stanza = u.toStanza(`<iq id="${iq.getAttribute('id')}" to="romeo@montague.lit/orchard" type="result"/>`);
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => !u.isVisible(_converse.rosterview.get('Pending contacts').el));
await u.waitUntil(() => !u.isVisible(_converse.rosterview.get('Pending contacts').el));
done();
}));
@ -630,7 +629,7 @@
async function (done, _converse) {
_addContacts(_converse);
await test_utils.waitUntil(() => _converse.roster.at(0).vcard.get('fullname'))
await u.waitUntil(() => _converse.roster.at(0).vcard.get('fullname'))
spyOn(window, 'confirm').and.returnValue(true);
for (var i=0; i<mock.pend_names.length; i++) {
const name = mock.pend_names[i];
@ -657,7 +656,7 @@
});
expect(_converse.rosterview.update).toHaveBeenCalled();
}
await test_utils.waitUntil(() => sizzle('li', _converse.rosterview.get('Pending contacts').el).filter(u.isVisible).length, 700);
await u.waitUntil(() => sizzle('li', _converse.rosterview.get('Pending contacts').el).filter(u.isVisible).length, 700);
// Check that they are sorted alphabetically
const view = _converse.rosterview.get('Pending contacts');
const spans = view.el.querySelectorAll('.pending-xmpp-contact span');
@ -678,7 +677,7 @@
async function (done, _converse) {
_addContacts(_converse);
await test_utils.waitUntil(() => sizzle('li', _converse.rosterview.el).filter(u.isVisible).length, 500);
await u.waitUntil(() => sizzle('li', _converse.rosterview.el).filter(u.isVisible).length, 500);
await checkHeaderToggling.apply(_converse, [_converse.rosterview.el.querySelector('.roster-group')]);
done();
}));
@ -690,7 +689,7 @@
_converse.roster_groups = false;
_addContacts(_converse);
await test_utils.waitUntil(() => sizzle('li', _converse.rosterview.el).filter(u.isVisible).length, 500);
await u.waitUntil(() => sizzle('li', _converse.rosterview.el).filter(u.isVisible).length, 500);
_converse.rosterview.el.querySelector('.roster-group a.group-toggle').click();
const name = "Romeo Montague";
const jid = name.replace(/ /g,'.').toLowerCase() + '@montague.lit';
@ -723,7 +722,7 @@
});
expect(_converse.rosterview.update).toHaveBeenCalled();
}
await test_utils.waitUntil(() => sizzle('li', _converse.rosterview.el).length, 600);
await u.waitUntil(() => sizzle('li', _converse.rosterview.el).length, 600);
// Check that they are sorted alphabetically
const t = _.reduce(
_converse.rosterview.el.querySelectorAll('.roster-group .current-xmpp-contact.offline a.open-chat'),
@ -739,7 +738,7 @@
async function (done, _converse) {
_addContacts(_converse);
await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('li').length);
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('li').length);
const name = mock.cur_names[0];
const jid = name.replace(/ /g,'.').toLowerCase() + '@montague.lit';
const contact = _converse.roster.get(jid);
@ -759,7 +758,7 @@
`<query xmlns="jabber:iq:roster"><item jid="mercutio@montague.lit" subscription="remove"/></query>`+
`</iq>`);
expect(contact.removeFromRoster).toHaveBeenCalled();
await test_utils.waitUntil(() => sizzle(".open-chat:contains('"+name+"')", _converse.rosterview.el).length === 0);
await u.waitUntil(() => sizzle(".open-chat:contains('"+name+"')", _converse.rosterview.el).length === 0);
done();
}));
@ -777,7 +776,7 @@
ask: null,
fullname: name
});
await test_utils.waitUntil(() => sizzle('.roster-group', _converse.rosterview.el).filter(u.isVisible).map(e => e.querySelector('li')).length, 1000);
await u.waitUntil(() => sizzle('.roster-group', _converse.rosterview.el).filter(u.isVisible).map(e => e.querySelector('li')).length, 1000);
spyOn(window, 'confirm').and.returnValue(true);
spyOn(contact, 'removeFromRoster').and.callThrough();
spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback) {
@ -788,7 +787,7 @@
expect(window.confirm).toHaveBeenCalled();
expect(_converse.connection.sendIQ).toHaveBeenCalled();
expect(contact.removeFromRoster).toHaveBeenCalled();
await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length === 0);
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group').length === 0);
done();
}));
@ -798,7 +797,7 @@
async function (done, _converse) {
_addContacts(_converse);
await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group li').length, 700);
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group li').length, 700);
let jid, t;
spyOn(_converse.rosterview, 'update').and.callThrough();
const roster = _converse.rosterview.el;
@ -820,7 +819,7 @@
async function (done, _converse) {
_addContacts(_converse);
await test_utils.waitUntil(() => sizzle('.roster-group li', _converse.rosterview.el).length, 700);
await u.waitUntil(() => sizzle('.roster-group li', _converse.rosterview.el).length, 700);
let jid, t;
spyOn(_converse.rosterview, 'update').and.callThrough();
const roster = _converse.rosterview.el;
@ -842,7 +841,7 @@
async function (done, _converse) {
_addContacts(_converse);
await test_utils.waitUntil(() => sizzle('.roster-group li', _converse.rosterview.el).length, 700);
await u.waitUntil(() => sizzle('.roster-group li', _converse.rosterview.el).length, 700);
let jid, t;
spyOn(_converse.rosterview, 'update').and.callThrough();
const roster = _converse.rosterview.el;
@ -864,7 +863,7 @@
async function (done, _converse) {
_addContacts(_converse);
await test_utils.waitUntil(() => sizzle('.roster-group li', _converse.rosterview.el).length, 700);
await u.waitUntil(() => sizzle('.roster-group li', _converse.rosterview.el).length, 700);
var jid, t;
spyOn(_converse.rosterview, 'update').and.callThrough();
const roster = _converse.rosterview.el;
@ -888,7 +887,7 @@
async function (done, _converse) {
_addContacts(_converse);
await test_utils.waitUntil(() => sizzle('.roster-group li', _converse.rosterview.el).length, 500)
await u.waitUntil(() => sizzle('.roster-group li', _converse.rosterview.el).length, 500)
var jid, t;
spyOn(_converse.rosterview, 'update').and.callThrough();
var roster = _converse.rosterview.el;
@ -912,7 +911,7 @@
async function (done, _converse) {
_addContacts(_converse);
await test_utils.waitUntil(() => sizzle('.roster-group li', _converse.rosterview.el).length, 700);
await u.waitUntil(() => sizzle('.roster-group li', _converse.rosterview.el).length, 700);
let i, jid;
for (i=0; i<3; i++) {
jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@montague.lit';
@ -934,8 +933,8 @@
jid = mock.cur_names[i].replace(/ /g,'.').toLowerCase() + '@montague.lit';
_converse.roster.get(jid).presence.set('show', 'unavailable');
}
await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('li.online').length)
await test_utils.waitUntil(() => _converse.rosterview.el.querySelector('li:first-child').textContent.trim() === 'Juliet Capulet', 900);
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('li.online').length)
await u.waitUntil(() => _converse.rosterview.el.querySelector('li:first-child').textContent.trim() === 'Juliet Capulet', 900);
const contacts = _converse.rosterview.el.querySelectorAll('.current-xmpp-contact');
for (i=0; i<3; i++) {
expect(u.hasClass('online', contacts[i])).toBe(true);
@ -1019,7 +1018,7 @@
nickname: mock.req_names[i]
});
}
await test_utils.waitUntil(() => _converse.rosterview.get('Contact requests').el.querySelectorAll('li').length, 700);
await u.waitUntil(() => _converse.rosterview.get('Contact requests').el.querySelectorAll('li').length, 700);
expect(_converse.rosterview.update).toHaveBeenCalled();
// Check that they are sorted alphabetically
const children = _converse.rosterview.get('Contact requests').el.querySelectorAll('.requesting-xmpp-contact span');
@ -1044,7 +1043,7 @@
'requesting': true,
'nickname': name
});
await test_utils.waitUntil(() => sizzle('.roster-group', _converse.rosterview.el).filter(u.isVisible).length, 900);
await u.waitUntil(() => sizzle('.roster-group', _converse.rosterview.el).filter(u.isVisible).length, 900);
expect(u.isVisible(_converse.rosterview.get('Contact requests').el)).toEqual(true);
expect(sizzle('.roster-group', _converse.rosterview.el).filter(u.isVisible).map(e => e.querySelector('li')).length).toBe(1);
sizzle('.roster-group', _converse.rosterview.el).filter(u.isVisible).map(e => e.querySelector('li .decline-xmpp-request'))[0].click();
@ -1059,7 +1058,7 @@
async function (done, _converse) {
test_utils.createContacts(_converse, 'requesting').openControlBox();
await test_utils.waitUntil(() => sizzle('.roster-group', _converse.rosterview.el).filter(u.isVisible).length, 700);
await u.waitUntil(() => sizzle('.roster-group', _converse.rosterview.el).filter(u.isVisible).length, 700);
await checkHeaderToggling.apply(
_converse,
[_converse.rosterview.get('Contact requests').el]
@ -1078,7 +1077,7 @@
const jid = name.replace(/ /g,'.').toLowerCase() + '@montague.lit';
const contact = _converse.roster.get(jid);
spyOn(contact, 'authorize').and.callFake(() => contact);
await test_utils.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group li').length)
await u.waitUntil(() => _converse.rosterview.el.querySelectorAll('.roster-group li').length)
// TODO: Testing can be more thorough here, the user is
// actually not accepted/authorized because of
// mock_connection.
@ -1086,7 +1085,7 @@
const req_contact = sizzle(`.req-contact-name:contains("${contact.getDisplayName()}")`, _converse.rosterview.el).pop();
req_contact.parentElement.parentElement.querySelector('.accept-xmpp-request').click();
expect(_converse.roster.sendContactAddIQ).toHaveBeenCalled();
await test_utils.waitUntil(() => contact.authorize.calls.count());
await u.waitUntil(() => contact.authorize.calls.count());
expect(contact.authorize).toHaveBeenCalled();
done();
}));
@ -1097,7 +1096,7 @@
async function (done, _converse) {
test_utils.createContacts(_converse, 'requesting').openControlBox();
await test_utils.waitUntil(() => sizzle('.roster-group li', _converse.rosterview.el).length, 700);
await u.waitUntil(() => sizzle('.roster-group li', _converse.rosterview.el).length, 700);
_converse.rosterview.update(); // XXX: Hack to make sure $roster element is attaced.
const name = mock.req_names.sort()[1];
const jid = name.replace(/ /g,'.').toLowerCase() + '@montague.lit';
@ -1123,7 +1122,7 @@
let stanza = $pres({from: 'data@enterprise/resource', type: 'subscribe'});
_converse.connection._dataRecv(test_utils.createRequest(stanza));
await test_utils.waitUntil(() => sizzle('a:contains("Contact requests")', _converse.rosterview.el).length, 700);
await u.waitUntil(() => sizzle('a:contains("Contact requests")', _converse.rosterview.el).length, 700);
expect(_converse.roster.pluck('jid').length).toBe(1);
expect(_.includes(_converse.roster.pluck('jid'), 'data@enterprise')).toBeTruthy();
// Taken from the spec
@ -1191,7 +1190,7 @@
async function (done, _converse) {
test_utils.createContacts(_converse, 'all').openControlBox();
await test_utils.waitUntil(() => sizzle('.roster-group li', _converse.rosterview.el).length, 700);
await u.waitUntil(() => sizzle('.roster-group li', _converse.rosterview.el).length, 700);
for (let i=0; i<mock.cur_names.length; i++) {
const name = mock.cur_names[i];
const jid = name.replace(/ /g,'.').toLowerCase() + '@montague.lit';

View File

@ -24,7 +24,7 @@
_converse.api.user.login('romeo@montague.lit/orchard', 'secret');
const sent_stanzas = _converse.connection.sent_stanzas;
let stanza = await test_utils.waitUntil(() =>
let stanza = await u.waitUntil(() =>
sent_stanzas.filter(s => (s.tagName === 'enable')).pop());
expect(_converse.session.get('smacks_enabled')).toBe(false);
@ -34,10 +34,10 @@
_converse.connection._dataRecv(test_utils.createRequest(result));
expect(_converse.session.get('smacks_enabled')).toBe(true);
await test_utils.waitUntil(() => view.renderControlBoxPane.calls.count());
await u.waitUntil(() => view.renderControlBoxPane.calls.count());
let IQ_stanzas = _converse.connection.IQ_stanzas;
await test_utils.waitUntil(() => IQ_stanzas.length === 4);
await u.waitUntil(() => IQ_stanzas.length === 4);
let iq = IQ_stanzas.pop();
expect(Strophe.serialize(iq)).toBe(
@ -69,7 +69,7 @@
// test handling of ack requests
let r = u.toStanza(`<r xmlns="urn:xmpp:sm:3"/>`);
_converse.connection._dataRecv(test_utils.createRequest(r));
ack = await test_utils.waitUntil(() => sent_stanzas.filter(s => (s.nodeName === 'a')).pop());
ack = await u.waitUntil(() => sent_stanzas.filter(s => (s.nodeName === 'a')).pop());
expect(Strophe.serialize(ack)).toBe('<a h="0" xmlns="urn:xmpp:sm:3"/>');
const disco_result = $iq({
@ -92,14 +92,14 @@
r = u.toStanza(`<r xmlns="urn:xmpp:sm:3"/>`);
_converse.connection._dataRecv(test_utils.createRequest(r));
ack = await test_utils.waitUntil(() => sent_stanzas.filter(s => (s.nodeName === 'a' && s.getAttribute('h') === '1')).pop());
ack = await u.waitUntil(() => sent_stanzas.filter(s => (s.nodeName === 'a' && s.getAttribute('h') === '1')).pop());
expect(Strophe.serialize(ack)).toBe('<a h="1" xmlns="urn:xmpp:sm:3"/>');
// test session resumption
_converse.connection.IQ_stanzas = [];
IQ_stanzas = _converse.connection.IQ_stanzas;
_converse.api.connection.reconnect();
stanza = await test_utils.waitUntil(() =>
stanza = await u.waitUntil(() =>
sent_stanzas.filter(s => (s.tagName === 'resume')).pop());
expect(Strophe.serialize(stanza)).toEqual('<resume h="1" previd="some-long-sm-id" xmlns="urn:xmpp:sm:3"/>');
@ -110,7 +110,7 @@
expect(sizzle('enable', sent_stanzas).length).toBe(0);
expect(_converse.session.get('smacks_enabled')).toBe(true);
await test_utils.waitUntil(() => IQ_stanzas.length === 2);
await u.waitUntil(() => IQ_stanzas.length === 2);
// Test that unacked stanzas get resent out
iq = IQ_stanzas.pop();

View File

@ -11,7 +11,7 @@
it("can be received with a hint",
mock.initConverse(
null, ['rosterGroupsFetched'], {},
null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
async (done, _converse) => {
await test_utils.waitForRoster(_converse, 'current');
@ -37,7 +37,7 @@
await _converse.chatboxes.onMessage(msg);
const view = _converse.chatboxviews.get(sender_jid);
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
await test_utils.waitUntil(() => view.model.vcard.get('fullname') === 'Mercutio')
await u.waitUntil(() => view.model.vcard.get('fullname') === 'Mercutio')
expect(view.el.querySelector('.chat-msg__author').textContent.trim()).toBe('Mercutio');
const message_content = view.el.querySelector('.chat-msg__text');
expect(message_content.textContent).toBe(spoiler);
@ -48,7 +48,7 @@
it("can be received without a hint",
mock.initConverse(
null, ['rosterGroupsFetched'], {},
null, ['rosterGroupsFetched', 'chatBoxesFetched'], {},
async (done, _converse) => {
await test_utils.waitForRoster(_converse, 'current');
@ -71,7 +71,7 @@
await _converse.chatboxes.onMessage(msg);
const view = _converse.chatboxviews.get(sender_jid);
await new Promise((resolve, reject) => view.once('messageInserted', resolve));
await test_utils.waitUntil(() => view.model.vcard.get('fullname') === 'Mercutio')
await u.waitUntil(() => view.model.vcard.get('fullname') === 'Mercutio')
expect(_.includes(view.el.querySelector('.chat-msg__author').textContent, 'Mercutio')).toBeTruthy();
const message_content = view.el.querySelector('.chat-msg__text');
expect(message_content.textContent).toBe(spoiler);
@ -103,7 +103,7 @@
const view = _converse.api.chatviews.get(contact_jid);
spyOn(_converse.connection, 'send');
await test_utils.waitUntil(() => view.el.querySelector('.toggle-compose-spoiler'));
await u.waitUntil(() => view.el.querySelector('.toggle-compose-spoiler'));
let spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
spoiler_toggle.click();
@ -175,7 +175,7 @@
await test_utils.waitUntilDiscoConfirmed(_converse, contact_jid+'/phone', [], [Strophe.NS.SPOILER]);
const view = _converse.chatboxviews.get(contact_jid);
await test_utils.waitUntil(() => view.el.querySelector('.toggle-compose-spoiler'));
await u.waitUntil(() => view.el.querySelector('.toggle-compose-spoiler'));
let spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
spoiler_toggle.click();

View File

@ -24,13 +24,13 @@
const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@montague.lit';
test_utils.openChatBoxFor(_converse, contact_jid);
await test_utils.waitUntil(() => _converse.chatboxes.length > 1);
await u.waitUntil(() => _converse.chatboxes.length > 1);
const view = _converse.chatboxviews.get(contact_jid);
let show_modal_button = view.el.querySelector('.show-user-details-modal');
expect(u.isVisible(show_modal_button)).toBeTruthy();
show_modal_button.click();
const modal = view.user_details_modal;
await test_utils.waitUntil(() => u.isVisible(modal.el), 1000);
await u.waitUntil(() => u.isVisible(modal.el), 1000);
spyOn(window, 'confirm').and.returnValue(true);
spyOn(view.model.contact, 'removeFromRoster').and.callFake(function (callback) {
callback();
@ -38,7 +38,7 @@
let remove_contact_button = modal.el.querySelector('button.remove-contact');
expect(u.isVisible(remove_contact_button)).toBeTruthy();
remove_contact_button.click();
await test_utils.waitUntil(() => modal.el.getAttribute('aria-hidden'), 1000);
await u.waitUntil(() => modal.el.getAttribute('aria-hidden'), 1000);
show_modal_button = view.el.querySelector('.show-user-details-modal');
show_modal_button.click();
@ -62,7 +62,7 @@
expect(u.isVisible(show_modal_button)).toBeTruthy();
show_modal_button.click();
const modal = view.user_details_modal;
await test_utils.waitUntil(() => u.isVisible(modal.el), 2000);
await u.waitUntil(() => u.isVisible(modal.el), 2000);
spyOn(window, 'confirm').and.returnValue(true);
spyOn(view.model.contact, 'removeFromRoster').and.callFake(function (callback, errback) {
errback();
@ -70,7 +70,7 @@
let remove_contact_button = modal.el.querySelector('button.remove-contact');
expect(u.isVisible(remove_contact_button)).toBeTruthy();
remove_contact_button.click();
await test_utils.waitUntil(() => u.isVisible(document.querySelector('.alert-danger')), 2000);
await u.waitUntil(() => u.isVisible(document.querySelector('.alert-danger')), 2000);
const header = document.querySelector('.alert-danger .modal-title');
expect(header.textContent).toBe("Error");
@ -79,11 +79,11 @@
document.querySelector('.alert-danger button.close').click();
show_modal_button = view.el.querySelector('.show-user-details-modal');
show_modal_button.click();
await test_utils.waitUntil(() => u.isVisible(modal.el), 2000)
await u.waitUntil(() => u.isVisible(modal.el), 2000)
show_modal_button = view.el.querySelector('.show-user-details-modal');
show_modal_button.click();
await test_utils.waitUntil(() => u.isVisible(modal.el), 2000)
await u.waitUntil(() => u.isVisible(modal.el), 2000)
remove_contact_button = modal.el.querySelector('button.remove-contact');
expect(u.isVisible(remove_contact_button)).toBeTruthy();

View File

@ -1769,17 +1769,23 @@ _converse.api = {
},
/**
* Wait until a promise is resolved
* Wait until a promise is resolved or until the passed in function returns
* a truthy value.
* @method _converse.api.waitUntil
* @param {string} name The name of the promise
* @param {string|function} condition - The name of the promise to wait for,
* or a function which should eventually return a truthy value.
* @returns {Promise}
*/
waitUntil (name) {
const promise = _converse.promises[name];
if (_.isUndefined(promise)) {
return null;
waitUntil (condition) {
if (_.isFunction(condition)) {
return u.waitUntil(condition);
} else {
const promise = _converse.promises[condition];
if (_.isUndefined(promise)) {
return null;
}
return promise;
}
return promise;
},
/**

View File

@ -498,4 +498,66 @@ u.getUniqueId = function () {
});
};
/**
* Clears the specified timeout and interval.
* @param {number} timeout - Id if the timeout to clear.
* @param {number} interval - Id of the interval to clear.
* @private
* @copyright Simen Bekkhus 2016
* @license MIT
*/
function clearTimers(timeout, interval) {
clearTimeout(timeout);
clearInterval(interval);
}
/**
* Creates a {@link Promise} that resolves if the passed in function returns a truthy value.
* Rejects if it throws or does not return truthy within the given max_wait.
* @param {Function} func - The function called every check_delay,
* and the result of which is the resolved value of the promise.
* @param {number} [max_wait=300] - The time to wait before rejecting the promise.
* @param {number} [check_delay=3] - The time to wait before each invocation of {func}.
* @returns {Promise} A promise resolved with the value of func,
* or rejected with the exception thrown by it or it times out.
* @copyright Simen Bekkhus 2016
* @license MIT
*/
u.waitUntil = function (func, max_wait=300, check_delay=3) {
// Run the function once without setting up any listeners in case it's already true
try {
const result = func();
if (result) {
return Promise.resolve(result);
}
} catch (e) {
return Promise.reject(e);
}
const promise = u.getResolveablePromise();
function checker () {
try {
const result = func();
if (result) {
clearTimers(max_wait_timeout, interval);
promise.resolve(result);
}
} catch (e) {
clearTimers(max_wait_timeout, interval);
promise.reject(e);
}
}
const interval = setInterval(checker, check_delay);
const max_wait_timeout = setTimeout(() => {
clearTimers(max_wait_timeout, interval);
promise.reject(new Error('Wait until promise timed out'));
}, max_wait);
return promise;
};
export default u;

View File

@ -10,8 +10,7 @@ var config = {
'mock': 'tests/mock',
'sinon': 'node_modules/sinon/pkg/sinon',
'test-utils': 'tests/utils',
'transcripts': 'converse-logs/converse-logs',
'wait-until-promise': 'node_modules/wait-until-promise/index'
'transcripts': 'converse-logs/converse-logs'
},
shim: {
'jasmine-html': {
@ -65,12 +64,11 @@ var specs = [
"spec/http-file-upload"
];
require(['console-reporter', 'mock', 'sinon', 'wait-until-promise'], (ConsoleReporter, mock, sinon, waitUntilPromise) => {
require(['console-reporter', 'mock', 'sinon'], (ConsoleReporter, mock, sinon) => {
if (window.view_mode) {
mock.view_mode = window.view_mode;
}
window.sinon = sinon;
window.waitUntilPromise = waitUntilPromise.default;
// Load the specs
require(specs, jasmine => {
jasmine.DEFAULT_TIMEOUT_INTERVAL = 7000;

View File

@ -1,22 +1,17 @@
(function (root, factory) {
define(['es6-promise', 'mock', 'wait-until-promise'], factory);
}(this, function (Promise, mock, waitUntilPromise) {
var _ = converse.env._;
var $msg = converse.env.$msg;
var $pres = converse.env.$pres;
var $iq = converse.env.$iq;
var Strophe = converse.env.Strophe;
var sizzle = converse.env.sizzle;
var u = converse.env.utils;
var utils = {};
if (typeof window.Promise === 'undefined') {
waitUntilPromise.setPromiseImplementation(Promise);
}
utils.waitUntil = waitUntilPromise.default;
define(['es6-promise', 'mock'], factory);
}(this, function (Promise, mock) {
const _ = converse.env._;
const $msg = converse.env.$msg;
const $pres = converse.env.$pres;
const $iq = converse.env.$iq;
const Strophe = converse.env.Strophe;
const sizzle = converse.env.sizzle;
const u = converse.env.utils;
const utils = {};
utils.waitUntilDiscoConfirmed = async function (_converse, entity_jid, identities, features=[], items=[], type='info') {
const iq = await utils.waitUntil(() => {
const iq = await u.waitUntil(() => {
return _.filter(
_converse.connection.IQ_stanzas,
(iq) => sizzle(`iq[to="${entity_jid}"] query[xmlns="http://jabber.org/protocol/disco#${type}"]`, iq).length
@ -94,7 +89,7 @@
utils.openChatBoxFor = function (_converse, jid) {
_converse.roster.get(jid).trigger("open");
return utils.waitUntil(() => _converse.chatboxviews.get(jid), 1000);
return u.waitUntil(() => _converse.chatboxviews.get(jid), 1000);
};
utils.openChatRoomViaModal = async function (_converse, jid, nick='') {
@ -104,13 +99,13 @@
roomspanel.el.querySelector('.show-add-muc-modal').click();
utils.closeControlBox(_converse);
const modal = roomspanel.add_room_modal;
await utils.waitUntil(() => u.isVisible(modal.el), 1500)
await u.waitUntil(() => u.isVisible(modal.el), 1500)
modal.el.querySelector('input[name="chatroom"]').value = jid;
if (nick) {
modal.el.querySelector('input[name="nickname"]').value = nick;
}
modal.el.querySelector('form input[type="submit"]').click();
await utils.waitUntil(() => _converse.chatboxviews.get(jid), 1000);
await u.waitUntil(() => _converse.chatboxviews.get(jid), 1000);
return _converse.chatboxviews.get(jid);
};
@ -124,7 +119,7 @@
const muc_jid = `${room}@${server}`.toLowerCase();
const stanzas = _converse.connection.IQ_stanzas;
const index = stanzas.length-1;
const stanza = await utils.waitUntil(() => _.filter(
const stanza = await u.waitUntil(() => _.filter(
stanzas.slice(index),
iq => iq.querySelector(
`iq[to="${muc_jid}"] query[xmlns="http://jabber.org/protocol/disco#info"]`
@ -168,7 +163,7 @@
utils.waitForReservedNick = async function (_converse, muc_jid, nick) {
const view = _converse.chatboxviews.get(muc_jid);
const stanzas = _converse.connection.IQ_stanzas;
const iq = await utils.waitUntil(() => _.filter(
const iq = await u.waitUntil(() => _.filter(
stanzas,
s => sizzle(`iq[to="${muc_jid.toLowerCase()}"] query[node="x-roomuser-item"]`, s).length
).pop());
@ -185,13 +180,13 @@
}).c('query', {'xmlns': 'http://jabber.org/protocol/disco#info', 'node': 'x-roomuser-item'})
.c('identity', {'category': 'conference', 'name': nick, 'type': 'text'});
_converse.connection._dataRecv(utils.createRequest(stanza));
return utils.waitUntil(() => view.model.get('nick'));
return u.waitUntil(() => view.model.get('nick'));
};
utils.returnMemberLists = async function (_converse, muc_jid, members=[]) {
const stanzas = _converse.connection.IQ_stanzas;
const member_IQ = await utils.waitUntil(() => _.filter(
const member_IQ = await u.waitUntil(() => _.filter(
stanzas,
s => sizzle(`iq[to="${muc_jid}"] query[xmlns="${Strophe.NS.MUC_ADMIN}"] item[affiliation="member"]`, s).length
).pop());
@ -211,7 +206,7 @@
});
_converse.connection._dataRecv(utils.createRequest(member_list_stanza));
const admin_IQ = await utils.waitUntil(() => _.filter(
const admin_IQ = await u.waitUntil(() => _.filter(
stanzas,
s => sizzle(`iq[to="${muc_jid}"] query[xmlns="${Strophe.NS.MUC_ADMIN}"] item[affiliation="admin"]`, s).length
).pop());
@ -223,7 +218,7 @@
}).c('query', {'xmlns': Strophe.NS.MUC_ADMIN});
_converse.connection._dataRecv(utils.createRequest(admin_list_stanza));
const owner_IQ = await utils.waitUntil(() => _.filter(
const owner_IQ = await u.waitUntil(() => _.filter(
stanzas,
s => sizzle(`iq[to="${muc_jid}"] query[xmlns="${Strophe.NS.MUC_ADMIN}"] item[affiliation="owner"]`, s).length
).pop());
@ -262,7 +257,7 @@
_converse.connection._dataRecv(utils.createRequest(presence));
const view = _converse.chatboxviews.get(muc_jid);
await utils.waitUntil(() => (view.model.get('connection_status') === converse.ROOMSTATUS.ENTERED));
await u.waitUntil(() => (view.model.get('connection_status') === converse.ROOMSTATUS.ENTERED));
await utils.returnMemberLists(_converse, muc_jid, members);
};
@ -329,7 +324,7 @@
};
utils.waitForRoster = async function (_converse, type='current', length, include_nick=true) {
const iq = await utils.waitUntil(() =>
const iq = await u.waitUntil(() =>
_.filter(
_converse.connection.IQ_stanzas,
iq => sizzle(`iq[type="get"] query[xmlns="${Strophe.NS.ROSTER}"]`, iq).length