mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-09-10 18:22:37 -04:00
Merge branch 'main' of https://github.com/GSA/notifications-admin into notify-445
This commit is contained in:
Generated
+119
-119
@@ -50,19 +50,19 @@
|
|||||||
},
|
},
|
||||||
"boto3": {
|
"boto3": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:4847855cfa4ff272eb66cf1fc9542068ada6d4816d56573cc9cafde51962d0ef",
|
"sha256:152def2fcc9854dcc42383d2b53e2ed2c9ccb5ff6cc0f3ada20f1ab54418ede4",
|
||||||
"sha256:ec53175eaf818dfe1eec33f7e165eca957744c1d8a82047a9efbcce9547e5cc9"
|
"sha256:a5d6fdcaec863bc7ad2f8133ff9a926d6f06468b83b5fb631cd90bd33b709c45"
|
||||||
],
|
],
|
||||||
"markers": "python_version >= '3.7'",
|
"markers": "python_version >= '3.7'",
|
||||||
"version": "==1.26.124"
|
"version": "==1.26.141"
|
||||||
},
|
},
|
||||||
"botocore": {
|
"botocore": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:cbcbd5b084952d332d7b8170577f10509e3e7b3b6abbc2920b1c27e93ad2ab25",
|
"sha256:b01d156c42765f3f437959e01a8c7f3cb0e29b24aa0b8f373498133408b2e3c7",
|
||||||
"sha256:ebe8a83dd1db18180774ce45b1911959c60bb1843ea0db610231495527a3518a"
|
"sha256:e86e1633f98838317b9e1b5c874c4d85339b77f6b7e55c2a4d83913f6166f9ad"
|
||||||
],
|
],
|
||||||
"markers": "python_version >= '3.7'",
|
"markers": "python_version >= '3.7'",
|
||||||
"version": "==1.29.124"
|
"version": "==1.29.141"
|
||||||
},
|
},
|
||||||
"cachetools": {
|
"cachetools": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@@ -74,11 +74,11 @@
|
|||||||
},
|
},
|
||||||
"certifi": {
|
"certifi": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3",
|
"sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7",
|
||||||
"sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"
|
"sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716"
|
||||||
],
|
],
|
||||||
"markers": "python_version >= '3.6'",
|
"markers": "python_version >= '3.6'",
|
||||||
"version": "==2022.12.7"
|
"version": "==2023.5.7"
|
||||||
},
|
},
|
||||||
"cffi": {
|
"cffi": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@@ -248,60 +248,60 @@
|
|||||||
},
|
},
|
||||||
"coverage": {
|
"coverage": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:0342a28617e63ad15d96dca0f7ae9479a37b7d8a295f749c14f3436ea59fdcb3",
|
"sha256:004948e296149644d208964300cb3d98affc5211e9e490e9979af4030b0d6473",
|
||||||
"sha256:066b44897c493e0dcbc9e6a6d9f8bbb6607ef82367cf6810d387c09f0cd4fe9a",
|
"sha256:13cde6bb0e58fb67d09e2f373de3899d1d1e866c5a9ff05d93615f2f54fbd2bb",
|
||||||
"sha256:10b15394c13544fce02382360cab54e51a9e0fd1bd61ae9ce012c0d1e103c813",
|
"sha256:1c9e4a5eb1bbc3675ee57bc31f8eea4cd7fb0cbcbe4912cf1cb2bf3b754f4a80",
|
||||||
"sha256:12580845917b1e59f8a1c2ffa6af6d0908cb39220f3019e36c110c943dc875b0",
|
"sha256:2025f913f2edb0272ef15d00b1f335ff8908c921c8eb2013536fcaf61f5a683d",
|
||||||
"sha256:156192e5fd3dbbcb11cd777cc469cf010a294f4c736a2b2c891c77618cb1379a",
|
"sha256:25bad4196104761bc26b1dae9b57383826542ec689ff0042f7f4f4dd7a815cba",
|
||||||
"sha256:1637253b11a18f453e34013c665d8bf15904c9e3c44fbda34c643fbdc9d452cd",
|
"sha256:2692306d3d4cb32d2cceed1e47cebd6b1d2565c993d6d2eda8e6e6adf53301e6",
|
||||||
"sha256:292300f76440651529b8ceec283a9370532f4ecba9ad67d120617021bb5ef139",
|
"sha256:272ab31228a9df857ab5df5d67936d8861464dc89c5d3fab35132626e9369379",
|
||||||
"sha256:30dcaf05adfa69c2a7b9f7dfd9f60bc8e36b282d7ed25c308ef9e114de7fc23b",
|
"sha256:2e8c0e79820cdd67978e1120983786422d279e07a381dbf89d03bbb23ec670a6",
|
||||||
"sha256:338aa9d9883aaaad53695cb14ccdeb36d4060485bb9388446330bef9c361c252",
|
"sha256:3062fd5c62df988cea9f2972c593f77fed1182bfddc5a3b12b1e606cb7aba99e",
|
||||||
"sha256:373ea34dca98f2fdb3e5cb33d83b6d801007a8074f992b80311fc589d3e6b790",
|
"sha256:3436927d1794fa6763b89b60c896f9e3bd53212001026ebc9080d23f0c2733c1",
|
||||||
"sha256:38c0a497a000d50491055805313ed83ddba069353d102ece8aef5d11b5faf045",
|
"sha256:35db06450272473eab4449e9c2ad9bc6a0a68dab8e81a0eae6b50d9c2838767e",
|
||||||
"sha256:40cc0f91c6cde033da493227797be2826cbf8f388eaa36a0271a97a332bfd7ce",
|
"sha256:392154d09bd4473b9d11351ab5d63391f3d5d24d752f27b3be7498b0ee2b5226",
|
||||||
"sha256:4436cc9ba5414c2c998eaedee5343f49c02ca93b21769c5fdfa4f9d799e84200",
|
"sha256:3cff6980fe7100242170092bb40d2b1cdad79502cd532fd26b12a2b8a5f9aee0",
|
||||||
"sha256:509ecd8334c380000d259dc66feb191dd0a93b21f2453faa75f7f9cdcefc0718",
|
"sha256:42c692b55a647a832025a4c048007034fe77b162b566ad537ce65ad824b12a84",
|
||||||
"sha256:5c587f52c81211d4530fa6857884d37f514bcf9453bdeee0ff93eaaf906a5c1b",
|
"sha256:44c9b9f1a245f3d0d202b1a8fa666a80b5ecbe4ad5d0859c0fb16a52d9763224",
|
||||||
"sha256:5f3671662dc4b422b15776cdca89c041a6349b4864a43aa2350b6b0b03bbcc7f",
|
"sha256:496b86f1fc9c81a1cd53d8842ef712e950a4611bba0c42d33366a7b91ba969ec",
|
||||||
"sha256:6599bf92f33ab041e36e06d25890afbdf12078aacfe1f1d08c713906e49a3fe5",
|
"sha256:4bbd58eb5a2371bf160590f4262109f66b6043b0b991930693134cb617bc0169",
|
||||||
"sha256:6e8a95f243d01ba572341c52f89f3acb98a3b6d1d5d830efba86033dd3687ade",
|
"sha256:4e3783a286d5a93a2921396d50ce45a909aa8f13eee964465012f110f0cbb611",
|
||||||
"sha256:706ec567267c96717ab9363904d846ec009a48d5f832140b6ad08aad3791b1f5",
|
"sha256:4f3c7c19581d471af0e9cb49d928172cd8492cd78a2b7a4e82345d33662929bb",
|
||||||
"sha256:780551e47d62095e088f251f5db428473c26db7829884323e56d9c0c3118791a",
|
"sha256:52c139b7ab3f0b15f9aad0a3fedef5a1f8c0b2bdc291d88639ca2c97d3682416",
|
||||||
"sha256:7ff8f3fb38233035028dbc93715551d81eadc110199e14bbbfa01c5c4a43f8d8",
|
"sha256:541280dde49ce74a4262c5e395b48ea1207e78454788887118c421cb4ffbfcac",
|
||||||
"sha256:828189fcdda99aae0d6bf718ea766b2e715eabc1868670a0a07bf8404bf58c33",
|
"sha256:5906f6a84b47f995cd1bf0aca1c72d591c55ee955f98074e93660d64dfc66eb9",
|
||||||
"sha256:857abe2fa6a4973f8663e039ead8d22215d31db613ace76e4a98f52ec919068e",
|
"sha256:6284a2005e4f8061c58c814b1600ad0074ccb0289fe61ea709655c5969877b70",
|
||||||
"sha256:883123d0bbe1c136f76b56276074b0c79b5817dd4238097ffa64ac67257f4b6c",
|
"sha256:6727a0d929ff0028b1ed8b3e7f8701670b1d7032f219110b55476bb60c390bfb",
|
||||||
"sha256:8877d9b437b35a85c18e3c6499b23674684bf690f5d96c1006a1ef61f9fdf0f3",
|
"sha256:697f4742aa3f26c107ddcb2b1784a74fe40180014edbd9adaa574eac0529914c",
|
||||||
"sha256:8e575a59315a91ccd00c7757127f6b2488c2f914096077c745c2f1ba5b8c0969",
|
"sha256:6b9f64526286255735847aed0221b189486e0b9ed943446936e41b7e44b08783",
|
||||||
"sha256:97072cc90f1009386c8a5b7de9d4fc1a9f91ba5ef2146c55c1f005e7b5c5e068",
|
"sha256:6babcbf1e66e46052442f10833cfc4a0d3554d8276aa37af8531a83ed3c1a01d",
|
||||||
"sha256:9a22cbb5ede6fade0482111fa7f01115ff04039795d7092ed0db43522431b4f2",
|
"sha256:6e7f1a8328eeec34c54f1d5968a708b50fc38d31e62ca8b0560e84a968fbf9a9",
|
||||||
"sha256:a063aad9f7b4c9f9da7b2550eae0a582ffc7623dca1c925e50c3fbde7a579771",
|
"sha256:71f739f97f5f80627f1fee2331e63261355fd1e9a9cce0016394b6707ac3f4ec",
|
||||||
"sha256:a08c7401d0b24e8c2982f4e307124b671c6736d40d1c39e09d7a8687bddf83ed",
|
"sha256:76d06b721c2550c01a60e5d3093f417168658fb454e5dfd9a23570e9bffe39a1",
|
||||||
"sha256:a0b273fe6dc655b110e8dc89b8ec7f1a778d78c9fd9b4bda7c384c8906072212",
|
"sha256:77a04b84d01f0e12c66f16e69e92616442dc675bbe51b90bfb074b1e5d1c7fbd",
|
||||||
"sha256:a2b3b05e22a77bb0ae1a3125126a4e08535961c946b62f30985535ed40e26614",
|
"sha256:97729e6828643f168a2a3f07848e1b1b94a366b13a9f5aba5484c2215724edc8",
|
||||||
"sha256:a66e055254a26c82aead7ff420d9fa8dc2da10c82679ea850d8feebf11074d88",
|
"sha256:9a8723ccec4e564d4b9a79923246f7b9a8de4ec55fa03ec4ec804459dade3c4f",
|
||||||
"sha256:aa387bd7489f3e1787ff82068b295bcaafbf6f79c3dad3cbc82ef88ce3f48ad3",
|
"sha256:a5ffd45c6b93c23a8507e2f436983015c6457aa832496b6a095505ca2f63e8f1",
|
||||||
"sha256:ae453f655640157d76209f42c62c64c4d4f2c7f97256d3567e3b439bd5c9b06c",
|
"sha256:a6f03f87fea579d55e0b690d28f5042ec1368650466520fbc400e7aeaf09e995",
|
||||||
"sha256:b5016e331b75310610c2cf955d9f58a9749943ed5f7b8cfc0bb89c6134ab0a84",
|
"sha256:aac1d5fdc5378f6bac2c0c7ebe7635a6809f5b4376f6cf5d43243c1917a67087",
|
||||||
"sha256:b9a4ee55174b04f6af539218f9f8083140f61a46eabcaa4234f3c2a452c4ed11",
|
"sha256:ae82c5f168d2a39a5d69a12a69d4dc23837a43cf2ca99be60dfe59996ea6b113",
|
||||||
"sha256:bd3b4b8175c1db502adf209d06136c000df4d245105c8839e9d0be71c94aefe1",
|
"sha256:bc7b667f8654376e9353dd93e55e12ce2a59fb6d8e29fce40de682273425e044",
|
||||||
"sha256:bebea5f5ed41f618797ce3ffb4606c64a5de92e9c3f26d26c2e0aae292f015c1",
|
"sha256:c1d7a31603c3483ac49c1726723b0934f88f2c011c660e6471e7bd735c2fa110",
|
||||||
"sha256:c10fbc8a64aa0f3ed136b0b086b6b577bc64d67d5581acd7cc129af52654384e",
|
"sha256:c534431153caffc7c495c3eddf7e6a6033e7f81d78385b4e41611b51e8870446",
|
||||||
"sha256:c2c41c1b1866b670573657d584de413df701f482574bad7e28214a2362cb1fd1",
|
"sha256:c93d52c3dc7b9c65e39473704988602300e3cc1bad08b5ab5b03ca98bbbc68c1",
|
||||||
"sha256:cf97ed82ca986e5c637ea286ba2793c85325b30f869bf64d3009ccc1a31ae3fd",
|
"sha256:cbcc874f454ee51f158afd604a315f30c0e31dff1d5d5bf499fc529229d964dd",
|
||||||
"sha256:d1f25ee9de21a39b3a8516f2c5feb8de248f17da7eead089c2e04aa097936b47",
|
"sha256:d3cacc6a665221108ecdf90517a8028d07a2783df3417d12dcfef1c517e67478",
|
||||||
"sha256:d2fbc2a127e857d2f8898aaabcc34c37771bf78a4d5e17d3e1f5c30cd0cbc62a",
|
"sha256:d712cefff15c712329113b01088ba71bbcef0f7ea58478ca0bbec63a824844cb",
|
||||||
"sha256:dc945064a8783b86fcce9a0a705abd7db2117d95e340df8a4333f00be5efb64c",
|
"sha256:d7786b2fa7809bf835f830779ad285215a04da76293164bb6745796873f0942d",
|
||||||
"sha256:ddc5a54edb653e9e215f75de377354e2455376f416c4378e1d43b08ec50acc31",
|
"sha256:dc11b42fa61ff1e788dd095726a0aed6aad9c03d5c5984b54cb9e1e67b276aa5",
|
||||||
"sha256:e8834e5f17d89e05697c3c043d3e58a8b19682bf365048837383abfe39adaed5",
|
"sha256:dc4d5187ef4d53e0d4c8eaf530233685667844c5fb0b855fea71ae659017854b",
|
||||||
"sha256:ef9659d1cda9ce9ac9585c045aaa1e59223b143f2407db0eaee0b61a4f266fb6",
|
"sha256:f5440cdaf3099e7ab17a5a7065aed59aff8c8b079597b61c1f8be6f32fe60636",
|
||||||
"sha256:f6f5cab2d7f0c12f8187a376cc6582c477d2df91d63f75341307fcdcb5d60303",
|
"sha256:fa079995432037b5e2ef5ddbb270bcd2ded9f52b8e191a5de11fe59a00ea30d8",
|
||||||
"sha256:f81c9b4bd8aa747d417407a7f6f0b1469a43b36a85748145e144ac4e8d303cb5",
|
"sha256:fbe6e8c0a9a7193ba10ee52977d4d5e7652957c1f56ccefed0701db8801a2a3b",
|
||||||
"sha256:f99ef080288f09ffc687423b8d60978cf3a465d3f404a18d1a05474bd8575a47"
|
"sha256:fde5c7a9d9864d3e07992f66767a9817f24324f354caa3d8129735a3dc74f126"
|
||||||
],
|
],
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==7.2.5"
|
"version": "==7.2.6"
|
||||||
},
|
},
|
||||||
"cryptography": {
|
"cryptography": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@@ -743,7 +743,7 @@
|
|||||||
"notifications-utils": {
|
"notifications-utils": {
|
||||||
"editable": true,
|
"editable": true,
|
||||||
"git": "https://github.com/GSA/notifications-utils.git",
|
"git": "https://github.com/GSA/notifications-utils.git",
|
||||||
"ref": "c7a85c4d1e8f975d349c1555f416ae20f28a2ce1"
|
"ref": "1492349e323df749771494f13e3eb268ee402a65"
|
||||||
},
|
},
|
||||||
"numpy": {
|
"numpy": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@@ -864,11 +864,11 @@
|
|||||||
},
|
},
|
||||||
"pyjwt": {
|
"pyjwt": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:69285c7e31fc44f68a1feb309e948e0df53259d579295e6cfe2b1792329f05fd",
|
"sha256:ba2b425b15ad5ef12f200dc67dd56af4e26de2331f965c5439994dad075876e1",
|
||||||
"sha256:d83c3d892a77bbb74d3e1a2cfa90afaadb60945205d1095d9221f04466f64c14"
|
"sha256:bd6ca4a3c4285c1a2d4349e5a035fdf8fb94e04ccd0fcbe6ba289dae9cc3e074"
|
||||||
],
|
],
|
||||||
"markers": "python_version >= '3.7'",
|
"markers": "python_version >= '3.7'",
|
||||||
"version": "==2.6.0"
|
"version": "==2.7.0"
|
||||||
},
|
},
|
||||||
"pypdf2": {
|
"pypdf2": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@@ -989,19 +989,19 @@
|
|||||||
},
|
},
|
||||||
"redis": {
|
"redis": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:2c19e6767c474f2e85167909061d525ed65bea9301c0770bb151e041b7ac89a2",
|
"sha256:77929bc7f5dab9adf3acba2d3bb7d7658f1e0c2f1cafe7eb36434e751c471119",
|
||||||
"sha256:73ec35da4da267d6847e47f68730fdd5f62e2ca69e3ef5885c6a78a9374c3893"
|
"sha256:dc87a0bdef6c8bfe1ef1e1c40be7034390c2ae02d92dcd0c7ca1729443899880"
|
||||||
],
|
],
|
||||||
"markers": "python_version >= '3.7'",
|
"markers": "python_version >= '3.7'",
|
||||||
"version": "==4.5.4"
|
"version": "==4.5.5"
|
||||||
},
|
},
|
||||||
"requests": {
|
"requests": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:e8f3c9be120d3333921d213eef078af392fba3933ab7ed2d1cba3b56f2568c3b",
|
"sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f",
|
||||||
"sha256:f2e34a75f4749019bb0e3effb66683630e4ffeaf75819fb51bebef1bf5aef059"
|
"sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"
|
||||||
],
|
],
|
||||||
"markers": "python_version >= '3.7'",
|
"markers": "python_version >= '3.7'",
|
||||||
"version": "==2.29.0"
|
"version": "==2.31.0"
|
||||||
},
|
},
|
||||||
"rtreelib": {
|
"rtreelib": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@@ -1013,19 +1013,19 @@
|
|||||||
},
|
},
|
||||||
"s3transfer": {
|
"s3transfer": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:06176b74f3a15f61f1b4f25a1fc29a4429040b7647133a463da8fa5bd28d5ecd",
|
"sha256:3c0da2d074bf35d6870ef157158641178a4204a6e689e82546083e31e0311346",
|
||||||
"sha256:2ed07d3866f523cc561bf4a00fc5535827981b117dd7876f036b0c1aca42c947"
|
"sha256:640bb492711f4c0c0905e1f62b6aaeb771881935ad27884852411f8e9cacbca9"
|
||||||
],
|
],
|
||||||
"markers": "python_version >= '3.7'",
|
"markers": "python_version >= '3.7'",
|
||||||
"version": "==0.6.0"
|
"version": "==0.6.1"
|
||||||
},
|
},
|
||||||
"setuptools": {
|
"setuptools": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:23aaf86b85ca52ceb801d32703f12d77517b2556af839621c641fca11287952b",
|
"sha256:5df61bf30bb10c6f756eb19e7c9f3b473051f48db77fddbe06ff2ca307df9a6f",
|
||||||
"sha256:f104fa03692a2602fa0fec6c6a9e63b6c8a968de13e17c026957dd1f53d80990"
|
"sha256:62642358adc77ffa87233bc4d2354c4b2682d214048f500964dbe760ccedf102"
|
||||||
],
|
],
|
||||||
"markers": "python_version >= '3.7'",
|
"markers": "python_version >= '3.7'",
|
||||||
"version": "==67.7.2"
|
"version": "==67.8.0"
|
||||||
},
|
},
|
||||||
"shapely": {
|
"shapely": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@@ -1094,19 +1094,19 @@
|
|||||||
},
|
},
|
||||||
"typing-extensions": {
|
"typing-extensions": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb",
|
"sha256:06006244c70ac8ee83fa8282cb188f697b8db25bc8b4df07be1873c43897060c",
|
||||||
"sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4"
|
"sha256:3a8b36f13dd5fdc5d1b16fe317f5668545de77fa0b8e02006381fd49d731ab98"
|
||||||
],
|
],
|
||||||
"markers": "python_version < '3.10'",
|
"markers": "python_version < '3.10'",
|
||||||
"version": "==4.5.0"
|
"version": "==4.6.2"
|
||||||
},
|
},
|
||||||
"urllib3": {
|
"urllib3": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:8a388717b9476f934a21484e8c8e61875ab60644d29b9b39e11e4b9dc1c6b305",
|
"sha256:8d36afa7616d8ab714608411b4a3b13e58f463aee519024578e062e141dce20f",
|
||||||
"sha256:aa751d169e23c7479ce47a0cb0da579e3ede798f994f5816a74e4f4500dcea42"
|
"sha256:8f135f6502756bde6b2a9b28989df5fbe87c9970cecaa69041edcce7f0589b14"
|
||||||
],
|
],
|
||||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'",
|
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'",
|
||||||
"version": "==1.26.15"
|
"version": "==1.26.16"
|
||||||
},
|
},
|
||||||
"webencodings": {
|
"webencodings": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@@ -1117,11 +1117,11 @@
|
|||||||
},
|
},
|
||||||
"werkzeug": {
|
"werkzeug": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:4866679a0722de00796a74086238bb3b98d90f423f05de039abb09315487254a",
|
"sha256:1d5a58e0377d1fe39d061a5de4469e414e78ccb1e1e59c0f5ad6fa1c36c52b76",
|
||||||
"sha256:a987caf1092edc7523edb139edb20c70571c4a8d5eed02e0b547b4739174d091"
|
"sha256:48e5e61472fee0ddee27ebad085614ebedb7af41e88f687aaf881afb723a162f"
|
||||||
],
|
],
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==2.3.3"
|
"version": "==2.3.4"
|
||||||
},
|
},
|
||||||
"wtforms": {
|
"wtforms": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@@ -1182,19 +1182,19 @@
|
|||||||
},
|
},
|
||||||
"boto3": {
|
"boto3": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:4847855cfa4ff272eb66cf1fc9542068ada6d4816d56573cc9cafde51962d0ef",
|
"sha256:152def2fcc9854dcc42383d2b53e2ed2c9ccb5ff6cc0f3ada20f1ab54418ede4",
|
||||||
"sha256:ec53175eaf818dfe1eec33f7e165eca957744c1d8a82047a9efbcce9547e5cc9"
|
"sha256:a5d6fdcaec863bc7ad2f8133ff9a926d6f06468b83b5fb631cd90bd33b709c45"
|
||||||
],
|
],
|
||||||
"markers": "python_version >= '3.7'",
|
"markers": "python_version >= '3.7'",
|
||||||
"version": "==1.26.124"
|
"version": "==1.26.141"
|
||||||
},
|
},
|
||||||
"botocore": {
|
"botocore": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:cbcbd5b084952d332d7b8170577f10509e3e7b3b6abbc2920b1c27e93ad2ab25",
|
"sha256:b01d156c42765f3f437959e01a8c7f3cb0e29b24aa0b8f373498133408b2e3c7",
|
||||||
"sha256:ebe8a83dd1db18180774ce45b1911959c60bb1843ea0db610231495527a3518a"
|
"sha256:e86e1633f98838317b9e1b5c874c4d85339b77f6b7e55c2a4d83913f6166f9ad"
|
||||||
],
|
],
|
||||||
"markers": "python_version >= '3.7'",
|
"markers": "python_version >= '3.7'",
|
||||||
"version": "==1.29.124"
|
"version": "==1.29.141"
|
||||||
},
|
},
|
||||||
"cachecontrol": {
|
"cachecontrol": {
|
||||||
"extras": [
|
"extras": [
|
||||||
@@ -1209,11 +1209,11 @@
|
|||||||
},
|
},
|
||||||
"certifi": {
|
"certifi": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3",
|
"sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7",
|
||||||
"sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"
|
"sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716"
|
||||||
],
|
],
|
||||||
"markers": "python_version >= '3.6'",
|
"markers": "python_version >= '3.6'",
|
||||||
"version": "==2022.12.7"
|
"version": "==2023.5.7"
|
||||||
},
|
},
|
||||||
"cffi": {
|
"cffi": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@@ -1717,11 +1717,11 @@
|
|||||||
},
|
},
|
||||||
"pip-audit": {
|
"pip-audit": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:a4cb03f9e2896d626f5b153973d3ac0d32fdb18594d78d393b153c83bb8089b6",
|
"sha256:04fc0ad1727674181bda243a457af5a73038ee691dd9b8afc71f7e9292ce3912",
|
||||||
"sha256:bee3748030c895488b4dd8a6196fa44f484da000cfd52d8fc64dfa3a2e121624"
|
"sha256:7673bea690470024f1aec9be26055334cb987a530c6a431a31c347f66064e475"
|
||||||
],
|
],
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==2.5.4"
|
"version": "==2.5.6"
|
||||||
},
|
},
|
||||||
"pip-requirements-parser": {
|
"pip-requirements-parser": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@@ -1889,11 +1889,11 @@
|
|||||||
},
|
},
|
||||||
"requests": {
|
"requests": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:e8f3c9be120d3333921d213eef078af392fba3933ab7ed2d1cba3b56f2568c3b",
|
"sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f",
|
||||||
"sha256:f2e34a75f4749019bb0e3effb66683630e4ffeaf75819fb51bebef1bf5aef059"
|
"sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"
|
||||||
],
|
],
|
||||||
"markers": "python_version >= '3.7'",
|
"markers": "python_version >= '3.7'",
|
||||||
"version": "==2.29.0"
|
"version": "==2.31.0"
|
||||||
},
|
},
|
||||||
"requests-mock": {
|
"requests-mock": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@@ -1921,19 +1921,19 @@
|
|||||||
},
|
},
|
||||||
"s3transfer": {
|
"s3transfer": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:06176b74f3a15f61f1b4f25a1fc29a4429040b7647133a463da8fa5bd28d5ecd",
|
"sha256:3c0da2d074bf35d6870ef157158641178a4204a6e689e82546083e31e0311346",
|
||||||
"sha256:2ed07d3866f523cc561bf4a00fc5535827981b117dd7876f036b0c1aca42c947"
|
"sha256:640bb492711f4c0c0905e1f62b6aaeb771881935ad27884852411f8e9cacbca9"
|
||||||
],
|
],
|
||||||
"markers": "python_version >= '3.7'",
|
"markers": "python_version >= '3.7'",
|
||||||
"version": "==0.6.0"
|
"version": "==0.6.1"
|
||||||
},
|
},
|
||||||
"setuptools": {
|
"setuptools": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:23aaf86b85ca52ceb801d32703f12d77517b2556af839621c641fca11287952b",
|
"sha256:5df61bf30bb10c6f756eb19e7c9f3b473051f48db77fddbe06ff2ca307df9a6f",
|
||||||
"sha256:f104fa03692a2602fa0fec6c6a9e63b6c8a968de13e17c026957dd1f53d80990"
|
"sha256:62642358adc77ffa87233bc4d2354c4b2682d214048f500964dbe760ccedf102"
|
||||||
],
|
],
|
||||||
"markers": "python_version >= '3.7'",
|
"markers": "python_version >= '3.7'",
|
||||||
"version": "==67.7.2"
|
"version": "==67.8.0"
|
||||||
},
|
},
|
||||||
"six": {
|
"six": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@@ -1968,11 +1968,11 @@
|
|||||||
},
|
},
|
||||||
"stevedore": {
|
"stevedore": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:2c428d2338976279e8eb2196f7a94910960d9f7ba2f41f3988511e95ca447021",
|
"sha256:8cc040628f3cea5d7128f2e76cf486b2251a4e543c7b938f58d9a377f6694a2d",
|
||||||
"sha256:bd5a71ff5e5e5f5ea983880e4a1dd1bb47f8feebbb3d95b592398e2f02194771"
|
"sha256:a54534acf9b89bc7ed264807013b505bf07f74dbe4bcfa37d32bd063870b087c"
|
||||||
],
|
],
|
||||||
"markers": "python_version >= '3.8'",
|
"markers": "python_version >= '3.8'",
|
||||||
"version": "==5.0.0"
|
"version": "==5.1.0"
|
||||||
},
|
},
|
||||||
"toml": {
|
"toml": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@@ -1992,18 +1992,18 @@
|
|||||||
},
|
},
|
||||||
"types-pyyaml": {
|
"types-pyyaml": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:5aed5aa66bd2d2e158f75dda22b059570ede988559f030cf294871d3b647e3e8",
|
"sha256:662fa444963eff9b68120d70cda1af5a5f2aa57900003c2006d7626450eaae5f",
|
||||||
"sha256:c51b1bd6d99ddf0aa2884a7a328810ebf70a4262c292195d3f4f9a0005f9eeb6"
|
"sha256:ebab3d0700b946553724ae6ca636ea932c1b0868701d4af121630e78d695fc97"
|
||||||
],
|
],
|
||||||
"version": "==6.0.12.9"
|
"version": "==6.0.12.10"
|
||||||
},
|
},
|
||||||
"urllib3": {
|
"urllib3": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:8a388717b9476f934a21484e8c8e61875ab60644d29b9b39e11e4b9dc1c6b305",
|
"sha256:8d36afa7616d8ab714608411b4a3b13e58f463aee519024578e062e141dce20f",
|
||||||
"sha256:aa751d169e23c7479ce47a0cb0da579e3ede798f994f5816a74e4f4500dcea42"
|
"sha256:8f135f6502756bde6b2a9b28989df5fbe87c9970cecaa69041edcce7f0589b14"
|
||||||
],
|
],
|
||||||
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'",
|
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'",
|
||||||
"version": "==1.26.15"
|
"version": "==1.26.16"
|
||||||
},
|
},
|
||||||
"webencodings": {
|
"webencodings": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
@@ -2014,11 +2014,11 @@
|
|||||||
},
|
},
|
||||||
"werkzeug": {
|
"werkzeug": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:4866679a0722de00796a74086238bb3b98d90f423f05de039abb09315487254a",
|
"sha256:1d5a58e0377d1fe39d061a5de4469e414e78ccb1e1e59c0f5ad6fa1c36c52b76",
|
||||||
"sha256:a987caf1092edc7523edb139edb20c70571c4a8d5eed02e0b547b4739174d091"
|
"sha256:48e5e61472fee0ddee27ebad085614ebedb7af41e88f687aaf881afb723a162f"
|
||||||
],
|
],
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==2.3.3"
|
"version": "==2.3.4"
|
||||||
},
|
},
|
||||||
"xmltodict": {
|
"xmltodict": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ The [Notify API](https://github.com/GSA/notifications-api) provides the UI's bac
|
|||||||
|
|
||||||
1. Install [pipenv](https://pipenv.pypa.io/en/latest/)
|
1. Install [pipenv](https://pipenv.pypa.io/en/latest/)
|
||||||
|
|
||||||
|
1. Install [nvm (Node Version Manager)](https://github.com/nvm-sh/nvm#installing-and-updating)
|
||||||
|
|
||||||
1. Install Python and Node dependencies
|
1. Install Python and Node dependencies
|
||||||
|
|
||||||
`make bootstrap`
|
`make bootstrap`
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 71 KiB |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 62 KiB |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 86 KiB |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 26 KiB |
@@ -40,6 +40,8 @@ class Config(object):
|
|||||||
TEMPLATE_PREVIEW_API_HOST = getenv('TEMPLATE_PREVIEW_API_HOST', 'http://localhost:9999')
|
TEMPLATE_PREVIEW_API_HOST = getenv('TEMPLATE_PREVIEW_API_HOST', 'http://localhost:9999')
|
||||||
TEMPLATE_PREVIEW_API_KEY = getenv('TEMPLATE_PREVIEW_API_KEY', 'my-secret-key')
|
TEMPLATE_PREVIEW_API_KEY = getenv('TEMPLATE_PREVIEW_API_KEY', 'my-secret-key')
|
||||||
|
|
||||||
|
GOVERNMENT_EMAIL_DOMAIN_NAMES = ['gov']
|
||||||
|
|
||||||
# Logging
|
# Logging
|
||||||
NOTIFY_LOG_LEVEL = getenv('NOTIFY_LOG_LEVEL', 'INFO')
|
NOTIFY_LOG_LEVEL = getenv('NOTIFY_LOG_LEVEL', 'INFO')
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
</p>
|
</p>
|
||||||
{% if job.status == 'sending limits exceeded'%}
|
{% if job.status == 'sending limits exceeded'%}
|
||||||
<p class="govuk-error-message">
|
<p class="govuk-error-message">
|
||||||
Notify cannot send these messages because you have reached your daily limit. You can only send {{ current_service.message_limit|format_thousands }} messages per day.
|
Notify cannot send these messages because you have reached a limit. You can only send {{ current_service.message_limit|format_thousands }} messages per day and {{ 250000|format_thousands }} messages in total.
|
||||||
</p>
|
</p>
|
||||||
<p class="govuk-error-message govuk-!-margin-bottom-6">
|
<p class="govuk-error-message govuk-!-margin-bottom-6">
|
||||||
Upload this spreadsheet again tomorrow or <a class="govuk-link" href="https://www.notifications.service.gov.uk/support">contact the U.S. Notify team</a> to raise the limit.
|
Upload this spreadsheet again tomorrow or <a class="govuk-link" href="https://www.notifications.service.gov.uk/support">contact the U.S. Notify team</a> to raise the limit.
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
{% extends "content_template.html" %}
|
{% extends "content_template.html" %}
|
||||||
{% from "components/table.html" import mapping_table, row, text_field, edit_field, field with context %}
|
{% from "components/table.html" import mapping_table, row, text_field, edit_field, field with context %}
|
||||||
{% from "components/sub-navigation.html" import sub_navigation %}
|
{% from "components/sub-navigation.html" import sub_navigation %}
|
||||||
|
{% from "components/service-link.html" import service_link %}
|
||||||
|
|
||||||
{% block per_page_title %}
|
{% block per_page_title %}
|
||||||
Features
|
Features
|
||||||
@@ -26,7 +27,20 @@
|
|||||||
|
|
||||||
<h2 class="heading-medium" id="personalised-messages">Personalized content</h2>
|
<h2 class="heading-medium" id="personalised-messages">Personalized content</h2>
|
||||||
<p class="govuk-body">Notify makes it easy to send personalized messages from a single template.</p>
|
<p class="govuk-body">Notify makes it easy to send personalized messages from a single template.</p>
|
||||||
<p class="govuk-body">See <a class="govuk-link govuk-link--no-visited-state" href="{{ url_for('.edit_and_format_messages', _anchor='personalised-content') }}">how to personalize your content</a>.</p>
|
<p class="govuk-body">See <a class="govuk-link govuk-link--no-visited-state" href="{{ url_for('.guidance_index', _anchor='personalized-content') }}">how to personalize your content</a>.</p>
|
||||||
|
<h3 class="heading heading-small" id="sender">Show people who your texts are from</h3>
|
||||||
|
<p class="govuk-body">When you send a text message with Notify, the sender name tells people who it’s from.</p>
|
||||||
|
|
||||||
|
<p class="govuk-body">To change the text message sender from the default of ‘U.S. Notify’:</p>
|
||||||
|
|
||||||
|
<ol class="list list-number">
|
||||||
|
<li>Go to the <b class="govuk-!-font-weight-bold">Text message settings</b> section of the {{
|
||||||
|
service_link(current_service, 'main.service_settings', 'settings') }} page.</li>
|
||||||
|
<li>Select <b class="govuk-!-font-weight-bold">Manage</b> on the <b class="govuk-!-font-weight-bold">Text message
|
||||||
|
senders</b> row.</li>
|
||||||
|
<li>Select <b class="govuk-!-font-weight-bold">Change</b> or <b class="govuk-!-font-weight-bold">Add text message
|
||||||
|
sender</b>.</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
<h2 class="heading-medium" id="bulk-sending">Bulk sending</h2>
|
<h2 class="heading-medium" id="bulk-sending">Bulk sending</h2>
|
||||||
<p class="govuk-body">To send a batch of messages at once, upload a list of contact details to Notify. You can also schedule the date and time you want them to be sent.</p>
|
<p class="govuk-body">To send a batch of messages at once, upload a list of contact details to Notify. You can also schedule the date and time you want them to be sent.</p>
|
||||||
@@ -56,7 +70,7 @@
|
|||||||
|
|
||||||
<!-- <p class="govuk-body">We send messages through several different providers. If one provider fails, Notify switches to another so that your messages are not affected.</p> -->
|
<!-- <p class="govuk-body">We send messages through several different providers. If one provider fails, Notify switches to another so that your messages are not affected.</p> -->
|
||||||
|
|
||||||
<p class="govuk-body">Visit our <a class="govuk-link govuk-link--no-visited-state" href="{{ url_for('main.performance') }}">performance data</a> page to see how Notify is performing.</p>
|
<!-- <p class="govuk-body">Visit our <a class="govuk-link govuk-link--no-visited-state" href="{{ url_for('main.performance') }}">performance data</a> page to see how Notify is performing.</p> -->
|
||||||
|
|
||||||
<h2 class="heading-medium" id="security">Security</h2>
|
<h2 class="heading-medium" id="security">Security</h2>
|
||||||
<p class="govuk-body">Notify protects and manages data to meet the needs of government services.</p>
|
<p class="govuk-body">Notify protects and manages data to meet the needs of government services.</p>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
<ul class="list list-bullet">
|
<ul class="list list-bullet">
|
||||||
<li><a class="govuk-link govuk-link--no-visited-state" href="#formatting">format your content</a></li>
|
<li><a class="govuk-link govuk-link--no-visited-state" href="#formatting">format your content</a></li>
|
||||||
<li><a class="govuk-link govuk-link--no-visited-state" href="#links">add links</a></li>
|
<li><a class="govuk-link govuk-link--no-visited-state" href="#links">add links</a></li>
|
||||||
<li><a class="govuk-link govuk-link--no-visited-state" href="#personalised-content">personalize your content</a></li>
|
<li><a class="govuk-link govuk-link--no-visited-state" href="#personalized-content">personalize your content</a></li>
|
||||||
<li><a class="govuk-link govuk-link--no-visited-state" href="#optional-content">add optional content</a></li>
|
<li><a class="govuk-link govuk-link--no-visited-state" href="#optional-content">add optional content</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
<li>you can no longer control where the redirect goes</li>
|
<li>you can no longer control where the redirect goes</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h2 class="heading-medium" id="personalised-content">Personalize your content</h2>
|
<h2 class="heading-medium" id="personalized-content">Personalize your content</h2>
|
||||||
|
|
||||||
<p class="govuk-body">To personalize the content of your messages, add a placeholder to the template.</p>
|
<p class="govuk-body">To personalize the content of your messages, add a placeholder to the template.</p>
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2 class="govuk-heading-m">
|
<h2 class="govuk-heading-m">
|
||||||
Messages sent since May 2016
|
Messages sent since May 2023
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<div class="govuk-grid-row">
|
<div class="govuk-grid-row">
|
||||||
@@ -47,7 +47,7 @@
|
|||||||
<div class="dashboard-table">
|
<div class="dashboard-table">
|
||||||
{% call(item, row_number) list_table(
|
{% call(item, row_number) list_table(
|
||||||
notifications_by_type|reverse,
|
notifications_by_type|reverse,
|
||||||
caption='Messages sent since May 2016',
|
caption='Messages sent since May 2023',
|
||||||
caption_visible=False,
|
caption_visible=False,
|
||||||
field_headings=[
|
field_headings=[
|
||||||
'Date',
|
'Date',
|
||||||
|
|||||||
@@ -51,12 +51,12 @@
|
|||||||
Control your content
|
Control your content
|
||||||
</h2>
|
</h2>
|
||||||
<p class="govuk-body">
|
<p class="govuk-body">
|
||||||
You do not need any technical knowledge to create message templates.
|
You do not need any technical knowledge to create messages.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="govuk-grid-column-one-half">
|
<div class="govuk-grid-column-one-half">
|
||||||
<img
|
<img
|
||||||
src="{{ asset_url('images/product/01-templates.svg') }}"
|
src="{{ asset_url('images/product/01-templates-no-chrome.svg') }}"
|
||||||
alt="Example screenshot of adding a new text message template">
|
alt="Example screenshot of adding a new text message template">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="govuk-grid-column-one-half">
|
<div class="govuk-grid-column-one-half">
|
||||||
<img
|
<img
|
||||||
src="{{ asset_url('images/product/02-reporting.svg') }}"
|
src="{{ asset_url('images/product/02-reporting-no-chrome.svg') }}"
|
||||||
alt="A screenshot of U.S. Notify showing counts of emails and text messages sent"
|
alt="A screenshot of U.S. Notify showing counts of emails and text messages sent"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@@ -90,7 +90,7 @@
|
|||||||
Upload a spreadsheet of phone numbers and Notify sends the messages.
|
Upload a spreadsheet of phone numbers and Notify sends the messages.
|
||||||
</p>
|
</p>
|
||||||
<img
|
<img
|
||||||
src="{{ asset_url('images/product/03-spreadsheet.svg') }}"
|
src="{{ asset_url('images/product/03-spreadsheet-no-chrome.svg') }}"
|
||||||
alt="A screenshot of a spreadsheet with columns for email address, name and color"
|
alt="A screenshot of a spreadsheet with columns for email address, name and color"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@@ -100,7 +100,7 @@
|
|||||||
back office system.
|
back office system.
|
||||||
</p>
|
</p>
|
||||||
<img
|
<img
|
||||||
src="{{ asset_url('images/product/04-api.svg') }}"
|
src="{{ asset_url('images/product/04-api-no-chrome.svg') }}"
|
||||||
alt="A screenshot of some computer code with a notify.send_email function"
|
alt="A screenshot of some computer code with a notify.send_email function"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@@ -122,10 +122,10 @@
|
|||||||
<span class="govuk-visually-hidden">using Notify.</span>
|
<span class="govuk-visually-hidden">using Notify.</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p class="govuk-body">
|
<!-- <p class="govuk-body">
|
||||||
See the
|
See the
|
||||||
<a class="govuk-link govuk-link--no-visited-state" href="{{ url_for('main.performance') }}">list of services and organizations</a>.
|
<a class="govuk-link govuk-link--no-visited-state" href="{{ url_for('main.performance') }}">list of services and organizations</a>.
|
||||||
</p>
|
</p> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="product-page-section">
|
<!-- <div class="product-page-section">
|
||||||
@@ -154,7 +154,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div> -->
|
</div> -->
|
||||||
<div class="product-page-section">
|
<div class="product-page-section">
|
||||||
<div class="govuk-grid-row">
|
<div class="govuk-grid-row bottom-gutter-2">
|
||||||
<div class="govuk-grid-column-full">
|
<div class="govuk-grid-column-full">
|
||||||
<h2 class="with-keyline">
|
<h2 class="with-keyline">
|
||||||
The team
|
The team
|
||||||
|
|||||||
@@ -28,9 +28,9 @@
|
|||||||
<p class="govuk-body"> U.S. Notify will:</p>
|
<p class="govuk-body"> U.S. Notify will:</p>
|
||||||
<ul class="list list-bullet">
|
<ul class="list list-bullet">
|
||||||
<li>send all the messages you pass to us, as long as they meet our guidelines</li>
|
<li>send all the messages you pass to us, as long as they meet our guidelines</li>
|
||||||
<li>
|
<!-- <li>
|
||||||
show how Notify is performing (through our <a class="govuk-link govuk-link--no-visited-state" href="{{ url_for('main.performance') }}">performance</a> <!--and <a class="govuk-link govuk-link--no-visited-state" href="https://status.notifications.service.gov.uk/">status</a>-->page)
|
show how Notify is performing (through our <a class="govuk-link govuk-link--no-visited-state" href="{{ url_for('main.performance') }}">performance</a> and <a class="govuk-link govuk-link--no-visited-state" href="https://status.notifications.service.gov.uk/">status</a> page)
|
||||||
</li>
|
</li> -->
|
||||||
<li>keep your data <a class="govuk-link govuk-link--no-visited-state" href="{{ url_for('.security') }}">secure</a></li>
|
<li>keep your data <a class="govuk-link govuk-link--no-visited-state" href="{{ url_for('.security') }}">secure</a></li>
|
||||||
<li>give you one month’s notice by email if we change our terms of use or delivery providers</li>
|
<li>give you one month’s notice by email if we change our terms of use or delivery providers</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
gsa.gov
|
|
||||||
gmail.com
|
|
||||||
dispostable.com
|
|
||||||
simulator.amazonses.com
|
|
||||||
amazonses.com
|
|
||||||
+2
-8
@@ -1,20 +1,14 @@
|
|||||||
import os
|
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
|
||||||
from flask import abort, current_app
|
from flask import abort, current_app
|
||||||
from flask_login import current_user, login_required
|
from flask_login import current_user, login_required
|
||||||
|
|
||||||
|
from app import config
|
||||||
from app.notify_client.organisations_api_client import organisations_client
|
from app.notify_client.organisations_api_client import organisations_client
|
||||||
|
|
||||||
user_is_logged_in = login_required
|
user_is_logged_in = login_required
|
||||||
|
|
||||||
|
|
||||||
with open('{}/email_domains.txt'.format(
|
|
||||||
os.path.dirname(os.path.realpath(__file__))
|
|
||||||
)) as email_domains:
|
|
||||||
GOVERNMENT_EMAIL_DOMAIN_NAMES = [line.strip() for line in email_domains]
|
|
||||||
|
|
||||||
|
|
||||||
def user_has_permissions(*permissions, **permission_kwargs):
|
def user_has_permissions(*permissions, **permission_kwargs):
|
||||||
def wrap(func):
|
def wrap(func):
|
||||||
@wraps(func)
|
@wraps(func)
|
||||||
@@ -52,7 +46,7 @@ def user_is_platform_admin(f):
|
|||||||
|
|
||||||
def is_gov_user(email_address):
|
def is_gov_user(email_address):
|
||||||
return _email_address_ends_with(
|
return _email_address_ends_with(
|
||||||
email_address, GOVERNMENT_EMAIL_DOMAIN_NAMES
|
email_address, config.Config.GOVERNMENT_EMAIL_DOMAIN_NAMES
|
||||||
) or _email_address_ends_with(
|
) or _email_address_ends_with(
|
||||||
email_address, organisations_client.get_domains()
|
email_address, organisations_client.get_domains()
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ use and the setup process takes only ten minutes.
|
|||||||
|
|
||||||
**We’re in the early stages of assessing this product’s market fit and
|
**We’re in the early stages of assessing this product’s market fit and
|
||||||
targeting to pilot** this shared service with at least 3 partners in
|
targeting to pilot** this shared service with at least 3 partners in
|
||||||
spring of 2023. Following our first pilot, we intend to scale by adding
|
2023. Following our first pilot, we intend to scale by adding
|
||||||
additional features based on partner needs.
|
additional features based on partner needs.
|
||||||
|
|
||||||
| | | |
|
| | | |
|
||||||
|
|||||||
+10
-1
@@ -1,6 +1,15 @@
|
|||||||
# Notify Sprint Goals Log
|
# Notify Sprint Goals Log
|
||||||
|
|
||||||
## Sprint: TBD (5/11/23)
|
## Sprint: K (5/24/23)
|
||||||
|
|
||||||
|
| | Goals | Impact |
|
||||||
|
|-------------|-----------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
|
| Engineering | Moving from an ad-hoc "complete must-haves" process to a more strategic, themed progression; examining and implementing a structure for [Architecture Decision Records](https://github.com/GSA/notifications-admin/issues/522); assessing and planning for timezone accommodations in both [back-end](https://github.com/GSA/notifications-api/issues/260) and [UI](https://github.com/GSA/notifications-admin/issues/525) | Less context-switching; better documentation and prioritization; a clear strategy and content regarding timezones for users |
|
||||||
|
| UX | Wrap first iteration of [USWDS component migration](https://github.com/GSA/notifications-admin/issues/453); [propose new flows and wireframes](https://github.com/GSA/notifications-admin/issues/455) | A U.S. government look and feel; easier user navigation |
|
||||||
|
| Content | [Hone content](https://github.com/GSA/notifications-admin/issues/523) for [U.S. Notify-specific aspects](https://github.com/GSA/notifications-admin/issues/521); finalize [style and terminology docs](https://github.com/GSA/notifications-admin/issues/481) | Clear and applicable documentation and direction in the application |
|
||||||
|
| Security | Respond to any assessment questions and/or needs | Keep the LATO award timeline as short as possible
|
||||||
|
|
||||||
|
## Sprint: Jabiru (5/11/23)
|
||||||
|
|
||||||
| | Goal | Impact |
|
| | Goal | Impact |
|
||||||
|-------------|-----------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|
|
|-------------|-----------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ def _gen_mock_field(x):
|
|||||||
|
|
||||||
@pytest.mark.parametrize("email", [ # TODO: update with email_domains.txt
|
@pytest.mark.parametrize("email", [ # TODO: update with email_domains.txt
|
||||||
'test@gsa.gov',
|
'test@gsa.gov',
|
||||||
'test@gmail.com',
|
'test@abc.gov',
|
||||||
'test@amazonses.com'
|
'test@xyz.gov'
|
||||||
])
|
])
|
||||||
def test_valid_list_of_white_list_email_domains(
|
def test_valid_list_of_white_list_email_domains(
|
||||||
client_request,
|
client_request,
|
||||||
@@ -29,7 +29,6 @@ def test_valid_list_of_white_list_email_domains(
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("email", [ # TODO: update with email_domains.txt
|
@pytest.mark.parametrize("email", [ # TODO: update with email_domains.txt
|
||||||
'test@gov.gov',
|
|
||||||
'test@gov.gsa',
|
'test@gov.gsa',
|
||||||
'test@gmail.co',
|
'test@gmail.co',
|
||||||
'test@mail.co',
|
'test@mail.co',
|
||||||
|
|||||||
@@ -267,7 +267,7 @@ def test_choose_account_should_not_show_back_to_service_link_if_not_signed_in(
|
|||||||
|
|
||||||
@pytest.mark.parametrize('active', (
|
@pytest.mark.parametrize('active', (
|
||||||
False,
|
False,
|
||||||
pytest.param(True, marks=pytest.mark.xfail(raises=AssertionError)),
|
pytest.param(True),
|
||||||
))
|
))
|
||||||
def test_choose_account_should_not_show_back_to_service_link_if_service_archived(
|
def test_choose_account_should_not_show_back_to_service_link_if_service_archived(
|
||||||
client_request,
|
client_request,
|
||||||
@@ -283,7 +283,10 @@ def test_choose_account_should_not_show_back_to_service_link_if_service_archived
|
|||||||
page = client_request.get('main.choose_account')
|
page = client_request.get('main.choose_account')
|
||||||
|
|
||||||
assert normalize_spaces(page.select_one('h1').text) == 'Choose service'
|
assert normalize_spaces(page.select_one('h1').text) == 'Choose service'
|
||||||
assert page.select_one('.navigation-service a') is None
|
if active:
|
||||||
|
assert page.select_one('.navigation-service a') is not None
|
||||||
|
else:
|
||||||
|
assert page.select_one('.navigation-service a') is None
|
||||||
|
|
||||||
|
|
||||||
def test_should_not_show_back_to_service_if_user_doesnt_belong_to_service(
|
def test_should_not_show_back_to_service_if_user_doesnt_belong_to_service(
|
||||||
|
|||||||
@@ -262,64 +262,6 @@ def test_gps_can_create_own_organisations(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('organisation_type, organisation, expected_status', (
|
|
||||||
('nhs_local', None, 200),
|
|
||||||
('nhs_gp', None, 403),
|
|
||||||
('central', None, 403),
|
|
||||||
('nhs_local', organisation_json(organisation_type='nhs_local'), 403),
|
|
||||||
))
|
|
||||||
@pytest.mark.skip(reason='Update for TTS')
|
|
||||||
def test_nhs_local_can_create_own_organisations(
|
|
||||||
client_request,
|
|
||||||
mocker,
|
|
||||||
mock_get_service_organisation,
|
|
||||||
service_one,
|
|
||||||
organisation_type,
|
|
||||||
organisation,
|
|
||||||
expected_status,
|
|
||||||
):
|
|
||||||
mocker.patch('app.organisations_client.get_organisation', return_value=organisation)
|
|
||||||
mocker.patch(
|
|
||||||
'app.models.organisation.AllOrganisations.client_method',
|
|
||||||
return_value=[
|
|
||||||
organisation_json('t2', 'Trust 2', organisation_type='nhs_local'),
|
|
||||||
organisation_json('t1', 'Trust 1', organisation_type='nhs_local'),
|
|
||||||
organisation_json('gp1', 'GP 1', organisation_type='nhs_gp'),
|
|
||||||
organisation_json('c1', 'Central 1'),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
service_one['organisation_type'] = organisation_type
|
|
||||||
|
|
||||||
page = client_request.get(
|
|
||||||
'.add_organisation_from_nhs_local_service',
|
|
||||||
service_id=SERVICE_ONE_ID,
|
|
||||||
_expected_status=expected_status,
|
|
||||||
)
|
|
||||||
|
|
||||||
if expected_status == 403:
|
|
||||||
return
|
|
||||||
|
|
||||||
assert normalize_spaces(page.select_one('main p').text) == (
|
|
||||||
'Which NHS Trust or Clinical Commissioning Group do you work for?'
|
|
||||||
)
|
|
||||||
assert page.select_one('[data-module=live-search]')['data-targets'] == (
|
|
||||||
'.govuk-radios__item'
|
|
||||||
)
|
|
||||||
assert [
|
|
||||||
(
|
|
||||||
normalize_spaces(radio.select_one('label').text),
|
|
||||||
radio.select_one('input')['value']
|
|
||||||
)
|
|
||||||
for radio in page.select('.govuk-radios__item')
|
|
||||||
] == [
|
|
||||||
('Trust 1', 't1'),
|
|
||||||
('Trust 2', 't2'),
|
|
||||||
]
|
|
||||||
assert normalize_spaces(page.select_one('.js-stick-at-bottom-when-scrolling button').text) == (
|
|
||||||
'Continue'
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('data, expected_service_name', (
|
@pytest.mark.parametrize('data, expected_service_name', (
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
@@ -398,33 +340,6 @@ def test_validation_of_gps_creating_organisations(
|
|||||||
assert expected_error in page.select_one('.govuk-error-message, .error-message').text
|
assert expected_error in page.select_one('.govuk-error-message, .error-message').text
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skip(reason='Update for TTS')
|
|
||||||
def test_nhs_local_assigns_to_selected_organisation(
|
|
||||||
client_request,
|
|
||||||
mocker,
|
|
||||||
service_one,
|
|
||||||
mock_get_organisation,
|
|
||||||
mock_update_service_organisation,
|
|
||||||
):
|
|
||||||
mocker.patch(
|
|
||||||
'app.models.organisation.AllOrganisations.client_method',
|
|
||||||
return_value=[
|
|
||||||
organisation_json(ORGANISATION_ID, 'Trust 1', organisation_type='nhs_local'),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
service_one['organisation_type'] = 'nhs_local'
|
|
||||||
|
|
||||||
client_request.post(
|
|
||||||
'.add_organisation_from_nhs_local_service',
|
|
||||||
service_id=SERVICE_ONE_ID,
|
|
||||||
_data={
|
|
||||||
'organisations': ORGANISATION_ID,
|
|
||||||
},
|
|
||||||
_expected_status=302,
|
|
||||||
)
|
|
||||||
mock_update_service_organisation.assert_called_once_with(SERVICE_ONE_ID, ORGANISATION_ID)
|
|
||||||
|
|
||||||
|
|
||||||
@freeze_time("2020-02-20 20:20")
|
@freeze_time("2020-02-20 20:20")
|
||||||
def test_organisation_services_shows_live_services_and_usage(
|
def test_organisation_services_shows_live_services_and_usage(
|
||||||
client_request,
|
client_request,
|
||||||
@@ -795,8 +710,8 @@ def test_manage_org_users_shows_no_link_for_cancelled_users(
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('number_of_users', (
|
@pytest.mark.parametrize('number_of_users', (
|
||||||
pytest.param(7, marks=pytest.mark.xfail),
|
|
||||||
pytest.param(8),
|
pytest.param(8),
|
||||||
|
pytest.param(800),
|
||||||
))
|
))
|
||||||
def test_manage_org_users_should_show_live_search_if_more_than_7_users(
|
def test_manage_org_users_should_show_live_search_if_more_than_7_users(
|
||||||
client_request,
|
client_request,
|
||||||
@@ -839,6 +754,37 @@ def test_manage_org_users_should_show_live_search_if_more_than_7_users(
|
|||||||
) == 'Search by name or email address'
|
) == 'Search by name or email address'
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('number_of_users', (
|
||||||
|
pytest.param(3),
|
||||||
|
pytest.param(7),
|
||||||
|
))
|
||||||
|
def test_manage_org_users_should_show_live_search_if_7_users_or_less(
|
||||||
|
client_request,
|
||||||
|
mocker,
|
||||||
|
mock_get_organisation,
|
||||||
|
active_user_with_permissions,
|
||||||
|
number_of_users,
|
||||||
|
):
|
||||||
|
mocker.patch(
|
||||||
|
'app.models.user.OrganisationInvitedUsers.client_method',
|
||||||
|
return_value=[],
|
||||||
|
)
|
||||||
|
mocker.patch(
|
||||||
|
'app.models.user.OrganisationUsers.client_method',
|
||||||
|
return_value=[active_user_with_permissions] * number_of_users,
|
||||||
|
)
|
||||||
|
|
||||||
|
page = client_request.get(
|
||||||
|
'.manage_org_users',
|
||||||
|
org_id=ORGANISATION_ID,
|
||||||
|
)
|
||||||
|
|
||||||
|
with pytest.raises(expected_exception=TypeError):
|
||||||
|
assert page.select_one('div[data-module=live-search]')['data-targets'] == (
|
||||||
|
".user-list-item"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_edit_organisation_user_shows_the_delete_confirmation_banner(
|
def test_edit_organisation_user_shows_the_delete_confirmation_banner(
|
||||||
client_request,
|
client_request,
|
||||||
mock_get_organisation,
|
mock_get_organisation,
|
||||||
@@ -993,7 +939,6 @@ def test_view_organisation_settings(
|
|||||||
),
|
),
|
||||||
pytest.param(
|
pytest.param(
|
||||||
create_active_user_with_permissions(),
|
create_active_user_with_permissions(),
|
||||||
marks=pytest.mark.xfail
|
|
||||||
),
|
),
|
||||||
))
|
))
|
||||||
def test_update_organisation_settings(
|
def test_update_organisation_settings(
|
||||||
@@ -1011,21 +956,28 @@ def test_update_organisation_settings(
|
|||||||
mocker.patch('app.organisations_client.get_organisation_services', return_value=[])
|
mocker.patch('app.organisations_client.get_organisation_services', return_value=[])
|
||||||
client_request.login(user)
|
client_request.login(user)
|
||||||
|
|
||||||
|
if user['email_address'] == 'platform@admin.gsa.gov':
|
||||||
|
expected_status = 302
|
||||||
|
expected_redirect = url_for(
|
||||||
|
'main.organisation_settings',
|
||||||
|
org_id=organisation_one['id'],
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
expected_status = 403
|
||||||
|
expected_redirect = None
|
||||||
client_request.post(
|
client_request.post(
|
||||||
endpoint,
|
endpoint,
|
||||||
org_id=organisation_one['id'],
|
org_id=organisation_one['id'],
|
||||||
_data=post_data,
|
_data=post_data,
|
||||||
_expected_status=302,
|
_expected_status=expected_status,
|
||||||
_expected_redirect=url_for(
|
_expected_redirect=expected_redirect,
|
||||||
'main.organisation_settings',
|
|
||||||
org_id=organisation_one['id'],
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
mock_update_organisation.assert_called_once_with(
|
if user['email_address'] == 'platform@admin.gsa.gov':
|
||||||
organisation_one['id'],
|
mock_update_organisation.assert_called_once_with(
|
||||||
**expected_persisted,
|
organisation_one['id'],
|
||||||
)
|
**expected_persisted,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_update_organisation_sector_sends_service_id_data_to_api_client(
|
def test_update_organisation_sector_sends_service_id_data_to_api_client(
|
||||||
@@ -1143,7 +1095,6 @@ def test_view_organisation_domains(
|
|||||||
),
|
),
|
||||||
pytest.param(
|
pytest.param(
|
||||||
create_active_user_with_permissions(),
|
create_active_user_with_permissions(),
|
||||||
marks=pytest.mark.xfail
|
|
||||||
),
|
),
|
||||||
))
|
))
|
||||||
def test_update_organisation_domains(
|
def test_update_organisation_domains(
|
||||||
@@ -1157,22 +1108,29 @@ def test_update_organisation_domains(
|
|||||||
user,
|
user,
|
||||||
):
|
):
|
||||||
client_request.login(user)
|
client_request.login(user)
|
||||||
|
if user['email_address'] == 'platform@admin.gsa.gov':
|
||||||
|
expected_status = 302
|
||||||
|
expected_redirect = url_for(
|
||||||
|
'main.organisation_settings',
|
||||||
|
org_id=organisation_one['id'],
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
expected_status = 403
|
||||||
|
expected_redirect = None
|
||||||
|
|
||||||
client_request.post(
|
client_request.post(
|
||||||
'main.edit_organisation_domains',
|
'main.edit_organisation_domains',
|
||||||
org_id=ORGANISATION_ID,
|
org_id=ORGANISATION_ID,
|
||||||
_data=post_data,
|
_data=post_data,
|
||||||
_expected_status=302,
|
_expected_status=expected_status,
|
||||||
_expected_redirect=url_for(
|
_expected_redirect=expected_redirect,
|
||||||
'main.organisation_settings',
|
|
||||||
org_id=organisation_one['id'],
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
mock_update_organisation.assert_called_once_with(
|
if user['email_address'] == 'platform@admin.gsa.gov':
|
||||||
ORGANISATION_ID,
|
mock_update_organisation.assert_called_once_with(
|
||||||
**expected_persisted,
|
ORGANISATION_ID,
|
||||||
)
|
**expected_persisted,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_update_organisation_domains_when_domain_already_exists(
|
def test_update_organisation_domains_when_domain_already_exists(
|
||||||
|
|||||||
@@ -6,21 +6,15 @@ from notifications_utils.clients.zendesk.zendesk_client import (
|
|||||||
NotifySupportTicket,
|
NotifySupportTicket,
|
||||||
)
|
)
|
||||||
|
|
||||||
from app.utils.branding import NHS_EMAIL_BRANDING_ID
|
|
||||||
from tests import sample_uuid
|
from tests import sample_uuid
|
||||||
from tests.conftest import ORGANISATION_ID, SERVICE_ONE_ID, normalize_spaces
|
from tests.conftest import ORGANISATION_ID, SERVICE_ONE_ID, normalize_spaces
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('organisation_type, expected_options', (
|
@pytest.mark.parametrize('organisation_type, expected_options', (
|
||||||
('nhs_central', [
|
|
||||||
('nhs', 'NHS'),
|
|
||||||
('something_else', 'Something else'),
|
|
||||||
]),
|
|
||||||
('other', [
|
('other', [
|
||||||
('something_else', 'Something else'),
|
('something_else', 'Something else'),
|
||||||
])
|
]),
|
||||||
))
|
))
|
||||||
@pytest.mark.skip(reason='Update for TTS')
|
|
||||||
def test_email_branding_request_page_when_no_branding_is_set(
|
def test_email_branding_request_page_when_no_branding_is_set(
|
||||||
service_one,
|
service_one,
|
||||||
client_request,
|
client_request,
|
||||||
@@ -77,7 +71,6 @@ def test_email_branding_request_page_shows_branding_if_set(
|
|||||||
assert page.find('iframe')['src'] == url_for('main.email_template', branding_style='some-random-branding')
|
assert page.find('iframe')['src'] == url_for('main.email_template', branding_style='some-random-branding')
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skip(reason='Update for TTS')
|
|
||||||
def test_email_branding_request_page_back_link(
|
def test_email_branding_request_page_back_link(
|
||||||
client_request,
|
client_request,
|
||||||
):
|
):
|
||||||
@@ -104,13 +97,6 @@ def test_email_branding_request_page_back_link(
|
|||||||
'federal',
|
'federal',
|
||||||
'main.email_branding_govuk_and_org',
|
'main.email_branding_govuk_and_org',
|
||||||
),
|
),
|
||||||
(
|
|
||||||
{
|
|
||||||
'options': 'organisation',
|
|
||||||
},
|
|
||||||
'federal',
|
|
||||||
'main.email_branding_organisation',
|
|
||||||
),
|
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
'options': 'something_else',
|
'options': 'something_else',
|
||||||
@@ -119,7 +105,6 @@ def test_email_branding_request_page_back_link(
|
|||||||
'main.email_branding_something_else',
|
'main.email_branding_something_else',
|
||||||
),
|
),
|
||||||
))
|
))
|
||||||
@pytest.mark.skip(reason='Update for TTS')
|
|
||||||
def test_email_branding_request_submit(
|
def test_email_branding_request_submit(
|
||||||
client_request,
|
client_request,
|
||||||
service_one,
|
service_one,
|
||||||
@@ -151,7 +136,6 @@ def test_email_branding_request_submit(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skip(reason='Update for TTS')
|
|
||||||
def test_email_branding_request_submit_when_no_radio_button_is_selected(
|
def test_email_branding_request_submit_when_no_radio_button_is_selected(
|
||||||
client_request,
|
client_request,
|
||||||
service_one,
|
service_one,
|
||||||
@@ -170,9 +154,7 @@ def test_email_branding_request_submit_when_no_radio_button_is_selected(
|
|||||||
|
|
||||||
@pytest.mark.parametrize('endpoint, expected_heading', [
|
@pytest.mark.parametrize('endpoint, expected_heading', [
|
||||||
('main.email_branding_govuk_and_org', 'Before you request new branding'),
|
('main.email_branding_govuk_and_org', 'Before you request new branding'),
|
||||||
('main.email_branding_organisation', 'When you request new branding'),
|
|
||||||
])
|
])
|
||||||
@pytest.mark.skip(reason='Update for TTS')
|
|
||||||
def test_email_branding_description_pages_for_org_branding(
|
def test_email_branding_description_pages_for_org_branding(
|
||||||
client_request,
|
client_request,
|
||||||
mocker,
|
mocker,
|
||||||
@@ -250,7 +232,6 @@ def test_email_branding_something_else_page(client_request, service_one):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skip(reason='Update for TTS')
|
|
||||||
def test_get_email_branding_something_else_page_is_only_option(client_request, service_one):
|
def test_get_email_branding_something_else_page_is_only_option(client_request, service_one):
|
||||||
# should only have a "something else" option
|
# should only have a "something else" option
|
||||||
# so back button goes back to settings page
|
# so back button goes back to settings page
|
||||||
@@ -268,7 +249,6 @@ def test_get_email_branding_something_else_page_is_only_option(client_request, s
|
|||||||
@pytest.mark.parametrize('endpoint', [
|
@pytest.mark.parametrize('endpoint', [
|
||||||
('main.email_branding_govuk'),
|
('main.email_branding_govuk'),
|
||||||
('main.email_branding_govuk_and_org'),
|
('main.email_branding_govuk_and_org'),
|
||||||
# ('main.email_branding_nhs'),
|
|
||||||
('main.email_branding_organisation'),
|
('main.email_branding_organisation'),
|
||||||
])
|
])
|
||||||
def test_email_branding_pages_give_404_if_selected_branding_not_allowed(
|
def test_email_branding_pages_give_404_if_selected_branding_not_allowed(
|
||||||
@@ -284,7 +264,6 @@ def test_email_branding_pages_give_404_if_selected_branding_not_allowed(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skip(reason='Update for TTS')
|
|
||||||
def test_email_branding_govuk_submit(
|
def test_email_branding_govuk_submit(
|
||||||
mocker,
|
mocker,
|
||||||
client_request,
|
client_request,
|
||||||
@@ -379,34 +358,6 @@ def test_email_branding_govuk_and_org_submit(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skip(reason='Update for TTS')
|
|
||||||
def test_email_branding_nhs_submit(
|
|
||||||
mocker,
|
|
||||||
client_request,
|
|
||||||
service_one,
|
|
||||||
organisation_one,
|
|
||||||
no_reply_to_email_addresses,
|
|
||||||
mock_get_email_branding,
|
|
||||||
single_sms_sender,
|
|
||||||
mock_update_service,
|
|
||||||
):
|
|
||||||
service_one['email_branding'] = sample_uuid()
|
|
||||||
service_one['organisation_type'] = 'nhs_local'
|
|
||||||
|
|
||||||
page = client_request.post(
|
|
||||||
'.email_branding_nhs',
|
|
||||||
service_id=SERVICE_ONE_ID,
|
|
||||||
_follow_redirects=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
mock_update_service.assert_called_once_with(
|
|
||||||
SERVICE_ONE_ID,
|
|
||||||
email_branding=NHS_EMAIL_BRANDING_ID,
|
|
||||||
)
|
|
||||||
assert page.h1.text == 'Settings'
|
|
||||||
assert normalize_spaces(page.select_one('.banner-default').text) == 'You’ve updated your email branding'
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skip(reason='Update for TTS')
|
@pytest.mark.skip(reason='Update for TTS')
|
||||||
def test_email_branding_organisation_submit(
|
def test_email_branding_organisation_submit(
|
||||||
mocker,
|
mocker,
|
||||||
@@ -466,7 +417,6 @@ def test_email_branding_organisation_submit(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skip(reason='Update for TTS')
|
|
||||||
def test_email_branding_something_else_submit(
|
def test_email_branding_something_else_submit(
|
||||||
client_request,
|
client_request,
|
||||||
mocker,
|
mocker,
|
||||||
@@ -518,7 +468,6 @@ def test_email_branding_something_else_submit(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skip(reason='Update for TTS')
|
|
||||||
def test_email_branding_something_else_submit_shows_error_if_textbox_is_empty(
|
def test_email_branding_something_else_submit_shows_error_if_textbox_is_empty(
|
||||||
client_request,
|
client_request,
|
||||||
):
|
):
|
||||||
|
|||||||
@@ -122,10 +122,6 @@ def test_service_setting_toggles_show(
|
|||||||
({'active': True}, '.history', 2, 'Service history'),
|
({'active': True}, '.history', 2, 'Service history'),
|
||||||
({'active': False}, '.resume_service', 0, 'Resume service'),
|
({'active': False}, '.resume_service', 0, 'Resume service'),
|
||||||
({'active': False}, '.history', 1, 'Service history'),
|
({'active': False}, '.history', 1, 'Service history'),
|
||||||
pytest.param(
|
|
||||||
{'active': False}, '.archive_service', 2, 'Resume service',
|
|
||||||
marks=pytest.mark.xfail(raises=IndexError)
|
|
||||||
)
|
|
||||||
])
|
])
|
||||||
def test_service_setting_link_toggles(
|
def test_service_setting_link_toggles(
|
||||||
get_service_settings_page,
|
get_service_settings_page,
|
||||||
@@ -143,6 +139,26 @@ def test_service_setting_link_toggles(
|
|||||||
assert link['href'] == link_url
|
assert link['href'] == link_url
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('service_fields, endpoint, index, text', [
|
||||||
|
pytest.param(
|
||||||
|
{'active': False}, '.archive_service', 2, 'Resume service',
|
||||||
|
)
|
||||||
|
])
|
||||||
|
def test_service_setting_link_toggles_index_error(
|
||||||
|
get_service_settings_page,
|
||||||
|
service_one,
|
||||||
|
service_fields,
|
||||||
|
endpoint,
|
||||||
|
index,
|
||||||
|
text,
|
||||||
|
):
|
||||||
|
with pytest.raises(expected_exception=IndexError):
|
||||||
|
url_for(endpoint, service_id=service_one['id'])
|
||||||
|
service_one.update(service_fields)
|
||||||
|
page = get_service_settings_page()
|
||||||
|
page.select('.page-footer-link a')[index]
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('permissions,permissions_text,visible', [
|
@pytest.mark.parametrize('permissions,permissions_text,visible', [
|
||||||
('sms', 'inbound SMS', True),
|
('sms', 'inbound SMS', True),
|
||||||
('inbound_sms', 'inbound SMS', False), # no sms parent permission
|
('inbound_sms', 'inbound SMS', False), # no sms parent permission
|
||||||
|
|||||||
@@ -61,12 +61,6 @@ def mock_get_service_settings_page_common(
|
|||||||
'Start text messages with service name On Change your settings for starting text messages with service name',
|
'Start text messages with service name On Change your settings for starting text messages with service name',
|
||||||
'Send international text messages Off Change your settings for sending international text messages',
|
'Send international text messages Off Change your settings for sending international text messages',
|
||||||
|
|
||||||
# 'Label Value Action',
|
|
||||||
# 'Send emails On Change your settings for sending emails',
|
|
||||||
# 'Reply-to email addresses Not set Manage reply-to email addresses',
|
|
||||||
# 'Email branding GOV.UK Change email branding',
|
|
||||||
# 'Send files by email contact_us@gsa.gov Manage sending files by email',
|
|
||||||
# 'Receive text messages Off Change your settings for receiving text messages',
|
|
||||||
]),
|
]),
|
||||||
(create_platform_admin_user(), [
|
(create_platform_admin_user(), [
|
||||||
|
|
||||||
@@ -78,12 +72,6 @@ def mock_get_service_settings_page_common(
|
|||||||
'Start text messages with service name On Change your settings for starting text messages with service name',
|
'Start text messages with service name On Change your settings for starting text messages with service name',
|
||||||
'Send international text messages Off Change your settings for sending international text messages',
|
'Send international text messages Off Change your settings for sending international text messages',
|
||||||
|
|
||||||
# 'Label Value Action',
|
|
||||||
# 'Send emails On Change your settings for sending emails',
|
|
||||||
# 'Reply-to email addresses Not set Manage reply-to email addresses',
|
|
||||||
# 'Email branding GOV.UK Change email branding',
|
|
||||||
# 'Send files by email contact_us@gsa.gov Manage sending files by email',
|
|
||||||
# 'Receive text messages Off Change your settings for receiving text messages',
|
|
||||||
|
|
||||||
'Label Value Action',
|
'Label Value Action',
|
||||||
'Live Off Change service status',
|
'Live Off Change service status',
|
||||||
@@ -221,12 +209,6 @@ def test_send_files_by_email_row_on_settings_page(
|
|||||||
'Start text messages with service name On Change your settings for starting text messages with service name',
|
'Start text messages with service name On Change your settings for starting text messages with service name',
|
||||||
'Send international text messages On Change your settings for sending international text messages',
|
'Send international text messages On Change your settings for sending international text messages',
|
||||||
|
|
||||||
# 'Label Value Action',
|
|
||||||
# 'Send emails On Change your settings for sending emails',
|
|
||||||
# 'Reply-to email addresses test@example.com Manage reply-to email addresses',
|
|
||||||
# 'Email branding Organisation name Change email branding',
|
|
||||||
# 'Send files by email Not set up Manage sending files by email',
|
|
||||||
# 'Receive text messages On Change your settings for receiving text messages',
|
|
||||||
|
|
||||||
]),
|
]),
|
||||||
(['email', 'sms', 'email_auth'], [
|
(['email', 'sms', 'email_auth'], [
|
||||||
@@ -238,12 +220,6 @@ def test_send_files_by_email_row_on_settings_page(
|
|||||||
'Start text messages with service name On Change your settings for starting text messages with service name',
|
'Start text messages with service name On Change your settings for starting text messages with service name',
|
||||||
'Send international text messages Off Change your settings for sending international text messages',
|
'Send international text messages Off Change your settings for sending international text messages',
|
||||||
|
|
||||||
# 'Label Value Action',
|
|
||||||
# 'Send emails On Change your settings for sending emails',
|
|
||||||
# 'Reply-to email addresses test@example.com Manage reply-to email addresses',
|
|
||||||
# 'Email branding Organisation name Change email branding',
|
|
||||||
# 'Send files by email Not set up Manage sending files by email'
|
|
||||||
# 'Receive text messages Off Change your settings for receiving text messages',
|
|
||||||
|
|
||||||
]),
|
]),
|
||||||
])
|
])
|
||||||
@@ -619,8 +595,6 @@ def test_should_check_if_estimated_volumes_provided(
|
|||||||
'reply_to_email_addresses,'
|
'reply_to_email_addresses,'
|
||||||
'expected_reply_to_checklist_item'
|
'expected_reply_to_checklist_item'
|
||||||
), [
|
), [
|
||||||
pytest.param(None, 0, [], '', marks=pytest.mark.xfail(raises=IndexError)),
|
|
||||||
pytest.param(0, 0, [], '', marks=pytest.mark.xfail(raises=IndexError)),
|
|
||||||
(None, 1, [], 'Add a reply-to email address Not completed'),
|
(None, 1, [], 'Add a reply-to email address Not completed'),
|
||||||
(None, 1, [{}], 'Add a reply-to email address Completed'),
|
(None, 1, [{}], 'Add a reply-to email address Completed'),
|
||||||
(1, 1, [], 'Add a reply-to email address Not completed'),
|
(1, 1, [], 'Add a reply-to email address Not completed'),
|
||||||
@@ -674,6 +648,59 @@ def test_should_check_for_reply_to_on_go_live(
|
|||||||
mock_get_reply_to_email_addresses.assert_called_once_with(SERVICE_ONE_ID)
|
mock_get_reply_to_email_addresses.assert_called_once_with(SERVICE_ONE_ID)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize((
|
||||||
|
'volume_email,'
|
||||||
|
'count_of_email_templates,'
|
||||||
|
'reply_to_email_addresses,'
|
||||||
|
'expected_reply_to_checklist_item'
|
||||||
|
), [
|
||||||
|
(None, 0, [], ''),
|
||||||
|
(0, 0, [], ''),
|
||||||
|
])
|
||||||
|
def test_should_check_for_reply_to_on_go_live_index_error(
|
||||||
|
client_request,
|
||||||
|
mocker,
|
||||||
|
service_one,
|
||||||
|
fake_uuid,
|
||||||
|
single_sms_sender,
|
||||||
|
volume_email,
|
||||||
|
count_of_email_templates,
|
||||||
|
reply_to_email_addresses,
|
||||||
|
expected_reply_to_checklist_item,
|
||||||
|
mock_get_invites_for_service,
|
||||||
|
mock_get_users_by_service,
|
||||||
|
):
|
||||||
|
mocker.patch(
|
||||||
|
'app.service_api_client.get_service_templates',
|
||||||
|
return_value={'data': [
|
||||||
|
create_template(template_type='email')
|
||||||
|
for _ in range(0, count_of_email_templates)
|
||||||
|
]}
|
||||||
|
)
|
||||||
|
|
||||||
|
mocker.patch(
|
||||||
|
'app.main.views.service_settings.service_api_client.get_reply_to_email_addresses',
|
||||||
|
return_value=reply_to_email_addresses
|
||||||
|
)
|
||||||
|
|
||||||
|
for channel, volume in (('email', volume_email), ('sms', 0)):
|
||||||
|
mocker.patch(
|
||||||
|
'app.models.service.Service.volume_{}'.format(channel),
|
||||||
|
create=True,
|
||||||
|
new_callable=PropertyMock,
|
||||||
|
return_value=volume,
|
||||||
|
)
|
||||||
|
|
||||||
|
with pytest.raises(expected_exception=IndexError):
|
||||||
|
page = client_request.get(
|
||||||
|
'main.request_to_go_live', service_id=SERVICE_ONE_ID
|
||||||
|
)
|
||||||
|
assert page.h1.text == 'Before you request to go live'
|
||||||
|
|
||||||
|
checklist_items = page.select('.task-list .task-list-item')
|
||||||
|
assert normalize_spaces(checklist_items[3].text) == expected_reply_to_checklist_item
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize((
|
@pytest.mark.parametrize((
|
||||||
'count_of_users_with_manage_service,'
|
'count_of_users_with_manage_service,'
|
||||||
'count_of_invites_with_manage_service,'
|
'count_of_invites_with_manage_service,'
|
||||||
@@ -835,55 +862,49 @@ def test_request_to_go_live_redirects_if_service_already_live(
|
|||||||
'sms_senders,'
|
'sms_senders,'
|
||||||
'expected_sms_sender_checklist_item'
|
'expected_sms_sender_checklist_item'
|
||||||
), [
|
), [
|
||||||
pytest.param(
|
(
|
||||||
0,
|
0,
|
||||||
'state',
|
'state',
|
||||||
0,
|
0,
|
||||||
[],
|
[],
|
||||||
'',
|
'',
|
||||||
marks=pytest.mark.xfail(raises=IndexError)
|
|
||||||
),
|
),
|
||||||
pytest.param(
|
(
|
||||||
None,
|
None,
|
||||||
'state',
|
'state',
|
||||||
0,
|
0,
|
||||||
[{'is_default': True, 'sms_sender': 'GOVUK'}],
|
[{'is_default': True, 'sms_sender': 'GOVUK'}],
|
||||||
'',
|
'',
|
||||||
marks=pytest.mark.xfail(raises=IndexError)
|
|
||||||
),
|
),
|
||||||
pytest.param(
|
(
|
||||||
1,
|
1,
|
||||||
'federal',
|
'federal',
|
||||||
99,
|
99,
|
||||||
[{'is_default': True, 'sms_sender': 'GOVUK'}],
|
[{'is_default': True, 'sms_sender': 'GOVUK'}],
|
||||||
'',
|
'',
|
||||||
marks=pytest.mark.xfail(raises=IndexError)
|
|
||||||
),
|
),
|
||||||
pytest.param(
|
(
|
||||||
None,
|
None,
|
||||||
'federal',
|
'federal',
|
||||||
99,
|
99,
|
||||||
[{'is_default': True, 'sms_sender': 'GOVUK'}],
|
[{'is_default': True, 'sms_sender': 'GOVUK'}],
|
||||||
'',
|
'',
|
||||||
marks=pytest.mark.xfail(raises=IndexError)
|
|
||||||
),
|
),
|
||||||
pytest.param(
|
(
|
||||||
1,
|
1,
|
||||||
'federal',
|
'federal',
|
||||||
99,
|
99,
|
||||||
[{'is_default': True, 'sms_sender': 'GOVUK'}],
|
[{'is_default': True, 'sms_sender': 'GOVUK'}],
|
||||||
'',
|
'',
|
||||||
marks=pytest.mark.xfail(raises=IndexError)
|
|
||||||
),
|
),
|
||||||
pytest.param(
|
(
|
||||||
1,
|
1,
|
||||||
'state',
|
'state',
|
||||||
1,
|
1,
|
||||||
[],
|
[],
|
||||||
'Change your text message sender name Not completed',
|
'Change your text message sender name Not completed',
|
||||||
marks=pytest.mark.xfail(raises=IndexError),
|
|
||||||
),
|
),
|
||||||
pytest.param(
|
(
|
||||||
1,
|
1,
|
||||||
'state',
|
'state',
|
||||||
1,
|
1,
|
||||||
@@ -892,7 +913,6 @@ def test_request_to_go_live_redirects_if_service_already_live(
|
|||||||
{'is_default': True, 'sms_sender': 'KUVOG'},
|
{'is_default': True, 'sms_sender': 'KUVOG'},
|
||||||
],
|
],
|
||||||
'Change your text message sender name Completed',
|
'Change your text message sender name Completed',
|
||||||
marks=pytest.mark.xfail(raises=IndexError),
|
|
||||||
),
|
),
|
||||||
])
|
])
|
||||||
def test_should_check_for_sms_sender_on_go_live(
|
def test_should_check_for_sms_sender_on_go_live(
|
||||||
@@ -935,15 +955,16 @@ def test_should_check_for_sms_sender_on_go_live(
|
|||||||
return_value=volume,
|
return_value=volume,
|
||||||
)
|
)
|
||||||
|
|
||||||
page = client_request.get(
|
with pytest.raises(expected_exception=IndexError):
|
||||||
'main.request_to_go_live', service_id=SERVICE_ONE_ID
|
page = client_request.get(
|
||||||
)
|
'main.request_to_go_live', service_id=SERVICE_ONE_ID
|
||||||
assert page.h1.text == 'Before you request to go live'
|
)
|
||||||
|
assert page.h1.text == 'Before you request to go live'
|
||||||
|
|
||||||
checklist_items = page.select('.task-list .task-list-item')
|
checklist_items = page.select('.task-list .task-list-item')
|
||||||
assert normalize_spaces(checklist_items[3].text) == expected_sms_sender_checklist_item
|
assert normalize_spaces(checklist_items[3].text) == expected_sms_sender_checklist_item
|
||||||
|
|
||||||
mock_get_sms_senders.assert_called_once_with(SERVICE_ONE_ID)
|
mock_get_sms_senders.assert_called_once_with(SERVICE_ONE_ID)
|
||||||
|
|
||||||
|
|
||||||
def test_non_gov_user_is_told_they_cant_go_live(
|
def test_non_gov_user_is_told_they_cant_go_live(
|
||||||
@@ -1702,8 +1723,6 @@ def test_and_more_hint_appears_on_settings_with_more_than_just_a_single_sender(
|
|||||||
"Reply-to email addresses test@example.com …and 2 more Manage reply-to email addresses"
|
"Reply-to email addresses test@example.com …and 2 more Manage reply-to email addresses"
|
||||||
assert get_row(page, 'Text message senders') == \
|
assert get_row(page, 'Text message senders') == \
|
||||||
"Text message senders Example …and 2 more Manage text message senders"
|
"Text message senders Example …and 2 more Manage text message senders"
|
||||||
# assert get_row(page, 'Sender addresses') == \
|
|
||||||
# "Sender addresses 1 Example Street …and 2 more Manage sender addresses"
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('sender_list_page, index, expected_output', [
|
@pytest.mark.parametrize('sender_list_page, index, expected_output', [
|
||||||
@@ -2899,7 +2918,6 @@ def test_should_show_page_to_set_sms_allowance(
|
|||||||
('0', 0),
|
('0', 0),
|
||||||
('1', 1),
|
('1', 1),
|
||||||
('250000', 250000),
|
('250000', 250000),
|
||||||
pytest.param('foo', 'foo', marks=pytest.mark.xfail),
|
|
||||||
])
|
])
|
||||||
def test_should_set_sms_allowance(
|
def test_should_set_sms_allowance(
|
||||||
client_request,
|
client_request,
|
||||||
@@ -2929,6 +2947,34 @@ def test_should_set_sms_allowance(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@freeze_time("2017-04-01 11:09:00.061258")
|
||||||
|
@pytest.mark.parametrize('given_allowance, expected_api_argument', [
|
||||||
|
pytest.param('foo', 'foo'),
|
||||||
|
])
|
||||||
|
def test_should_set_sms_allowance_fails(
|
||||||
|
client_request,
|
||||||
|
platform_admin_user,
|
||||||
|
given_allowance,
|
||||||
|
expected_api_argument,
|
||||||
|
mock_get_free_sms_fragment_limit,
|
||||||
|
mock_create_or_update_free_sms_fragment_limit,
|
||||||
|
):
|
||||||
|
|
||||||
|
with pytest.raises(expected_exception=AssertionError):
|
||||||
|
client_request.login(platform_admin_user)
|
||||||
|
client_request.post(
|
||||||
|
'main.set_free_sms_allowance',
|
||||||
|
service_id=SERVICE_ONE_ID,
|
||||||
|
_data={
|
||||||
|
'free_sms_allowance': given_allowance,
|
||||||
|
},
|
||||||
|
_expected_redirect=url_for(
|
||||||
|
'main.service_settings',
|
||||||
|
service_id=SERVICE_ONE_ID,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_should_show_page_to_set_message_limit(
|
def test_should_show_page_to_set_message_limit(
|
||||||
client_request,
|
client_request,
|
||||||
platform_admin_user,
|
platform_admin_user,
|
||||||
@@ -3147,8 +3193,6 @@ def test_switch_service_enable_international_sms(
|
|||||||
[create_platform_admin_user(), True],
|
[create_platform_admin_user(), True],
|
||||||
[create_platform_admin_user(), False],
|
[create_platform_admin_user(), False],
|
||||||
[create_active_user_with_permissions(), True],
|
[create_active_user_with_permissions(), True],
|
||||||
pytest.param(create_active_user_with_permissions(), False, marks=pytest.mark.xfail),
|
|
||||||
pytest.param(create_active_user_no_settings_permission(), True, marks=pytest.mark.xfail),
|
|
||||||
))
|
))
|
||||||
def test_archive_service_after_confirm(
|
def test_archive_service_after_confirm(
|
||||||
client_request,
|
client_request,
|
||||||
@@ -3186,12 +3230,41 @@ def test_archive_service_after_confirm(
|
|||||||
assert call(f"user-{sample_uuid()}") in redis_delete_mock.call_args_list
|
assert call(f"user-{sample_uuid()}") in redis_delete_mock.call_args_list
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('user, is_trial_service', (
|
||||||
|
pytest.param(create_active_user_with_permissions(), False),
|
||||||
|
pytest.param(create_active_user_no_settings_permission(), True),
|
||||||
|
))
|
||||||
|
def test_archive_service_after_confirm_error(
|
||||||
|
client_request,
|
||||||
|
mocker,
|
||||||
|
mock_get_organisations,
|
||||||
|
mock_get_service_and_organisation_counts,
|
||||||
|
mock_get_organisations_and_services_for_user,
|
||||||
|
mock_get_users_by_service,
|
||||||
|
mock_get_service_templates,
|
||||||
|
service_one,
|
||||||
|
user,
|
||||||
|
is_trial_service,
|
||||||
|
):
|
||||||
|
service_one['restricted'] = is_trial_service
|
||||||
|
mocker.patch('app.service_api_client.post')
|
||||||
|
mocker.patch('app.main.views.service_settings.create_archive_service_event')
|
||||||
|
mocker.patch('app.notify_client.service_api_client.redis_client.delete')
|
||||||
|
mocker.patch('app.notify_client.service_api_client.redis_client.delete_by_pattern')
|
||||||
|
|
||||||
|
with pytest.raises(expected_exception=AssertionError):
|
||||||
|
client_request.login(user)
|
||||||
|
client_request.post(
|
||||||
|
'main.archive_service',
|
||||||
|
service_id=SERVICE_ONE_ID,
|
||||||
|
_follow_redirects=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('user, is_trial_service', (
|
@pytest.mark.parametrize('user, is_trial_service', (
|
||||||
[create_platform_admin_user(), True],
|
[create_platform_admin_user(), True],
|
||||||
[create_platform_admin_user(), False],
|
[create_platform_admin_user(), False],
|
||||||
[create_active_user_with_permissions(), True],
|
[create_active_user_with_permissions(), True],
|
||||||
pytest.param(create_active_user_with_permissions(), False, marks=pytest.mark.xfail),
|
|
||||||
pytest.param(create_active_user_no_settings_permission(), True, marks=pytest.mark.xfail),
|
|
||||||
))
|
))
|
||||||
def test_archive_service_prompts_user(
|
def test_archive_service_prompts_user(
|
||||||
client_request,
|
client_request,
|
||||||
@@ -3230,6 +3303,31 @@ def test_archive_service_prompts_user(
|
|||||||
assert mock_api.called is False
|
assert mock_api.called is False
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('user, is_trial_service', (
|
||||||
|
pytest.param(create_active_user_with_permissions(), False),
|
||||||
|
pytest.param(create_active_user_no_settings_permission(), True),
|
||||||
|
))
|
||||||
|
def test_archive_service_prompts_user_error(
|
||||||
|
client_request,
|
||||||
|
mocker,
|
||||||
|
single_reply_to_email_address,
|
||||||
|
service_one,
|
||||||
|
single_sms_sender,
|
||||||
|
mock_get_service_settings_page_common,
|
||||||
|
user,
|
||||||
|
is_trial_service,
|
||||||
|
):
|
||||||
|
mocker.patch('app.service_api_client.post')
|
||||||
|
service_one['restricted'] = is_trial_service
|
||||||
|
client_request.login(user)
|
||||||
|
|
||||||
|
with pytest.raises(expected_exception=AssertionError):
|
||||||
|
client_request.get(
|
||||||
|
'main.archive_service',
|
||||||
|
service_id=SERVICE_ONE_ID
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_cant_archive_inactive_service(
|
def test_cant_archive_inactive_service(
|
||||||
client_request,
|
client_request,
|
||||||
platform_admin_user,
|
platform_admin_user,
|
||||||
@@ -3251,7 +3349,6 @@ def test_cant_archive_inactive_service(
|
|||||||
|
|
||||||
@pytest.mark.parametrize('user', (
|
@pytest.mark.parametrize('user', (
|
||||||
create_platform_admin_user(),
|
create_platform_admin_user(),
|
||||||
pytest.param(create_active_user_with_permissions(), marks=pytest.mark.xfail),
|
|
||||||
))
|
))
|
||||||
def test_suspend_service_after_confirm(
|
def test_suspend_service_after_confirm(
|
||||||
client_request,
|
client_request,
|
||||||
@@ -3275,9 +3372,31 @@ def test_suspend_service_after_confirm(
|
|||||||
mock_event.assert_called_once_with(service_id=SERVICE_ONE_ID, suspended_by_id=user['id'])
|
mock_event.assert_called_once_with(service_id=SERVICE_ONE_ID, suspended_by_id=user['id'])
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('user', (
|
||||||
|
pytest.param(create_active_user_with_permissions()),
|
||||||
|
))
|
||||||
|
def test_suspend_service_after_confirm_error(
|
||||||
|
client_request,
|
||||||
|
user,
|
||||||
|
mocker,
|
||||||
|
):
|
||||||
|
mocker.patch('app.service_api_client.post')
|
||||||
|
mocker.patch('app.main.views.service_settings.create_suspend_service_event')
|
||||||
|
with pytest.raises(expected_exception=AssertionError):
|
||||||
|
client_request.login(user)
|
||||||
|
client_request.post(
|
||||||
|
'main.suspend_service',
|
||||||
|
service_id=SERVICE_ONE_ID,
|
||||||
|
_expected_redirect=url_for(
|
||||||
|
'main.service_settings',
|
||||||
|
service_id=SERVICE_ONE_ID,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('user', (
|
@pytest.mark.parametrize('user', (
|
||||||
create_platform_admin_user(),
|
create_platform_admin_user(),
|
||||||
pytest.param(create_active_user_with_permissions(), marks=pytest.mark.xfail),
|
pytest.param(create_active_user_with_permissions()),
|
||||||
))
|
))
|
||||||
def test_suspend_service_prompts_user(
|
def test_suspend_service_prompts_user(
|
||||||
client_request,
|
client_request,
|
||||||
@@ -3291,6 +3410,12 @@ def test_suspend_service_prompts_user(
|
|||||||
mock_api = mocker.patch('app.service_api_client.post')
|
mock_api = mocker.patch('app.service_api_client.post')
|
||||||
|
|
||||||
client_request.login(user)
|
client_request.login(user)
|
||||||
|
|
||||||
|
if user['email_address'] != 'platform@admin.gsa.gov':
|
||||||
|
with pytest.raises(expected_exception=AssertionError):
|
||||||
|
client_request.get('main.suspend_service', service_id=service_one['id'])
|
||||||
|
return
|
||||||
|
|
||||||
page = client_request.get('main.suspend_service', service_id=service_one['id'])
|
page = client_request.get('main.suspend_service', service_id=service_one['id'])
|
||||||
|
|
||||||
assert 'This will suspend the service and revoke all api keys. Are you sure you want to suspend this service?' in \
|
assert 'This will suspend the service and revoke all api keys. Are you sure you want to suspend this service?' in \
|
||||||
@@ -3319,7 +3444,7 @@ def test_cant_suspend_inactive_service(
|
|||||||
|
|
||||||
@pytest.mark.parametrize('user', (
|
@pytest.mark.parametrize('user', (
|
||||||
create_platform_admin_user(),
|
create_platform_admin_user(),
|
||||||
pytest.param(create_active_user_with_permissions(), marks=pytest.mark.xfail),
|
create_active_user_with_permissions(),
|
||||||
))
|
))
|
||||||
def test_resume_service_after_confirm(
|
def test_resume_service_after_confirm(
|
||||||
mocker,
|
mocker,
|
||||||
@@ -3332,6 +3457,14 @@ def test_resume_service_after_confirm(
|
|||||||
mock_event = mocker.patch('app.main.views.service_settings.create_resume_service_event')
|
mock_event = mocker.patch('app.main.views.service_settings.create_resume_service_event')
|
||||||
|
|
||||||
client_request.login(user)
|
client_request.login(user)
|
||||||
|
if user['email_address'] != "platform@admin.gsa.gov":
|
||||||
|
client_request.post(
|
||||||
|
'main.resume_service',
|
||||||
|
service_id=SERVICE_ONE_ID,
|
||||||
|
_expected_status=403,
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
client_request.post(
|
client_request.post(
|
||||||
'main.resume_service',
|
'main.resume_service',
|
||||||
service_id=SERVICE_ONE_ID,
|
service_id=SERVICE_ONE_ID,
|
||||||
@@ -3530,20 +3663,6 @@ def test_send_files_by_email_contact_details_does_not_update_invalid_contact_det
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('endpoint, permissions, expected_p', [
|
@pytest.mark.parametrize('endpoint, permissions, expected_p', [
|
||||||
# (
|
|
||||||
# 'main.service_set_inbound_sms',
|
|
||||||
# ['sms'],
|
|
||||||
# (
|
|
||||||
# 'Contact us if you want to be able to receive text messages from your users.'
|
|
||||||
# )
|
|
||||||
# ),
|
|
||||||
# (
|
|
||||||
# 'main.service_set_inbound_sms',
|
|
||||||
# ['sms', 'inbound_sms'],
|
|
||||||
# (
|
|
||||||
# 'Your service can receive text messages sent to 2028675301.'
|
|
||||||
# )
|
|
||||||
# ),
|
|
||||||
(
|
(
|
||||||
'main.service_set_auth_type',
|
'main.service_set_auth_type',
|
||||||
[],
|
[],
|
||||||
@@ -3771,7 +3890,6 @@ def test_update_service_organisation_does_not_update_if_same_value(
|
|||||||
@pytest.mark.skip(reason="Email currently deactivated")
|
@pytest.mark.skip(reason="Email currently deactivated")
|
||||||
@pytest.mark.parametrize('single_branding_option, expected_href', [
|
@pytest.mark.parametrize('single_branding_option, expected_href', [
|
||||||
(True, f'/services/{SERVICE_ONE_ID}/service-settings/email-branding/something-else'),
|
(True, f'/services/{SERVICE_ONE_ID}/service-settings/email-branding/something-else'),
|
||||||
# (False, f'/services/{SERVICE_ONE_ID}/service-settings/email-branding'),
|
|
||||||
])
|
])
|
||||||
def test_service_settings_links_to_branding_request_page_for_emails(
|
def test_service_settings_links_to_branding_request_page_for_emails(
|
||||||
service_one,
|
service_one,
|
||||||
@@ -3785,10 +3903,6 @@ def test_service_settings_links_to_branding_request_page_for_emails(
|
|||||||
# should only have a "something else" option
|
# should only have a "something else" option
|
||||||
# so we go straight to that form
|
# so we go straight to that form
|
||||||
service_one['organisation_type'] = 'other'
|
service_one['organisation_type'] = 'other'
|
||||||
# else:
|
|
||||||
# # expect to have a "NHS" option as well as the
|
|
||||||
# # fallback one, so ask user to choose
|
|
||||||
# service_one['organisation_type'] = 'nhs_central'
|
|
||||||
|
|
||||||
page = client_request.get(
|
page = client_request.get(
|
||||||
'.service_settings', service_id=SERVICE_ONE_ID
|
'.service_settings', service_id=SERVICE_ONE_ID
|
||||||
|
|||||||
@@ -28,14 +28,18 @@ def test_non_logged_in_user_can_see_homepage(
|
|||||||
'to your users. Try it now if you work in federal, state, or local government.'
|
'to your users. Try it now if you work in federal, state, or local government.'
|
||||||
)
|
)
|
||||||
|
|
||||||
assert normalize_spaces(page.select_one('#whos-using-notify').text) == (
|
# assert normalize_spaces(page.select_one('#whos-using-notify').text) == (
|
||||||
'Who’s using U.S. Notify '
|
# 'Who’s using U.S. Notify '
|
||||||
'There are 111 organizations and 9,999 services using Notify. '
|
# 'There are 111 organizations and 9,999 services using Notify. '
|
||||||
'See the list of services and organizations.'
|
# 'See the list of services and organizations.'
|
||||||
)
|
# )
|
||||||
assert page.select_one('#whos-using-notify a')['href'] == url_for(
|
# assert page.select_one('#whos-using-notify a')['href'] == url_for(
|
||||||
'main.performance'
|
# 'main.performance'
|
||||||
)
|
# )
|
||||||
|
|
||||||
|
# To be removed if we decide to use the "Who’s using Notify" link
|
||||||
|
anchor_tag = page.select_one('#whos-using-notify a')
|
||||||
|
assert anchor_tag is None
|
||||||
|
|
||||||
|
|
||||||
def test_logged_in_user_redirects_to_choose_account(
|
def test_logged_in_user_redirects_to_choose_account(
|
||||||
@@ -239,14 +243,13 @@ def test_css_is_served_from_correct_path(client_request):
|
|||||||
][index])
|
][index])
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skip(reason="Update for TTS")
|
|
||||||
def test_resources_that_use_asset_path_variable_have_correct_path(client_request):
|
def test_resources_that_use_asset_path_variable_have_correct_path(client_request):
|
||||||
|
|
||||||
page = client_request.get('main.documentation') # easy static page
|
page = client_request.get('main.documentation') # easy static page
|
||||||
|
|
||||||
logo_svg_fallback = page.select_one('.govuk-header__logotype-fallback-image')
|
logo_svg_fallback = page.select_one('.govuk-header__logotype-fallback-image')
|
||||||
|
|
||||||
assert logo_svg_fallback['src'].startswith('https://static.example.com/images/govuk-logotype.png')
|
assert logo_svg_fallback['src'].startswith('https://static.example.com/images/email-template/us-flag.png')
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('extra_args, email_branding_retrieved', (
|
@pytest.mark.parametrize('extra_args, email_branding_retrieved', (
|
||||||
|
|||||||
@@ -230,7 +230,7 @@ def test_should_show_job_with_sending_limit_exceeded_status(
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert normalize_spaces(page.select('main p')[1].text) == (
|
assert normalize_spaces(page.select('main p')[1].text) == (
|
||||||
"Notify cannot send these messages because you have reached your daily limit. You can only send 1,000 messages per day." # noqa
|
"Notify cannot send these messages because you have reached a limit. You can only send 1,000 messages per day and 250,000 messages in total." # noqa
|
||||||
)
|
)
|
||||||
assert normalize_spaces(page.select('main p')[2].text) == (
|
assert normalize_spaces(page.select('main p')[2].text) == (
|
||||||
"Upload this spreadsheet again tomorrow or contact the U.S. Notify team to raise the limit."
|
"Upload this spreadsheet again tomorrow or contact the U.S. Notify team to raise the limit."
|
||||||
@@ -245,16 +245,19 @@ def test_should_show_job_with_sending_limit_exceeded_status(
|
|||||||
)),
|
)),
|
||||||
# Just started
|
# Just started
|
||||||
(datetime(2020, 1, 10, 0, 0, 0), datetime(2020, 1, 10, 0, 0, 1), (
|
(datetime(2020, 1, 10, 0, 0, 0), datetime(2020, 1, 10, 0, 0, 1), (
|
||||||
'No messages to show yet…'
|
'No messages to show yet…'
|
||||||
)),
|
)),
|
||||||
# Created a while ago, just started
|
# Created a while ago, just started
|
||||||
(datetime(2020, 1, 1, 0, 0, 0), datetime(2020, 1, 10, 0, 0, 1), (
|
(datetime(2020, 1, 1, 0, 0, 0), datetime(2020, 1, 10, 0, 0, 1), (
|
||||||
'No messages to show yet…'
|
'No messages to show yet…'
|
||||||
)),
|
)),
|
||||||
# Created a while ago, started just within the last 24h
|
# Created a while ago, started just within the last 24h
|
||||||
(datetime(2020, 1, 1, 0, 0, 0), datetime(2020, 1, 9, 6, 0, 1), (
|
# TODO -- fails locally, should pass, tech debt due to timezone changes, re-evaluate after UTC changes
|
||||||
'No messages to show yet…'
|
pytest.param(
|
||||||
)),
|
datetime(2020, 1, 1, 0, 0, 0),
|
||||||
|
datetime(2020, 1, 9, 6, 0, 1),
|
||||||
|
('No messages to show yet…'),
|
||||||
|
),
|
||||||
# Created a while ago, started exactly 24h ago
|
# Created a while ago, started exactly 24h ago
|
||||||
# ---
|
# ---
|
||||||
# It doesn’t matter that 24h (1 day) and 7 days (the service’s data
|
# It doesn’t matter that 24h (1 day) and 7 days (the service’s data
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ def test_should_show_change_details_link(
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('number_of_users', (
|
@pytest.mark.parametrize('number_of_users', (
|
||||||
pytest.param(7, marks=pytest.mark.xfail),
|
pytest.param(7),
|
||||||
pytest.param(8),
|
pytest.param(8),
|
||||||
))
|
))
|
||||||
def test_should_show_live_search_if_more_than_7_users(
|
def test_should_show_live_search_if_more_than_7_users(
|
||||||
@@ -213,6 +213,13 @@ def test_should_show_live_search_if_more_than_7_users(
|
|||||||
|
|
||||||
page = client_request.get('main.manage_users', service_id=SERVICE_ONE_ID)
|
page = client_request.get('main.manage_users', service_id=SERVICE_ONE_ID)
|
||||||
|
|
||||||
|
if number_of_users == 7:
|
||||||
|
with pytest.raises(expected_exception=TypeError):
|
||||||
|
assert page.select_one('div[data-module=live-search]')['data-targets'] == (
|
||||||
|
".user-list-item"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
assert page.select_one('div[data-module=live-search]')['data-targets'] == (
|
assert page.select_one('div[data-module=live-search]')['data-targets'] == (
|
||||||
".user-list-item"
|
".user-list-item"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -9,99 +9,99 @@ from tests.conftest import normalize_spaces
|
|||||||
|
|
||||||
def _get_example_performance_data():
|
def _get_example_performance_data():
|
||||||
return {
|
return {
|
||||||
"total_notifications": 1_789_000_000,
|
"total_notifications": 1_789_000_000,
|
||||||
"email_notifications": 1_123_000_000,
|
"email_notifications": 1_123_000_000,
|
||||||
"sms_notifications": 987_654_321,
|
"sms_notifications": 987_654_321,
|
||||||
"live_service_count": random.randrange(1, 1000),
|
"live_service_count": random.randrange(1, 1000),
|
||||||
"notifications_by_type": [
|
"notifications_by_type": [
|
||||||
{
|
{
|
||||||
"date": "2021-02-21",
|
"date": "2021-02-21",
|
||||||
"emails": 1_234_567, "sms": 123_456,
|
"emails": 1_234_567, "sms": 123_456,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"date": "2021-02-22",
|
"date": "2021-02-22",
|
||||||
"emails": 1, "sms": 2,
|
"emails": 1, "sms": 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"date": "2021-02-23",
|
"date": "2021-02-23",
|
||||||
"emails": 1, "sms": 2,
|
"emails": 1, "sms": 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"date": "2021-02-24",
|
"date": "2021-02-24",
|
||||||
"emails": 1, "sms": 2,
|
"emails": 1, "sms": 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"date": "2021-02-25",
|
"date": "2021-02-25",
|
||||||
"emails": 1, "sms": 2,
|
"emails": 1, "sms": 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"date": "2021-02-26",
|
"date": "2021-02-26",
|
||||||
"emails": 1, "sms": 2,
|
"emails": 1, "sms": 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"date": "2021-02-27",
|
"date": "2021-02-27",
|
||||||
"emails": 1, "sms": 2,
|
"emails": 1, "sms": 2,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"processing_time": [
|
"processing_time": [
|
||||||
{
|
{
|
||||||
"date": "2021-02-21",
|
"date": "2021-02-21",
|
||||||
"percentage_under_10_seconds": 99.25
|
"percentage_under_10_seconds": 99.25
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"date": "2021-02-22",
|
"date": "2021-02-22",
|
||||||
"percentage_under_10_seconds": 95.30
|
"percentage_under_10_seconds": 95.30
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"date": "2021-02-23",
|
"date": "2021-02-23",
|
||||||
"percentage_under_10_seconds": 95.0
|
"percentage_under_10_seconds": 95.0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"date": "2021-02-24",
|
"date": "2021-02-24",
|
||||||
"percentage_under_10_seconds": 100.0
|
"percentage_under_10_seconds": 100.0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"date": "2021-02-25",
|
"date": "2021-02-25",
|
||||||
"percentage_under_10_seconds": 99.99
|
"percentage_under_10_seconds": 99.99
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"date": "2021-02-26",
|
"date": "2021-02-26",
|
||||||
"percentage_under_10_seconds": 100.0
|
"percentage_under_10_seconds": 100.0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"date": "2021-02-27",
|
"date": "2021-02-27",
|
||||||
"percentage_under_10_seconds": 98.60
|
"percentage_under_10_seconds": 98.60
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
"services_using_notify": [
|
"services_using_notify": [
|
||||||
{
|
{
|
||||||
"organisation_id": uuid.uuid4(),
|
"organisation_id": uuid.uuid4(),
|
||||||
"organisation_name": "Department of Examples and Patterns",
|
"organisation_name": "Department of Examples and Patterns",
|
||||||
"service_id": uuid.uuid4(),
|
"service_id": uuid.uuid4(),
|
||||||
"service_name": "Example service"
|
"service_name": "Example service"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"organisation_id": uuid.uuid4(),
|
"organisation_id": uuid.uuid4(),
|
||||||
"organisation_name": "Department of Examples and Patterns",
|
"organisation_name": "Department of Examples and Patterns",
|
||||||
"service_id": uuid.uuid4(),
|
"service_id": uuid.uuid4(),
|
||||||
"service_name": "Example service 2"
|
"service_name": "Example service 2"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"organisation_id": uuid.uuid4(),
|
"organisation_id": uuid.uuid4(),
|
||||||
"organisation_name": "Department of One Service",
|
"organisation_name": "Department of One Service",
|
||||||
"service_id": uuid.uuid4(),
|
"service_id": uuid.uuid4(),
|
||||||
"service_name": "Example service 3"
|
"service_name": "Example service 3"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
# On production there should be no live services without an
|
# On production there should be no live services without an
|
||||||
# organisation, but this isn’t always true in people’s local
|
# organisation, but this isn’t always true in people’s local
|
||||||
# environments
|
# environments
|
||||||
"organisation_id": None,
|
"organisation_id": None,
|
||||||
"organisation_name": None,
|
"organisation_name": None,
|
||||||
"service_id": uuid.uuid4(),
|
"service_id": uuid.uuid4(),
|
||||||
"service_name": "Example service 4"
|
"service_name": "Example service 4"
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -123,12 +123,12 @@ def test_should_render_performance_page(
|
|||||||
assert normalize_spaces(page.select_one('main').text) == (
|
assert normalize_spaces(page.select_one('main').text) == (
|
||||||
'Performance data '
|
'Performance data '
|
||||||
''
|
''
|
||||||
'Messages sent since May 2016 '
|
'Messages sent since May 2023 '
|
||||||
'1.8 billion total '
|
'1.8 billion total '
|
||||||
'1.1 billion emails '
|
'1.1 billion emails '
|
||||||
'987.7 million text messages '
|
'987.7 million text messages '
|
||||||
''
|
''
|
||||||
'Messages sent since May 2016 '
|
'Messages sent since May 2023 '
|
||||||
'Date Emails Text messages '
|
'Date Emails Text messages '
|
||||||
'26 February 2021 1 2 '
|
'26 February 2021 1 2 '
|
||||||
'25 February 2021 1 2 '
|
'25 February 2021 1 2 '
|
||||||
|
|||||||
@@ -2172,9 +2172,7 @@ def test_check_messages_shows_trial_mode_error(
|
|||||||
|
|
||||||
@pytest.mark.parametrize('uploaded_file_name', (
|
@pytest.mark.parametrize('uploaded_file_name', (
|
||||||
pytest.param('applicants.ods'), # normal job
|
pytest.param('applicants.ods'), # normal job
|
||||||
pytest.param('thisisatest.csv', marks=pytest.mark.xfail), # different template version
|
|
||||||
pytest.param('send_me_later.csv'), # should look at scheduled job
|
pytest.param('send_me_later.csv'), # should look at scheduled job
|
||||||
pytest.param('full_of_regret.csv', marks=pytest.mark.xfail), # job is cancelled
|
|
||||||
))
|
))
|
||||||
def test_warns_if_file_sent_already(
|
def test_warns_if_file_sent_already(
|
||||||
client_request,
|
client_request,
|
||||||
@@ -2215,6 +2213,51 @@ def test_warns_if_file_sent_already(
|
|||||||
mock_get_jobs.assert_called_once_with(SERVICE_ONE_ID, limit_days=0)
|
mock_get_jobs.assert_called_once_with(SERVICE_ONE_ID, limit_days=0)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('uploaded_file_name', (
|
||||||
|
pytest.param('thisisatest.csv'), # different template version
|
||||||
|
pytest.param('full_of_regret.csv'), # job is cancelled
|
||||||
|
))
|
||||||
|
def test_warns_if_file_sent_already_errors(
|
||||||
|
client_request,
|
||||||
|
mock_get_users_by_service,
|
||||||
|
mock_get_live_service,
|
||||||
|
mock_get_service_template,
|
||||||
|
mock_has_permissions,
|
||||||
|
mock_get_service_statistics,
|
||||||
|
mock_get_job_doesnt_exist,
|
||||||
|
mock_get_jobs,
|
||||||
|
fake_uuid,
|
||||||
|
mocker,
|
||||||
|
uploaded_file_name,
|
||||||
|
):
|
||||||
|
mocker.patch('app.main.views.send.s3download', return_value=(
|
||||||
|
'phone number,\n2028675209'
|
||||||
|
))
|
||||||
|
mocker.patch(
|
||||||
|
'app.main.views.send.get_csv_metadata',
|
||||||
|
return_value={'original_file_name': uploaded_file_name},
|
||||||
|
)
|
||||||
|
# Should be botocore.errorfactory.NoSuchKey but for some reason can't use that
|
||||||
|
with pytest.raises(expected_exception=Exception):
|
||||||
|
page = client_request.get(
|
||||||
|
'main.check_messages',
|
||||||
|
service_id=SERVICE_ONE_ID,
|
||||||
|
template_id="5d729fbd-239c-44ab-b498-75a985f3198f",
|
||||||
|
upload_id=fake_uuid,
|
||||||
|
original_file_name=uploaded_file_name,
|
||||||
|
_test_page_title=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert normalize_spaces(
|
||||||
|
page.select_one('.banner-dangerous').text
|
||||||
|
) == (
|
||||||
|
'These messages have already been sent today '
|
||||||
|
'If you need to resend them, rename the file and upload it again.'
|
||||||
|
)
|
||||||
|
|
||||||
|
mock_get_jobs.assert_called_once_with(SERVICE_ONE_ID, limit_days=0)
|
||||||
|
|
||||||
|
|
||||||
def test_check_messages_column_error_doesnt_show_optional_columns(
|
def test_check_messages_column_error_doesnt_show_optional_columns(
|
||||||
mocker,
|
mocker,
|
||||||
client_request,
|
client_request,
|
||||||
|
|||||||
@@ -985,14 +985,6 @@ def test_delete_folder(
|
|||||||
pytest.param(
|
pytest.param(
|
||||||
create_active_user_with_permissions()
|
create_active_user_with_permissions()
|
||||||
),
|
),
|
||||||
pytest.param(
|
|
||||||
create_active_user_view_permissions(),
|
|
||||||
marks=pytest.mark.xfail(raises=AssertionError)
|
|
||||||
),
|
|
||||||
pytest.param(
|
|
||||||
create_active_caseworking_user(),
|
|
||||||
marks=pytest.mark.xfail(raises=AssertionError)
|
|
||||||
),
|
|
||||||
])
|
])
|
||||||
def test_should_show_checkboxes_for_selecting_templates(
|
def test_should_show_checkboxes_for_selecting_templates(
|
||||||
client_request,
|
client_request,
|
||||||
@@ -1022,6 +1014,43 @@ def test_should_show_checkboxes_for_selecting_templates(
|
|||||||
assert TEMPLATE_ONE_ID not in checkboxes[index]['id']
|
assert TEMPLATE_ONE_ID not in checkboxes[index]['id']
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('user', [
|
||||||
|
pytest.param(
|
||||||
|
create_active_user_view_permissions(),
|
||||||
|
),
|
||||||
|
pytest.param(
|
||||||
|
create_active_caseworking_user(),
|
||||||
|
),
|
||||||
|
])
|
||||||
|
def test_should_show_checkboxes_for_selecting_templates_assertion_error(
|
||||||
|
client_request,
|
||||||
|
mocker,
|
||||||
|
service_one,
|
||||||
|
mock_get_service_templates,
|
||||||
|
mock_get_template_folders,
|
||||||
|
mock_has_no_jobs,
|
||||||
|
mock_get_no_api_keys,
|
||||||
|
user,
|
||||||
|
):
|
||||||
|
with pytest.raises(expected_exception=AssertionError):
|
||||||
|
client_request.login(user)
|
||||||
|
|
||||||
|
page = client_request.get(
|
||||||
|
'main.choose_template',
|
||||||
|
service_id=SERVICE_ONE_ID,
|
||||||
|
)
|
||||||
|
checkboxes = page.select('input[name=templates_and_folders]')
|
||||||
|
|
||||||
|
assert len(checkboxes) == 4
|
||||||
|
|
||||||
|
assert checkboxes[0]['value'] == TEMPLATE_ONE_ID
|
||||||
|
assert checkboxes[0]['id'] == 'templates-or-folder-{}'.format(TEMPLATE_ONE_ID)
|
||||||
|
|
||||||
|
for index in (1, 2, 3):
|
||||||
|
assert checkboxes[index]['value'] != TEMPLATE_ONE_ID
|
||||||
|
assert TEMPLATE_ONE_ID not in checkboxes[index]['id']
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('user', [
|
@pytest.mark.parametrize('user', [
|
||||||
create_active_user_view_permissions(),
|
create_active_user_view_permissions(),
|
||||||
create_active_caseworking_user(),
|
create_active_caseworking_user(),
|
||||||
|
|||||||
@@ -352,11 +352,11 @@ def test_all_endpoints_are_covered(navigation_instance):
|
|||||||
navigation_instances,
|
navigation_instances,
|
||||||
ids=(x.__class__.__name__ for x in navigation_instances)
|
ids=(x.__class__.__name__ for x in navigation_instances)
|
||||||
)
|
)
|
||||||
@pytest.mark.xfail(raises=KeyError)
|
|
||||||
def test_raises_on_invalid_navigation_item(
|
def test_raises_on_invalid_navigation_item(
|
||||||
client_request, navigation_instance
|
client_request, navigation_instance
|
||||||
):
|
):
|
||||||
navigation_instance.is_selected('foo')
|
with pytest.raises(expected_exception=KeyError):
|
||||||
|
navigation_instance.is_selected('foo')
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('endpoint, selected_nav_item', [
|
@pytest.mark.parametrize('endpoint, selected_nav_item', [
|
||||||
|
|||||||
@@ -6,10 +6,6 @@ from app.utils.user import user_has_permissions
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('permissions', (
|
@pytest.mark.parametrize('permissions', (
|
||||||
pytest.param([
|
|
||||||
# Route has a permission which the user doesn’t have
|
|
||||||
'send_messages'
|
|
||||||
], marks=pytest.mark.xfail(raises=Forbidden)),
|
|
||||||
[
|
[
|
||||||
# Route has one of the permissions which the user has
|
# Route has one of the permissions which the user has
|
||||||
'manage_service'
|
'manage_service'
|
||||||
@@ -45,6 +41,32 @@ def test_permissions(
|
|||||||
index()
|
index()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('permissions', (
|
||||||
|
[
|
||||||
|
# Route has a permission which the user doesn’t have
|
||||||
|
'send_messages'
|
||||||
|
],
|
||||||
|
))
|
||||||
|
def test_permissions_forbidden(
|
||||||
|
client_request,
|
||||||
|
permissions,
|
||||||
|
api_user_active,
|
||||||
|
):
|
||||||
|
request.view_args.update({'service_id': 'foo'})
|
||||||
|
|
||||||
|
api_user_active['permissions'] = {'foo': ['manage_users', 'manage_templates', 'manage_settings']}
|
||||||
|
api_user_active['services'] = ['foo', 'bar']
|
||||||
|
|
||||||
|
client_request.login(api_user_active)
|
||||||
|
|
||||||
|
@user_has_permissions(*permissions)
|
||||||
|
def index():
|
||||||
|
pass
|
||||||
|
|
||||||
|
with pytest.raises(expected_exception=Forbidden):
|
||||||
|
index()
|
||||||
|
|
||||||
|
|
||||||
def test_restrict_admin_usage(
|
def test_restrict_admin_usage(
|
||||||
client_request,
|
client_request,
|
||||||
platform_admin_user,
|
platform_admin_user,
|
||||||
|
|||||||
Reference in New Issue
Block a user