Update wagtail, django and wagtail_factories

Also make some changes according to the migration guides of those
packages.
This commit is contained in:
Ramon Wenger 2023-12-06 23:27:40 +01:00
parent 1e79e7ba38
commit 6f563806f7
12 changed files with 463 additions and 415 deletions

26
Pipfile
View File

@ -14,21 +14,20 @@ django-silk = "*"
black = "*" black = "*"
[packages] [packages]
factory-boy = "==2.11.0" factory-boy = "~=3.3"
wagtail_factories = "==2.0.0" wagtail_factories = "~=4.0"
django = "==3.2.16" django = "~=4.2"
whitenoise = "~=5.3" whitenoise = "~=6.6"
psycopg2-binary = "==2.9.3" psycopg2-binary = "==2.9.3"
gunicorn = "==19.10.0" gunicorn = "~=21.2.0"
python-dotenv = "==0.13.0" python-dotenv = "~=1.0.0"
dj-database-url = "==0.4.1" dj-database-url = "~=2.1.0"
raven = "==6.9.0"
django-extensions = "*" django-extensions = "*"
graphene-django = "==2.15.0" graphene-django = "*"
django-filter = "~=21.1" django-filter = "*"
djangorestframework = "~=3.8" djangorestframework = "*"
pillow = "==9.1.0" pillow = "==9.1.0"
wagtail = "~=4.2" wagtail = "==5.0.5"
django-cors-headers = "~=3.0" django-cors-headers = "~=3.0"
django-storages = "*" django-storages = "*"
boto3 = "*" boto3 = "*"
@ -36,8 +35,7 @@ django-compressor = "*"
django-libsass = "*" django-libsass = "*"
bleach = "*" bleach = "*"
newrelic = "*" newrelic = "*"
sentry-sdk = "==1.38.0" sentry-sdk = "~=1.38.0"
python-http-client = "==3.2.1"
ipython = "*" ipython = "*"
requests = "*" requests = "*"
unittest-xml-reporting = "*" unittest-xml-reporting = "*"

222
Pipfile.lock generated
View File

@ -1,7 +1,7 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "206150258b8979912bf9986f82049bdb1530666d5e9f7997e1c4acbe56c7eaf2" "sha256": "26df7fc2ce976c8437910e196f69cd281d39b7cd5551c9fbf7a298d14d3cf531"
}, },
"pipfile-spec": 6, "pipfile-spec": 6,
"requires": { "requires": {
@ -18,10 +18,10 @@
"default": { "default": {
"aniso8601": { "aniso8601": {
"hashes": [ "hashes": [
"sha256:513d2b6637b7853806ae79ffaca6f3e8754bdd547048f5ccc1420aec4b714f1e", "sha256:1d2b7ef82963909e93c4f24ce48d4de9e66009a21bf1c1e1c85bdd0812fe412f",
"sha256:d10a4bf949f619f719b227ef5386e31f49a2b6d453004b21f02661ccc8670c7b" "sha256:72e3117667eedf66951bb2d93f4296a56b94b078a8a95905a052611fb3f1b973"
], ],
"version": "==7.0.0" "version": "==9.0.1"
}, },
"anyascii": { "anyascii": {
"hashes": [ "hashes": [
@ -36,7 +36,7 @@
"sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e", "sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e",
"sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed" "sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed"
], ],
"markers": "python_full_version >= '3.7.0'", "markers": "python_version >= '3.7'",
"version": "==3.7.2" "version": "==3.7.2"
}, },
"asttokens": { "asttokens": {
@ -104,19 +104,19 @@
}, },
"boto3": { "boto3": {
"hashes": [ "hashes": [
"sha256:b8c818125489fc0371ef28d806d36d8f1dcb71734fcb0d96b3201563e3e86f22", "sha256:9486f66f9a89f66d64d25cb4baa55aad323a1734ef9815b7a2c4c0787a3fc1fb",
"sha256:d02a084b25aa8d46ef917b128e90877efab1ba45f9d1ba3a11f336930378e350" "sha256:baa6ea61527bcc82365a4ef365aa8f34126483ff8533d01274f3cdb340c22d73"
], ],
"index": "pypi", "index": "pypi",
"version": "==1.33.8" "version": "==1.33.9"
}, },
"botocore": { "botocore": {
"hashes": [ "hashes": [
"sha256:90236e6e69d7e80875d7f9d39383630706edbc1298026698c6c70d9b6a65576e", "sha256:07ff4eea62f546da540310887000c81fca802c788eb374fef06eda28009dcafd",
"sha256:e6970bf89cbe2624399aeffce52c253917d8e5a1c671de4054557603ab56c922" "sha256:1b90be11dd9a9a25290c995a6b713e76b9e2bf7bf86ba9036e0d28f2ceb2edfc"
], ],
"markers": "python_full_version >= '3.7.0'", "markers": "python_version >= '3.7'",
"version": "==1.33.8" "version": "==1.33.9"
}, },
"certifi": { "certifi": {
"hashes": [ "hashes": [
@ -277,7 +277,7 @@
"sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519",
"sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561" "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"
], ],
"markers": "python_full_version >= '3.7.0'", "markers": "python_version >= '3.7'",
"version": "==3.3.2" "version": "==3.3.2"
}, },
"click": { "click": {
@ -285,7 +285,7 @@
"sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28",
"sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"
], ],
"markers": "python_full_version >= '3.7.0'", "markers": "python_version >= '3.7'",
"version": "==8.1.7" "version": "==8.1.7"
}, },
"coverage": { "coverage": {
@ -375,7 +375,7 @@
"sha256:e3114da6d7f95d2dee7d3f4eec16dacff819740bbab931aff8648cb13c5ff5e7", "sha256:e3114da6d7f95d2dee7d3f4eec16dacff819740bbab931aff8648cb13c5ff5e7",
"sha256:f983596065a18a2183e7f79ab3fd4c475205b839e02cbc0efbbf9666c4b3083d" "sha256:f983596065a18a2183e7f79ab3fd4c475205b839e02cbc0efbbf9666c4b3083d"
], ],
"markers": "python_full_version >= '3.7.0'", "markers": "python_version >= '3.7'",
"version": "==41.0.7" "version": "==41.0.7"
}, },
"decorator": { "decorator": {
@ -386,27 +386,36 @@
"markers": "python_version >= '3.5'", "markers": "python_version >= '3.5'",
"version": "==5.1.1" "version": "==5.1.1"
}, },
"defusedxml": {
"hashes": [
"sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69",
"sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
"version": "==0.7.1"
},
"dj-database-url": { "dj-database-url": {
"hashes": [ "hashes": [
"sha256:7f4c78d2a090df8dfaf56d5d3ff7bbee17360436e4879558317e2314424864cd" "sha256:04bc34b248d4c21aaa13e4ab419ae6575ef5f10f3df735ce7da97722caa356e0",
"sha256:f2042cefe1086e539c9da39fad5ad7f61173bf79665e69bf7e4de55fa88b135f"
], ],
"index": "pypi", "index": "pypi",
"version": "==0.4.1" "version": "==2.1.0"
}, },
"django": { "django": {
"hashes": [ "hashes": [
"sha256:18ba8efa36b69cfcd4b670d0fa187c6fe7506596f0ababe580e16909bcdec121", "sha256:6cb5dcea9e3d12c47834d32156b8841f533a4493c688e2718cafd51aa430ba6d",
"sha256:3adc285124244724a394fa9b9839cc8cd116faf7d159554c43ecdaa8cdf0b94d" "sha256:d69d5e36cc5d9f4eb4872be36c622878afcdce94062716cf3e25bcedcb168b62"
], ],
"index": "pypi", "index": "pypi",
"version": "==3.2.16" "version": "==4.2.8"
}, },
"django-appconf": { "django-appconf": {
"hashes": [ "hashes": [
"sha256:c3ae442fba1ff7ec830412c5184b17169a7a1e71cf0864a4c3f93cf4c98a1993", "sha256:c3ae442fba1ff7ec830412c5184b17169a7a1e71cf0864a4c3f93cf4c98a1993",
"sha256:cfe87ea827c4ee04b9a70fab90b86d704cb02f2981f89da8423cb0fabf88efbf" "sha256:cfe87ea827c4ee04b9a70fab90b86d704cb02f2981f89da8423cb0fabf88efbf"
], ],
"markers": "python_full_version >= '3.7.0'", "markers": "python_version >= '3.7'",
"version": "==1.0.6" "version": "==1.0.6"
}, },
"django-compressor": { "django-compressor": {
@ -435,11 +444,11 @@
}, },
"django-filter": { "django-filter": {
"hashes": [ "hashes": [
"sha256:632a251fa8f1aadb4b8cceff932bb52fe2f826dd7dfe7f3eac40e5c463d6836e", "sha256:ed429e34760127e3520a67f415bec4c905d4649fbe45d0d6da37e6ff5e0287eb",
"sha256:f4a6737a30104c98d2e2a5fb93043f36dd7978e0c7ddc92f5998e85433ea5063" "sha256:ed473b76e84f7e83b2511bb2050c3efb36d135207d0128dfe3ae4b36e3594ba5"
], ],
"index": "pypi", "index": "pypi",
"version": "==21.1" "version": "==22.1"
}, },
"django-libsass": { "django-libsass": {
"hashes": [ "hashes": [
@ -462,7 +471,7 @@
"sha256:4340bb20c4477fffb13b4cc5cccf9f1b1010b64f79956c291c72d2ad2ed243f8", "sha256:4340bb20c4477fffb13b4cc5cccf9f1b1010b64f79956c291c72d2ad2ed243f8",
"sha256:d341a961a27cc77fde8cc42141c6ab55cc1f0cb886963cc2d6967b9674fa47d6" "sha256:d341a961a27cc77fde8cc42141c6ab55cc1f0cb886963cc2d6967b9674fa47d6"
], ],
"markers": "python_full_version >= '3.7.0'", "markers": "python_version >= '3.7'",
"version": "==0.1" "version": "==0.1"
}, },
"django-silk": { "django-silk": {
@ -544,7 +553,7 @@
"sha256:88256416ae766bc9e8895c76a87928c0012183da3cc4fc18016e6f050e025f41", "sha256:88256416ae766bc9e8895c76a87928c0012183da3cc4fc18016e6f050e025f41",
"sha256:cc59bc4423742fd71ad227122eb0dd44db51efb3dc4095b45ac9a08c770096af" "sha256:cc59bc4423742fd71ad227122eb0dd44db51efb3dc4095b45ac9a08c770096af"
], ],
"markers": "python_full_version >= '3.7.0'", "markers": "python_version >= '3.7'",
"version": "==2.0.2" "version": "==2.0.2"
}, },
"executing": { "executing": {
@ -557,11 +566,11 @@
}, },
"factory-boy": { "factory-boy": {
"hashes": [ "hashes": [
"sha256:3763ecabafb341df75b82f3a80c40747adef32d0288282c0c2db7a13e53c6944", "sha256:a2cdbdb63228177aa4f1c52f4b6d83fab2b8623bf602c7dedd7eb83c0f69c04c",
"sha256:d0f7209473312c99dfcf154069a1c559d83cfcae0979af43cf8779c9a9f645b3" "sha256:bc76d97d1a65bbd9842a6d722882098eb549ec8ee1081f9fb2e8ff29f0c300f1"
], ],
"index": "pypi", "index": "pypi",
"version": "==2.11.0" "version": "==3.3.0"
}, },
"faker": { "faker": {
"hashes": [ "hashes": [
@ -571,6 +580,13 @@
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==20.1.0" "version": "==20.1.0"
}, },
"filetype": {
"hashes": [
"sha256:66b56cd6474bf41d8c54660347d37afcc3f7d1970648de365c102ef77548aadb",
"sha256:7ce71b6880181241cf7ac8697a2f1eb6a8bd9b429f7ad6d27b8db9ba5f1c2d25"
],
"version": "==1.2.0"
},
"gprof2dot": { "gprof2dot": {
"hashes": [ "hashes": [
"sha256:45b4d298bd36608fccf9511c3fd88a773f7a1abc04d6cd39445b11ba43133ec5", "sha256:45b4d298bd36608fccf9511c3fd88a773f7a1abc04d6cd39445b11ba43133ec5",
@ -581,40 +597,42 @@
}, },
"graphene": { "graphene": {
"hashes": [ "hashes": [
"sha256:3d446eb1237c551052bc31155cf1a3a607053e4f58c9172b83a1b597beaa0868", "sha256:529bf40c2a698954217d3713c6041d69d3f719ad0080857d7ee31327112446b0",
"sha256:b9f2850e064eebfee9a3ef4a1f8aa0742848d97652173ab44c82cc8a62b9ed93" "sha256:bb3810be33b54cb3e6969506671eb72319e8d7ba0d5ca9c8066472f75bf35a38"
], ],
"version": "==2.1.9" "version": "==3.3"
}, },
"graphene-django": { "graphene-django": {
"hashes": [ "hashes": [
"sha256:02671d195f0c09c8649acff2a8f4ad4f297d0f7d98ea6e6cdf034b81bab92880", "sha256:2e42742fae21fa50e514f3acae26a9bc6cb5e51c179a97b3db5390ff258ca816",
"sha256:b78c9b05bc899016b9cc5bf13faa1f37fe1faa8c5407552c6ddd1a28f46fc31a" "sha256:abe42f820b9731d94bebff6d73088d0dc2ffb8c8863a6d7bf3d378412d866a3b"
], ],
"index": "pypi", "index": "pypi",
"version": "==2.15.0" "version": "==3.1.5"
}, },
"graphql-core": { "graphql-core": {
"hashes": [ "hashes": [
"sha256:44c9bac4514e5e30c5a595fac8e3c76c1975cae14db215e8174c7fe995825bad", "sha256:06d2aad0ac723e35b1cb47885d3e5c45e956a53bc1b209a9fc5369007fe46676",
"sha256:aac46a9ac524c9855910c14c48fc5d60474def7f99fd10245e76608eba7af746" "sha256:5766780452bd5ec8ba133f8bf287dc92713e3868ddd83aee4faab9fc3e303dc3"
], ],
"version": "==2.3.2" "markers": "python_version >= '3.6' and python_version < '4'",
"version": "==3.2.3"
}, },
"graphql-relay": { "graphql-relay": {
"hashes": [ "hashes": [
"sha256:870b6b5304123a38a0b215a79eace021acce5a466bf40cd39fa18cb8528afabb", "sha256:1ff1c51298356e481a0be009ccdff249832ce53f30559c1338f22a0e0d17250c",
"sha256:ac514cb86db9a43014d7e73511d521137ac12cf0101b2eaa5f0a3da2e10d913d" "sha256:c9b22bd28b170ba1fe674c74384a8ff30a76c8e26f88ac3aa1584dd3179953e5"
], ],
"version": "==2.0.1" "markers": "python_version >= '3.6' and python_version < '4'",
"version": "==3.2.0"
}, },
"gunicorn": { "gunicorn": {
"hashes": [ "hashes": [
"sha256:c3930fe8de6778ab5ea716cab432ae6335fa9f03b3f2c3e02529214c476f4bcb", "sha256:3213aa5e8c24949e792bcacfc176fef362e7aac80b76c56f6b5122bf350722f0",
"sha256:f9de24e358b841567063629cd0a656b26792a41e23a24d0dcb40224fc3940081" "sha256:88ec8bff1d634f98e61b9f65bc4bf3cd918a90806c6f5c48bc5603849ec81033"
], ],
"index": "pypi", "index": "pypi",
"version": "==19.10.0" "version": "==21.2.0"
}, },
"html5lib": { "html5lib": {
"hashes": [ "hashes": [
@ -637,7 +655,7 @@
"sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3",
"sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374" "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"
], ],
"markers": "python_full_version >= '3.7.0'", "markers": "python_version >= '3.7'",
"version": "==2.0.0" "version": "==2.0.0"
}, },
"ipython": { "ipython": {
@ -661,7 +679,7 @@
"sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980", "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980",
"sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe" "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe"
], ],
"markers": "python_full_version >= '3.7.0'", "markers": "python_version >= '3.7'",
"version": "==1.0.1" "version": "==1.0.1"
}, },
"l18n": { "l18n": {
@ -862,7 +880,7 @@
"sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5", "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5",
"sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7" "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"
], ],
"markers": "python_full_version >= '3.7.0'", "markers": "python_version >= '3.7'",
"version": "==23.2" "version": "==23.2"
}, },
"parso": { "parso": {
@ -878,7 +896,7 @@
"sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20", "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20",
"sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3" "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"
], ],
"markers": "python_full_version >= '3.7.0'", "markers": "python_version >= '3.7'",
"version": "==0.11.2" "version": "==0.11.2"
}, },
"pexpect": { "pexpect": {
@ -960,7 +978,7 @@
"sha256:941367d97fc815548822aa26c2a269fdc4eb21e9ec05fc5d447cf09bad5d75f0", "sha256:941367d97fc815548822aa26c2a269fdc4eb21e9ec05fc5d447cf09bad5d75f0",
"sha256:f36fe301fafb7470e86aaf90f036eef600a3210be4decf461a5b1ca8403d3cb2" "sha256:f36fe301fafb7470e86aaf90f036eef600a3210be4decf461a5b1ca8403d3cb2"
], ],
"markers": "python_full_version >= '3.7.0'", "markers": "python_version >= '3.7'",
"version": "==3.0.41" "version": "==3.0.41"
}, },
"psycopg2-binary": { "psycopg2-binary": {
@ -1062,7 +1080,7 @@
"sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c", "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c",
"sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367" "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"
], ],
"markers": "python_full_version >= '3.7.0'", "markers": "python_version >= '3.7'",
"version": "==2.17.2" "version": "==2.17.2"
}, },
"pytest": { "pytest": {
@ -1070,7 +1088,7 @@
"sha256:0d009c083ea859a71b76adf7c1d502e4bc170b80a8ef002da5806527b9591fac", "sha256:0d009c083ea859a71b76adf7c1d502e4bc170b80a8ef002da5806527b9591fac",
"sha256:d989d136982de4e3b29dabcc838ad581c64e8ed52c11fbe86ddebd9da0818cd5" "sha256:d989d136982de4e3b29dabcc838ad581c64e8ed52c11fbe86ddebd9da0818cd5"
], ],
"markers": "python_full_version >= '3.7.0'", "markers": "python_version >= '3.7'",
"version": "==7.4.3" "version": "==7.4.3"
}, },
"pytest-cov": { "pytest-cov": {
@ -1107,20 +1125,11 @@
}, },
"python-dotenv": { "python-dotenv": {
"hashes": [ "hashes": [
"sha256:25c0ff1a3e12f4bde8d592cc254ab075cfe734fc5dd989036716fd17ee7e5ec7", "sha256:a8df96034aae6d2d50a4ebe8216326c61c3eb64836776504fcca410e5937a3ba",
"sha256:3b9909bc96b0edc6b01586e1eed05e71174ef4e04c71da5786370cebea53ad74" "sha256:f5971a9226b701070a4bf2c38c89e5a3f0d64de8debda981d1db98583009122a"
], ],
"index": "pypi", "index": "pypi",
"version": "==0.13.0" "version": "==1.0.0"
},
"python-http-client": {
"hashes": [
"sha256:01f58f1871612fdce6a4545df7c867a6d1457695652a7ca48d5c22e5bf57628d",
"sha256:c2776054245db376ea26c859b80e9280b1a470b96ed998d60d35951f89bbbe79",
"sha256:e455ae0dfd5819ac483f7fecf08ab8693048d9dc47a0a6fe0d4aebf86d9d1d17"
],
"index": "pypi",
"version": "==3.2.1"
}, },
"pytz": { "pytz": {
"hashes": [ "hashes": [
@ -1129,14 +1138,6 @@
], ],
"version": "==2023.3.post1" "version": "==2023.3.post1"
}, },
"raven": {
"hashes": [
"sha256:3fd787d19ebb49919268f06f19310e8112d619ef364f7989246fc8753d469888",
"sha256:95f44f3ea2c1b176d5450df4becdb96c15bf2632888f9ab193e9dd22300ce46a"
],
"index": "pypi",
"version": "==6.9.0"
},
"rcssmin": { "rcssmin": {
"hashes": [ "hashes": [
"sha256:271e3d2f8614a6d4637ed8fff3d90007f03e2a654cd9444f37d888797662ba72", "sha256:271e3d2f8614a6d4637ed8fff3d90007f03e2a654cd9444f37d888797662ba72",
@ -1201,18 +1202,12 @@
], ],
"version": "==1.2.1" "version": "==1.2.1"
}, },
"rx": {
"hashes": [
"sha256:ca71b65d0fc0603a3b5cfaa9e33f5ba81e4aae10a58491133595088d7734b2da"
],
"version": "==1.6.3"
},
"s3transfer": { "s3transfer": {
"hashes": [ "hashes": [
"sha256:368ac6876a9e9ed91f6bc86581e319be08188dc60d50e0d56308ed5765446283", "sha256:368ac6876a9e9ed91f6bc86581e319be08188dc60d50e0d56308ed5765446283",
"sha256:c9e56cbe88b28d8e197cf841f1f0c130f246595e77ae5b5a05b69fe7cb83de76" "sha256:c9e56cbe88b28d8e197cf841f1f0c130f246595e77ae5b5a05b69fe7cb83de76"
], ],
"markers": "python_full_version >= '3.7.0'", "markers": "python_version >= '3.7'",
"version": "==0.8.2" "version": "==0.8.2"
}, },
"sentry-sdk": { "sentry-sdk": {
@ -1223,14 +1218,6 @@
"index": "pypi", "index": "pypi",
"version": "==1.38.0" "version": "==1.38.0"
}, },
"singledispatch": {
"hashes": [
"sha256:6061bd291204beaeac90cdbc342b68d213b7a6efb44ae6c5e6422a78be351c8a",
"sha256:f3430b886d5b4213d07d715096a75da5e4a8105284c497b9aee6d6d48bfe90cb"
],
"markers": "python_version >= '3.8'",
"version": "==4.1.0"
},
"six": { "six": {
"hashes": [ "hashes": [
"sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926",
@ -1325,11 +1312,11 @@
}, },
"wagtail": { "wagtail": {
"hashes": [ "hashes": [
"sha256:4bf146194e1725cd4305bf1998f507d46f587e207d609bc2ec73a6c5cce04410", "sha256:cbdef3e08d87a949cb2a63afb73c112e8921bb91608711fa1a9608f5591a77e2",
"sha256:93e8d39a14a44099ca620e46613a3a2319b1d10c622dc7f0ff8658807b18190c" "sha256:ec59a23013ef8cbc260d95ed73977010985edf5f8cb6097fdd740db6854babee"
], ],
"index": "pypi", "index": "pypi",
"version": "==4.2.4" "version": "==5.0.5"
}, },
"wagtail-autocomplete": { "wagtail-autocomplete": {
"hashes": [ "hashes": [
@ -1341,11 +1328,11 @@
}, },
"wagtail-factories": { "wagtail-factories": {
"hashes": [ "hashes": [
"sha256:2198e791854ef3883812f532a4d1b364aae1c68abc58a48b8ecec8c61e4a151f", "sha256:067e3e1a30721a90eaa1514c8214aae7a171490bbedf026eeaa904a2ed9abcd0",
"sha256:416196b88dcdb2d2787926692d7eef7fa0664556900eb6166537026b085d9fbf" "sha256:6abd435518fdf0cdd3d9920acb2abbd9005936d6fecfdf6fdde3e404834d4b0c"
], ],
"index": "pypi", "index": "pypi",
"version": "==2.0.0" "version": "==4.1.0"
}, },
"wcwidth": { "wcwidth": {
"hashes": [ "hashes": [
@ -1363,19 +1350,20 @@
}, },
"whitenoise": { "whitenoise": {
"hashes": [ "hashes": [
"sha256:d234b871b52271ae7ed6d9da47ffe857c76568f11dd30e28e18c5869dbd11e12", "sha256:8998f7370973447fac1e8ef6e8ded2c5209a7b1f67c1012866dbcd09681c3251",
"sha256:d963ef25639d1417e8a247be36e6aedd8c7c6f0a08adcb5a89146980a96b577c" "sha256:b1f9db9bf67dc183484d760b99f4080185633136a273a03f6436034a41064146"
], ],
"index": "pypi", "index": "pypi",
"version": "==5.3.0" "version": "==6.6.0"
}, },
"willow": { "willow": {
"extras": [],
"hashes": [ "hashes": [
"sha256:0df8ff528531e00b48d40bf72ed81beac1dc82f2d42e5bbed4aff0218bef8c0d", "sha256:143cefd30d3bb816cdff857c454da24991dda35a0315ea795101675e0b14262f",
"sha256:fc4042696d090e75aef922fa1ed26d483c764f005b36cf523cf7c34e69d5dd7a" "sha256:f4b17a16c6315864604dadb6cdf2987d0b685e295cca74c6da28b94167a3126e"
], ],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", "markers": "python_version >= '3.8'",
"version": "==1.4.1" "version": "==1.6.3"
} }
}, },
"develop": { "develop": {
@ -1384,7 +1372,7 @@
"sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e", "sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e",
"sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed" "sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed"
], ],
"markers": "python_full_version >= '3.7.0'", "markers": "python_version >= '3.7'",
"version": "==3.7.2" "version": "==3.7.2"
}, },
"asttokens": { "asttokens": {
@ -1404,11 +1392,11 @@
}, },
"awscli": { "awscli": {
"hashes": [ "hashes": [
"sha256:d589961a525f08caf4e3df3a85030768e5afdc89089cb720b78626fa812ad574", "sha256:448d5fdf00dac64f8c19a0ea8342aec3c33eba36551b49e7d1d563e75572e103",
"sha256:f8a6c7066b8a375b76200146f375b40121dfb2df5464fc76a9f7ad44fa3a6dbe" "sha256:f10ef081eb55eb354573239d12994b9c9c1454e271a5c09bb0bce26ffcbc2eca"
], ],
"index": "pypi", "index": "pypi",
"version": "==1.31.8" "version": "==1.31.9"
}, },
"black": { "black": {
"hashes": [ "hashes": [
@ -1436,18 +1424,18 @@
}, },
"botocore": { "botocore": {
"hashes": [ "hashes": [
"sha256:90236e6e69d7e80875d7f9d39383630706edbc1298026698c6c70d9b6a65576e", "sha256:07ff4eea62f546da540310887000c81fca802c788eb374fef06eda28009dcafd",
"sha256:e6970bf89cbe2624399aeffce52c253917d8e5a1c671de4054557603ab56c922" "sha256:1b90be11dd9a9a25290c995a6b713e76b9e2bf7bf86ba9036e0d28f2ceb2edfc"
], ],
"markers": "python_full_version >= '3.7.0'", "markers": "python_version >= '3.7'",
"version": "==1.33.8" "version": "==1.33.9"
}, },
"click": { "click": {
"hashes": [ "hashes": [
"sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28",
"sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"
], ],
"markers": "python_full_version >= '3.7.0'", "markers": "python_version >= '3.7'",
"version": "==8.1.7" "version": "==8.1.7"
}, },
"colorama": { "colorama": {
@ -1529,11 +1517,11 @@
}, },
"django": { "django": {
"hashes": [ "hashes": [
"sha256:18ba8efa36b69cfcd4b670d0fa187c6fe7506596f0ababe580e16909bcdec121", "sha256:6cb5dcea9e3d12c47834d32156b8841f533a4493c688e2718cafd51aa430ba6d",
"sha256:3adc285124244724a394fa9b9839cc8cd116faf7d159554c43ecdaa8cdf0b94d" "sha256:d69d5e36cc5d9f4eb4872be36c622878afcdce94062716cf3e25bcedcb168b62"
], ],
"index": "pypi", "index": "pypi",
"version": "==3.2.16" "version": "==4.2.8"
}, },
"django-silk": { "django-silk": {
"hashes": [ "hashes": [
@ -1596,7 +1584,7 @@
"sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980", "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980",
"sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe" "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe"
], ],
"markers": "python_full_version >= '3.7.0'", "markers": "python_version >= '3.7'",
"version": "==1.0.1" "version": "==1.0.1"
}, },
"matplotlib-inline": { "matplotlib-inline": {
@ -1620,7 +1608,7 @@
"sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5", "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5",
"sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7" "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"
], ],
"markers": "python_full_version >= '3.7.0'", "markers": "python_version >= '3.7'",
"version": "==23.2" "version": "==23.2"
}, },
"parso": { "parso": {
@ -1636,7 +1624,7 @@
"sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20", "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20",
"sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3" "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"
], ],
"markers": "python_full_version >= '3.7.0'", "markers": "python_version >= '3.7'",
"version": "==0.11.2" "version": "==0.11.2"
}, },
"pexpect": { "pexpect": {
@ -1660,7 +1648,7 @@
"sha256:941367d97fc815548822aa26c2a269fdc4eb21e9ec05fc5d447cf09bad5d75f0", "sha256:941367d97fc815548822aa26c2a269fdc4eb21e9ec05fc5d447cf09bad5d75f0",
"sha256:f36fe301fafb7470e86aaf90f036eef600a3210be4decf461a5b1ca8403d3cb2" "sha256:f36fe301fafb7470e86aaf90f036eef600a3210be4decf461a5b1ca8403d3cb2"
], ],
"markers": "python_full_version >= '3.7.0'", "markers": "python_version >= '3.7'",
"version": "==3.0.41" "version": "==3.0.41"
}, },
"ptyprocess": { "ptyprocess": {
@ -1698,7 +1686,7 @@
"sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c", "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c",
"sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367" "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"
], ],
"markers": "python_full_version >= '3.7.0'", "markers": "python_version >= '3.7'",
"version": "==2.17.2" "version": "==2.17.2"
}, },
"python-dateutil": { "python-dateutil": {
@ -1778,7 +1766,7 @@
"sha256:368ac6876a9e9ed91f6bc86581e319be08188dc60d50e0d56308ed5765446283", "sha256:368ac6876a9e9ed91f6bc86581e319be08188dc60d50e0d56308ed5765446283",
"sha256:c9e56cbe88b28d8e197cf841f1f0c130f246595e77ae5b5a05b69fe7cb83de76" "sha256:c9e56cbe88b28d8e197cf841f1f0c130f246595e77ae5b5a05b69fe7cb83de76"
], ],
"markers": "python_full_version >= '3.7.0'", "markers": "python_version >= '3.7'",
"version": "==0.8.2" "version": "==0.8.2"
}, },
"six": { "six": {

View File

@ -28,7 +28,16 @@ from books.blocks import (
SurveyBlock, SurveyBlock,
VideoBlock, VideoBlock,
) )
from books.models import Book, Chapter, ContentBlock, Module, TextBlock, Topic, ModuleLevel, ModuleCategory from books.models import (
Book,
Chapter,
ContentBlock,
Module,
TextBlock,
Topic,
ModuleLevel,
ModuleCategory,
)
from core.factories import ( from core.factories import (
BasePageFactory, BasePageFactory,
DummyImageFactory, DummyImageFactory,
@ -109,7 +118,7 @@ class TextBlockFactory(wagtail_factories.StructBlockFactory):
model = TextBlock model = TextBlock
class InstrumentCategoryFactory(factory.DjangoModelFactory): class InstrumentCategoryFactory(factory.django.DjangoModelFactory):
class Meta: class Meta:
model = InstrumentCategory model = InstrumentCategory
django_get_or_create = ("name",) django_get_or_create = ("name",)
@ -121,7 +130,7 @@ class InstrumentCategoryFactory(factory.DjangoModelFactory):
background = factory.Iterator(["FF0000", "FFFFFF", "000000"]) background = factory.Iterator(["FF0000", "FFFFFF", "000000"])
class InstrumentTypeFactory(factory.DjangoModelFactory): class InstrumentTypeFactory(factory.django.DjangoModelFactory):
class Meta: class Meta:
model = InstrumentType model = InstrumentType
@ -201,16 +210,19 @@ class VideoBlockFactory(wagtail_factories.StructBlockFactory):
class Meta: class Meta:
model = VideoBlock model = VideoBlock
class ModuleLevelFactory(factory.DjangoModelFactory):
class ModuleLevelFactory(factory.django.DjangoModelFactory):
class Meta: class Meta:
model = ModuleLevel model = ModuleLevel
name = '1. Lehrjahr'
name = "1. Lehrjahr"
class ModuleTypeFactory(factory.DjangoModelFactory): class ModuleTypeFactory(factory.django.DjangoModelFactory):
class Meta: class Meta:
model = ModuleCategory model = ModuleCategory
name = 'Lernfeld 1'
name = "Lernfeld 1"
block_types = [ block_types = [
@ -238,15 +250,17 @@ class ContentBlockFactory(BasePageFactory):
contents = wagtail_factories.StreamFieldFactory( contents = wagtail_factories.StreamFieldFactory(
{ {
"text_block": TextBlockFactory, "text_block": factory.SubFactory(TextBlockFactory),
"basic_knowledge": BasicKnowledgeBlockFactory, "basic_knowledge": factory.SubFactory(BasicKnowledgeBlockFactory),
"assignment": AssignmentBlockFactory, "assignment": factory.SubFactory(AssignmentBlockFactory),
"image_block": wagtail_factories.ImageChooserBlockFactory, "image_block": factory.SubFactory(
"image_url_block": ImageUrlBlockFactory, wagtail_factories.ImageChooserBlockFactory
"link_block": LinkBlockFactory, ),
"video_block": VideoBlockFactory, "image_url_block": factory.SubFactory(ImageUrlBlockFactory),
"solution": TextBlockFactory, "link_block": factory.SubFactory(LinkBlockFactory),
"survey": SurveyBlockFactory, "video_block": factory.SubFactory(VideoBlockFactory),
"solution": factory.SubFactory(TextBlockFactory),
"survey": factory.SubFactory(SurveyBlockFactory),
} }
) )

View File

@ -27,7 +27,7 @@ class BasePageFactory(wagtail_factories.PageFactory):
title = factory.LazyAttribute(fake_title) title = factory.LazyAttribute(fake_title)
class DummyDocumentFactory(factory.DjangoModelFactory): class DummyDocumentFactory(factory.django.DjangoModelFactory):
class Meta: class Meta:
model = get_document_model() model = get_document_model()
@ -37,7 +37,7 @@ class DummyDocumentFactory(factory.DjangoModelFactory):
) )
class DummyImageFactory(factory.DjangoModelFactory): class DummyImageFactory(factory.django.DjangoModelFactory):
class Meta: class Meta:
model = get_image_model() model = get_image_model()

View File

@ -3,10 +3,10 @@ import factory
from notes.models import ChapterBookmark, ModuleBookmark from notes.models import ChapterBookmark, ModuleBookmark
class ChapterBookmarkFactory(factory.DjangoModelFactory): class ChapterBookmarkFactory(factory.django.DjangoModelFactory):
class Meta: class Meta:
model = ChapterBookmark model = ChapterBookmark
class ModuleBookmarkFactory(factory.DjangoModelFactory): class ModuleBookmarkFactory(factory.django.DjangoModelFactory):
class Meta: class Meta:
model = ModuleBookmark model = ModuleBookmark

View File

@ -1,4 +1,4 @@
from unittest.mock import patch from unittest.mock import MagicMock, patch
from authlib.integrations.base_client import BaseApp from authlib.integrations.base_client import BaseApp
from django.contrib.sessions.middleware import SessionMiddleware from django.contrib.sessions.middleware import SessionMiddleware
@ -57,6 +57,7 @@ INVALID_LICENSE = {
class CouponTests(TestCase): class CouponTests(TestCase):
def setUp(self): def setUp(self):
get_response = MagicMock()
self.user = UserFactory( self.user = UserFactory(
username="aschi@iterativ.ch", email="aschi@iterativ.ch", hep_id=3 username="aschi@iterativ.ch", email="aschi@iterativ.ch", hep_id=3
) )
@ -66,7 +67,7 @@ class CouponTests(TestCase):
# adding session # adding session
request = RequestFactory().post("/") request = RequestFactory().post("/")
middleware = SessionMiddleware() middleware = SessionMiddleware(get_response)
middleware.process_request(request) middleware.process_request(request)
request.user = self.user request.user = self.user
request.session.save() request.session.save()
@ -165,8 +166,9 @@ class CouponTests(TestCase):
BaseApp, "put", return_value=MockResponse(200, data=["201", "Invalid Coupon"]) BaseApp, "put", return_value=MockResponse(200, data=["201", "Invalid Coupon"])
) )
def test_unauthenticated_user_cannot_redeem(self, response_mock): def test_unauthenticated_user_cannot_redeem(self, response_mock):
get_response = MagicMock()
request = RequestFactory().post("/") request = RequestFactory().post("/")
middleware = SessionMiddleware() middleware = SessionMiddleware(get_response)
middleware.process_request(request) middleware.process_request(request)
request.session.save() request.session.save()
client = Client(schema=schema, context_value=request) client = Client(schema=schema, context_value=request)

View File

@ -1,6 +1,6 @@
import time import time
from datetime import timedelta from datetime import timedelta
from unittest.mock import patch from unittest.mock import MagicMock, patch
import requests import requests
from authlib.integrations.django_client import DjangoOAuth2App from authlib.integrations.django_client import DjangoOAuth2App
@ -11,9 +11,18 @@ from django.utils import timezone
from core.factories import UserFactory from core.factories import UserFactory
from oauth.hep_client import HepClient from oauth.hep_client import HepClient
from oauth.user_signup_login_handler import EMAIL_NOT_VERIFIED, NO_VALID_LICENSE, UNKNOWN_ERROR from oauth.user_signup_login_handler import (
EMAIL_NOT_VERIFIED,
NO_VALID_LICENSE,
UNKNOWN_ERROR,
)
from oauth.views import authorize, OAUTH_REDIRECT from oauth.views import authorize, OAUTH_REDIRECT
from users.tests.mock_hep_data_factory import MockResponse, ME_DATA, VALID_STUDENT_ORDERS, VALID_TEACHERS_ORDERS from users.tests.mock_hep_data_factory import (
MockResponse,
ME_DATA,
VALID_STUDENT_ORDERS,
VALID_TEACHERS_ORDERS,
)
from users.factories import LicenseFactory from users.factories import LicenseFactory
from users.models import Role, User, SchoolClass, License, UserData from users.models import Role, User, SchoolClass, License, UserData
@ -21,65 +30,69 @@ IN_A_HOUR = timezone.now() + timedelta(hours=1)
IN_A_HOUR_UNIX = time.mktime(IN_A_HOUR.timetuple()) IN_A_HOUR_UNIX = time.mktime(IN_A_HOUR.timetuple())
TOKEN = { TOKEN = {
'token_type': 'hep', "token_type": "hep",
'access_token': '123456', "access_token": "123456",
'refresh_token': 'abcdqwer', "refresh_token": "abcdqwer",
'expires_at': IN_A_HOUR_UNIX, "expires_at": IN_A_HOUR_UNIX,
} }
NEW_ME_DATA = ME_DATA.copy() NEW_ME_DATA = ME_DATA.copy()
NEW_ME_DATA['email'] = 'stiller@has.ch' NEW_ME_DATA["email"] = "stiller@has.ch"
NEW_ME_DATA['id'] = 99 NEW_ME_DATA["id"] = 99
class LoginTests(TestCase): class LoginTests(TestCase):
def setUp(self): def setUp(self):
self.user = UserFactory(username=ME_DATA['id'], email=ME_DATA['id']) self.user = UserFactory(username=ME_DATA["id"], email=ME_DATA["id"])
Role.objects.create_default_roles() Role.objects.create_default_roles()
self.teacher_role = Role.objects.get_default_teacher_role() self.teacher_role = Role.objects.get_default_teacher_role()
self.factory = RequestFactory() self.factory = RequestFactory()
def _login(self, url): def _login(self, url):
get_response = MagicMock()
request = self.factory.get(url) request = self.factory.get(url)
middleware = SessionMiddleware() middleware = SessionMiddleware(get_response)
middleware.process_request(request) middleware.process_request(request)
request.session.save() request.session.save()
request.user = AnonymousUser() request.user = AnonymousUser()
return authorize(request) return authorize(request)
@patch.object(DjangoOAuth2App, 'authorize_access_token', return_value=TOKEN) @patch.object(DjangoOAuth2App, "authorize_access_token", return_value=TOKEN)
@patch.object(HepClient, 'user_details', return_value=ME_DATA) @patch.object(HepClient, "user_details", return_value=ME_DATA)
def test_user_data_is_synced_on_login(self, user_mock, authorize_mock): def test_user_data_is_synced_on_login(self, user_mock, authorize_mock):
old_mail = "aschi@iterativ.ch"
old_mail = 'aschi@iterativ.ch' self.user.hep_id = ME_DATA["id"]
self.user.hep_id = ME_DATA['id']
self.user.email = old_mail self.user.email = old_mail
self.user.username = old_mail self.user.username = old_mail
self.user.save() self.user.save()
now = timezone.now() now = timezone.now()
expiry_date = now + timedelta(365) expiry_date = now + timedelta(365)
LicenseFactory(expire_date=expiry_date, licensee=self.user, for_role=self.teacher_role).save() LicenseFactory(
expire_date=expiry_date, licensee=self.user, for_role=self.teacher_role
).save()
response = self._login('/api/oauth/authorize?code=1234') response = self._login("/api/oauth/authorize?code=1234")
user = User.objects.get(hep_id=self.user.hep_id) user = User.objects.get(hep_id=self.user.hep_id)
self.assertEqual(response.status_code, 302) self.assertEqual(response.status_code, 302)
self.assertEqual(response.url, f'/{OAUTH_REDIRECT}?state=success') self.assertEqual(response.url, f"/{OAUTH_REDIRECT}?state=success")
self.assertEqual(user.username, ME_DATA['email']) self.assertEqual(user.username, ME_DATA["email"])
self.assertEqual(user.email, ME_DATA['email']) self.assertEqual(user.email, ME_DATA["email"])
self.assertTrue(self.user.is_authenticated) self.assertTrue(self.user.is_authenticated)
@patch.object(HepClient, 'fetch_eorders', return_value=VALID_TEACHERS_ORDERS) @patch.object(HepClient, "fetch_eorders", return_value=VALID_TEACHERS_ORDERS)
@patch.object(DjangoOAuth2App, 'authorize_access_token', return_value=TOKEN) @patch.object(DjangoOAuth2App, "authorize_access_token", return_value=TOKEN)
@patch.object(HepClient, 'user_details', return_value=ME_DATA) @patch.object(HepClient, "user_details", return_value=ME_DATA)
def test_teacher_can_login_with_valid_license(self, user_mock, authorize_mock, orders_mock): def test_teacher_can_login_with_valid_license(
response = self._login('/api/oauth/authorize?code=1234') self, user_mock, authorize_mock, orders_mock
):
response = self._login("/api/oauth/authorize?code=1234")
user = User.objects.get(email=ME_DATA['email']) user = User.objects.get(email=ME_DATA["email"])
user_role_key = user.user_roles.get(user=user).role.key user_role_key = user.user_roles.get(user=user).role.key
self.assertEqual(user_role_key, Role.objects.TEACHER_KEY) self.assertEqual(user_role_key, Role.objects.TEACHER_KEY)
@ -91,22 +104,25 @@ class LoginTests(TestCase):
self.assertIsNotNone(school_class) self.assertIsNotNone(school_class)
self.assertEqual(response.status_code, 302) self.assertEqual(response.status_code, 302)
self.assertEqual(response.url, f'/{OAUTH_REDIRECT}?state=success') self.assertEqual(response.url, f"/{OAUTH_REDIRECT}?state=success")
self.assertTrue(self.user.is_authenticated) self.assertTrue(self.user.is_authenticated)
try: try:
UserData.objects.get(user=user) UserData.objects.get(user=user)
self.fail('LoginTests.test_teacher_can_login_with_valid_license: Userdata should not exist') self.fail(
"LoginTests.test_teacher_can_login_with_valid_license: Userdata should not exist"
)
except: except:
pass pass
@patch.object(HepClient, 'fetch_eorders', return_value=VALID_STUDENT_ORDERS) @patch.object(HepClient, "fetch_eorders", return_value=VALID_STUDENT_ORDERS)
@patch.object(DjangoOAuth2App, 'authorize_access_token', return_value=TOKEN) @patch.object(DjangoOAuth2App, "authorize_access_token", return_value=TOKEN)
@patch.object(HepClient, 'user_details', return_value=ME_DATA) @patch.object(HepClient, "user_details", return_value=ME_DATA)
def test_student_can_login_with_valid_license(self, user_mock, authorize_mock, orders_mock): def test_student_can_login_with_valid_license(
self, user_mock, authorize_mock, orders_mock
response = self._login('/api/oauth/authorize?code=1234') ):
user = User.objects.get(email=ME_DATA['email']) response = self._login("/api/oauth/authorize?code=1234")
user = User.objects.get(email=ME_DATA["email"])
user_role_key = user.user_roles.get(user=user).role.key user_role_key = user.user_roles.get(user=user).role.key
self.assertEqual(user_role_key, Role.objects.STUDENT_KEY) self.assertEqual(user_role_key, Role.objects.STUDENT_KEY)
@ -115,60 +131,70 @@ class LoginTests(TestCase):
self.assertEqual(license.for_role.key, Role.objects.STUDENT_KEY) self.assertEqual(license.for_role.key, Role.objects.STUDENT_KEY)
self.assertEqual(response.status_code, 302) self.assertEqual(response.status_code, 302)
self.assertEqual(response.url, f'/{OAUTH_REDIRECT}?state=success') self.assertEqual(response.url, f"/{OAUTH_REDIRECT}?state=success")
self.assertTrue(self.user.is_authenticated) self.assertTrue(self.user.is_authenticated)
@patch.object(HepClient, 'is_email_verified', return_value=False) @patch.object(HepClient, "is_email_verified", return_value=False)
@patch.object(DjangoOAuth2App, 'authorize_access_token', return_value=TOKEN) @patch.object(DjangoOAuth2App, "authorize_access_token", return_value=TOKEN)
@patch.object(HepClient, 'user_details', return_value=ME_DATA) @patch.object(HepClient, "user_details", return_value=ME_DATA)
def test_user_with_unconfirmed_email_cannot_login(self, user_mock, authorize_mock, verified_mock): def test_user_with_unconfirmed_email_cannot_login(
response = self._login('/api/oauth/authorize?code=1234') self, user_mock, authorize_mock, verified_mock
):
response = self._login("/api/oauth/authorize?code=1234")
User.objects.get(email=ME_DATA['email']) User.objects.get(email=ME_DATA["email"])
self.assertEqual(302, response.status_code) self.assertEqual(302, response.status_code)
self.assertEqual(f'/{OAUTH_REDIRECT}?state={EMAIL_NOT_VERIFIED}', response.url) self.assertEqual(f"/{OAUTH_REDIRECT}?state={EMAIL_NOT_VERIFIED}", response.url)
@patch.object(HepClient, 'fetch_eorders', return_value=[]) @patch.object(HepClient, "fetch_eorders", return_value=[])
@patch.object(DjangoOAuth2App, 'authorize_access_token', return_value=TOKEN) @patch.object(DjangoOAuth2App, "authorize_access_token", return_value=TOKEN)
@patch.object(HepClient, 'user_details', return_value=ME_DATA) @patch.object(HepClient, "user_details", return_value=ME_DATA)
def test_user_can_login_without_license(self, me_mock, product_mock, verified_mock): def test_user_can_login_without_license(self, me_mock, product_mock, verified_mock):
response = self._login('/api/oauth/authorize?code=1234') response = self._login("/api/oauth/authorize?code=1234")
self.assertEqual(response.status_code, 302) self.assertEqual(response.status_code, 302)
self.assertEqual(response.url, f'/{OAUTH_REDIRECT}?state={NO_VALID_LICENSE}') self.assertEqual(response.url, f"/{OAUTH_REDIRECT}?state={NO_VALID_LICENSE}")
self.assertTrue(self.user.is_authenticated) self.assertTrue(self.user.is_authenticated)
@patch.object(HepClient, 'fetch_eorders', return_value=[]) @patch.object(HepClient, "fetch_eorders", return_value=[])
@patch.object(DjangoOAuth2App, 'authorize_access_token', return_value=TOKEN) @patch.object(DjangoOAuth2App, "authorize_access_token", return_value=TOKEN)
@patch.object(HepClient, 'user_details', return_value=ME_DATA) @patch.object(HepClient, "user_details", return_value=ME_DATA)
def test_user_can_login_local_license_invalid(self, me_mock, product_mock, verified_mock): def test_user_can_login_local_license_invalid(
self, me_mock, product_mock, verified_mock
):
now = timezone.now() now = timezone.now()
expiry_date = now - timedelta(1) expiry_date = now - timedelta(1)
LicenseFactory(expire_date=expiry_date, licensee=self.user, for_role=self.teacher_role).save() LicenseFactory(
expire_date=expiry_date, licensee=self.user, for_role=self.teacher_role
).save()
response = self._login('/api/oauth/authorize?code=1234') response = self._login("/api/oauth/authorize?code=1234")
self.assertEqual(response.status_code, 302) self.assertEqual(response.status_code, 302)
self.assertEqual(response.url, f'/{OAUTH_REDIRECT}?state={NO_VALID_LICENSE}') self.assertEqual(response.url, f"/{OAUTH_REDIRECT}?state={NO_VALID_LICENSE}")
self.assertTrue(self.user.is_authenticated) self.assertTrue(self.user.is_authenticated)
@patch.object(requests, 'get', return_value=MockResponse(500)) @patch.object(requests, "get", return_value=MockResponse(500))
def test_user_gets_notified_if_server_error(self, post_mock): def test_user_gets_notified_if_server_error(self, post_mock):
response = self._login('/api/oauth/authorize?code=1234') response = self._login("/api/oauth/authorize?code=1234")
self.assertEqual(response.status_code, 302) self.assertEqual(response.status_code, 302)
self.assertEqual(response.url, f'/{OAUTH_REDIRECT}?state={UNKNOWN_ERROR}') self.assertEqual(response.url, f"/{OAUTH_REDIRECT}?state={UNKNOWN_ERROR}")
@patch.object(HepClient, 'fetch_eorders', return_value=VALID_TEACHERS_ORDERS) @patch.object(HepClient, "fetch_eorders", return_value=VALID_TEACHERS_ORDERS)
@patch.object(DjangoOAuth2App, 'authorize_access_token', return_value=TOKEN) @patch.object(DjangoOAuth2App, "authorize_access_token", return_value=TOKEN)
@patch.object(HepClient, 'user_details', return_value=NEW_ME_DATA) @patch.object(HepClient, "user_details", return_value=NEW_ME_DATA)
def new_user_is_created_in_system_after_login_with_valid_license(self, user_mock, authorize_mock, orders_mock): def new_user_is_created_in_system_after_login_with_valid_license(
response = self._login('/api/oauth/authorize?code=1234') self, user_mock, authorize_mock, orders_mock
):
response = self._login("/api/oauth/authorize?code=1234")
try: try:
user = User.objects.get(email=NEW_ME_DATA['email']) user = User.objects.get(email=NEW_ME_DATA["email"])
except: except:
self.fail('LoginTests.new_user_is_created_in_system_after_login: User was not created') self.fail(
"LoginTests.new_user_is_created_in_system_after_login: User was not created"
)
user_role_key = user.user_roles.get(user=user).role.key user_role_key = user.user_roles.get(user=user).role.key
self.assertEqual(user_role_key, Role.objects.TEACHER_KEY) self.assertEqual(user_role_key, Role.objects.TEACHER_KEY)
@ -180,25 +206,31 @@ class LoginTests(TestCase):
self.assertIsNotNone(school_class) self.assertIsNotNone(school_class)
self.assertEqual(response.status_code, 302) self.assertEqual(response.status_code, 302)
self.assertEqual(response.url, f'/{OAUTH_REDIRECT}?state=success') self.assertEqual(response.url, f"/{OAUTH_REDIRECT}?state=success")
self.assertTrue(self.user.is_authenticated) self.assertTrue(self.user.is_authenticated)
try: try:
UserData.objects.get(user=user) UserData.objects.get(user=user)
self.fail('LoginTests.test_teacher_can_login_with_valid_license: Userdata should not exist') self.fail(
"LoginTests.test_teacher_can_login_with_valid_license: Userdata should not exist"
)
except: except:
pass pass
@patch.object(HepClient, 'fetch_eorders', return_value=[]) @patch.object(HepClient, "fetch_eorders", return_value=[])
@patch.object(DjangoOAuth2App, 'authorize_access_token', return_value=TOKEN) @patch.object(DjangoOAuth2App, "authorize_access_token", return_value=TOKEN)
@patch.object(HepClient, 'user_details', return_value=NEW_ME_DATA) @patch.object(HepClient, "user_details", return_value=NEW_ME_DATA)
def new_user_is_created_in_system_after_login(self, user_mock, authorize_mock, orders_mock): def new_user_is_created_in_system_after_login(
response = self._login('/api/oauth/authorize?code=1234') self, user_mock, authorize_mock, orders_mock
):
response = self._login("/api/oauth/authorize?code=1234")
try: try:
user = User.objects.get(email=NEW_ME_DATA['email']) user = User.objects.get(email=NEW_ME_DATA["email"])
except: except:
self.fail('LoginTests.new_user_is_created_in_system_after_login: User was not created') self.fail(
"LoginTests.new_user_is_created_in_system_after_login: User was not created"
)
user_role_key = user.user_roles.get(user=user).role.key user_role_key = user.user_roles.get(user=user).role.key
self.assertEqual(user_role_key, Role.objects.TEACHER_KEY) self.assertEqual(user_role_key, Role.objects.TEACHER_KEY)
@ -210,12 +242,14 @@ class LoginTests(TestCase):
self.assertIsNotNone(school_class) self.assertIsNotNone(school_class)
self.assertEqual(response.status_code, 302) self.assertEqual(response.status_code, 302)
self.assertEqual(response.url, f'/{OAUTH_REDIRECT}?state={NO_VALID_LICENSE}') self.assertEqual(response.url, f"/{OAUTH_REDIRECT}?state={NO_VALID_LICENSE}")
self.assertTrue(self.user.is_authenticated) self.assertTrue(self.user.is_authenticated)
try: try:
UserData.objects.get(user=user) UserData.objects.get(user=user)
self.fail('LoginTests.test_teacher_can_login_with_valid_license: Userdata should not exist') self.fail(
"LoginTests.test_teacher_can_login_with_valid_license: Userdata should not exist"
)
except: except:
pass pass

View File

@ -16,45 +16,67 @@ class RoomFactory(factory.django.DjangoModelFactory):
class Meta: class Meta:
model = Room model = Room
title = factory.LazyAttribute(lambda x: fake.sentence(nb_words=random.randint(4, 8))) title = factory.LazyAttribute(
lambda x: fake.sentence(nb_words=random.randint(4, 8))
)
school_class = factory.Iterator(SchoolClass.objects.all()) school_class = factory.Iterator(SchoolClass.objects.all())
appearance = factory.LazyAttribute(lambda x: random.choice(['red', 'green', 'brown'])) appearance = factory.LazyAttribute(
lambda x: random.choice(["red", "green", "brown"])
)
block_types = ['text_block', 'image_block'] block_types = ["text_block", "image_block"]
class RoomEntryFactory(factory.django.DjangoModelFactory): class RoomEntryFactory(factory.django.DjangoModelFactory):
class Meta: class Meta:
model = RoomEntry model = RoomEntry
title = factory.LazyAttribute(lambda x: fake.sentence(nb_words=random.randint(8, 12))) title = factory.LazyAttribute(
description = factory.LazyAttribute(lambda x: fake.sentence(nb_words=random.randint(20, 30))) lambda x: fake.sentence(nb_words=random.randint(8, 12))
)
description = factory.LazyAttribute(
lambda x: fake.sentence(nb_words=random.randint(20, 30))
)
author = factory.Iterator(get_user_model().objects.all()) author = factory.Iterator(get_user_model().objects.all())
room = factory.SubFactory(RoomFactory) room = factory.SubFactory(RoomFactory)
contents = wagtail_factories.StreamFieldFactory({ contents = wagtail_factories.StreamFieldFactory(
'text_block': TextBlockFactory, {
'image_url_block': ImageUrlBlockFactory, "text_block": factory.SubFactory(TextBlockFactory),
'link_block': LinkBlockFactory "image_url_block": factory.SubFactory(ImageUrlBlockFactory),
}) "link_block": factory.SubFactory(LinkBlockFactory),
}
)
@classmethod @classmethod
def stream_field_magic(cls, kwargs, stream_field_name): def stream_field_magic(cls, kwargs, stream_field_name):
if stream_field_name in kwargs: if stream_field_name in kwargs:
for idx, resource in enumerate(kwargs[stream_field_name]): for idx, resource in enumerate(kwargs[stream_field_name]):
value = resource['value'] value = resource["value"]
for jdx, field in enumerate(value): for jdx, field in enumerate(value):
block_type = resource['type'] block_type = resource["type"]
if block_type == 'text_block': if block_type == "text_block":
kwargs['{}__{}__{}__{}'.format(stream_field_name, idx, block_type, field)] = RichText(value[field]) kwargs[
"{}__{}__{}__{}".format(
stream_field_name, idx, block_type, field
)
] = RichText(value[field])
if block_type == 'image_url_block': if block_type == "image_url_block":
kwargs['{}__{}__{}__{}'.format(stream_field_name, idx, block_type, field)] = value[field] kwargs[
"{}__{}__{}__{}".format(
stream_field_name, idx, block_type, field
)
] = value[field]
if block_type == 'link_block': if block_type == "link_block":
kwargs['{}__{}__{}__{}'.format(stream_field_name, idx, block_type, field)] = value[field] kwargs[
"{}__{}__{}__{}".format(
stream_field_name, idx, block_type, field
)
] = value[field]
# elif block_type == 'image_block': # elif block_type == 'image_block':
# kwargs['{}__{}__{}__{}'.format(stream_field_name, idx, block_type, 'image__title')] = fake_paragraph() # kwargs['{}__{}__{}__{}'.format(stream_field_name, idx, block_type, 'image__title')] = fake_paragraph()
@ -67,15 +89,19 @@ class RoomEntryFactory(factory.django.DjangoModelFactory):
else: else:
for i in range(0, random.randint(3, 7)): for i in range(0, random.randint(3, 7)):
block_type = random.choice(block_types) block_type = random.choice(block_types)
if block_type == 'text_block': if block_type == "text_block":
kwargs['{}__{}__{}__{}'.format(stream_field_name, i, 'text_block', 'text')] = RichText(fake_paragraph()) kwargs[
"{}__{}__{}__{}".format(
stream_field_name, i, "text_block", "text"
)
] = RichText(fake_paragraph())
# elif block_type == 'image_block': # elif block_type == 'image_block':
# kwargs['{}__{}__{}__{}'.format(stream_field_name, i, 'image_block', 'image__title')] = fake_paragraph() # kwargs['{}__{}__{}__{}'.format(stream_field_name, i, 'image_block', 'image__title')] = fake_paragraph()
@classmethod @classmethod
def create(cls, **kwargs): def create(cls, **kwargs):
cls.stream_field_magic(kwargs, 'contents') cls.stream_field_magic(kwargs, "contents")
return cls._generate(CREATE_STRATEGY, kwargs) return cls._generate(CREATE_STRATEGY, kwargs)
@ -83,12 +109,14 @@ class ModuleRoomSlugFactory(factory.django.DjangoModelFactory):
class Meta: class Meta:
model = ModuleRoomSlug model = ModuleRoomSlug
slug = factory.Sequence(lambda n: u'slug-{:d}'.format(n)) slug = factory.Sequence(lambda n: "slug-{:d}".format(n))
title = factory.Sequence(lambda n: u'Title {:d}'.format(n)) title = factory.Sequence(lambda n: "Title {:d}".format(n))
class CommentFactory(factory.django.DjangoModelFactory): class CommentFactory(factory.django.DjangoModelFactory):
class Meta: class Meta:
model = Comment model = Comment
text = factory.LazyAttribute(lambda x: fake.sentence(nb_words=random.randint(10, 30))) text = factory.LazyAttribute(
lambda x: fake.sentence(nb_words=random.randint(10, 30))
)

View File

@ -38,66 +38,66 @@ mutation AddRoomEntry($input: AddRoomEntryInput!){
class RoomEntryMutationsTestCase(SkillboxTestCase): class RoomEntryMutationsTestCase(SkillboxTestCase):
def setUp(self): def setUp(self):
self.user = UserFactory(username='aschi') self.user = UserFactory(username="aschi")
self.another_user = UserFactory(username='pesche') self.another_user = UserFactory(username="pesche")
self.yet_another_user = UserFactory(username='hansueli') self.yet_another_user = UserFactory(username="hansueli")
s = SchoolClassFactory(users=[self.user, self.another_user]) s = SchoolClassFactory(users=[self.user, self.another_user])
s2 = SchoolClassFactory(users=[self.yet_another_user]) s2 = SchoolClassFactory(users=[self.yet_another_user])
self.room_entry = RoomEntryFactory(author=self.user, room=RoomFactory(school_class=s)) # self.room_entry = RoomEntryFactory(author=self.user, room=RoomFactory(school_class=s))
self.room_entry = RoomEntryFactory(author=self.user, room__school_class=s)
self.room = self.room_entry.room self.room = self.room_entry.room
self.first_school_class = s self.first_school_class = s
request = RequestFactory().get('/') request = RequestFactory().get("/")
request.user = self.user request.user = self.user
self.client = Client(schema=schema, context_value=request) self.client = Client(schema=schema, context_value=request)
def test_delete_room_entry(self): def test_delete_room_entry(self):
self.assertEqual(RoomEntry.objects.count(), 1) self.assertEqual(RoomEntry.objects.count(), 1)
mutation = ''' mutation = """
mutation DeleteRoomEntry($input: DeleteRoomEntryInput!) { mutation DeleteRoomEntry($input: DeleteRoomEntryInput!) {
deleteRoomEntry(input: $input) { deleteRoomEntry(input: $input) {
success success
errors errors
} }
} }
''' """
result = self.client.execute(mutation, variables={ result = self.client.execute(
'input': { mutation, variables={"input": {"slug": self.room_entry.slug}}
'slug': self.room_entry.slug )
} self.assertIsNone(result.get("errors"))
})
self.assertIsNone(result.get('errors'))
self.assertEqual(RoomEntry.objects.count(), 0) self.assertEqual(RoomEntry.objects.count(), 0)
def test_delete_room_not_owner(self): def test_delete_room_not_owner(self):
self.assertEqual(RoomEntry.objects.count(), 1) self.assertEqual(RoomEntry.objects.count(), 1)
mutation = ''' mutation = """
mutation DeleteRoomEntry($input: DeleteRoomEntryInput!) { mutation DeleteRoomEntry($input: DeleteRoomEntryInput!) {
deleteRoomEntry(input: $input) { deleteRoomEntry(input: $input) {
success success
errors errors
} }
} }
''' """
request = RequestFactory().get('/') request = RequestFactory().get("/")
request.user = self.another_user request.user = self.another_user
client = Client(schema=schema, context_value=request) client = Client(schema=schema, context_value=request)
result = client.execute(mutation, variables={ result = client.execute(
'input': { mutation,
'id': to_global_id('RoomEntryNode', self.room_entry.pk) variables={
} "input": {"id": to_global_id("RoomEntryNode", self.room_entry.pk)}
}) },
)
self.assertIsNotNone(result.get('errors')) self.assertIsNotNone(result.get("errors"))
self.assertEqual(RoomEntry.objects.count(), 1) self.assertEqual(RoomEntry.objects.count(), 1)
def test_update_room_entry_not_owner_but_same_class(self): def test_update_room_entry_not_owner_but_same_class(self):
self.assertEqual(RoomEntry.objects.count(), 1) self.assertEqual(RoomEntry.objects.count(), 1)
mutation = ''' mutation = """
mutation UpdateRoomEntry($input: UpdateRoomEntryInput!){ mutation UpdateRoomEntry($input: UpdateRoomEntryInput!){
updateRoomEntry(input: $input) { updateRoomEntry(input: $input) {
roomEntry { roomEntry {
@ -109,30 +109,33 @@ class RoomEntryMutationsTestCase(SkillboxTestCase):
errors errors
} }
} }
''' """
request = RequestFactory().get('/') request = RequestFactory().get("/")
request.user = self.another_user request.user = self.another_user
client = Client(schema=schema, context_value=request) client = Client(schema=schema, context_value=request)
new_title = 'new title, Alte!' new_title = "new title, Alte!"
result = client.execute(mutation, variables={ result = client.execute(
'input': { mutation,
'roomEntry': { variables={
'id': to_global_id('RoomEntryNode', self.room_entry.pk), "input": {
'title': new_title "roomEntry": {
"id": to_global_id("RoomEntryNode", self.room_entry.pk),
"title": new_title,
} }
} }
}) },
)
entry = RoomEntry.objects.get(pk=self.room_entry.pk) entry = RoomEntry.objects.get(pk=self.room_entry.pk)
self.assertIsNotNone(result.get('errors')) self.assertIsNotNone(result.get("errors"))
self.assertEqual(entry.title, self.room_entry.title) self.assertEqual(entry.title, self.room_entry.title)
def test_update_room_entry_not_owner_from_other_class(self): def test_update_room_entry_not_owner_from_other_class(self):
self.assertEqual(RoomEntry.objects.count(), 1) self.assertEqual(RoomEntry.objects.count(), 1)
mutation = ''' mutation = """
mutation UpdateRoomEntry($input: UpdateRoomEntryInput!){ mutation UpdateRoomEntry($input: UpdateRoomEntryInput!){
updateRoomEntry(input: $input) { updateRoomEntry(input: $input) {
roomEntry { roomEntry {
@ -144,25 +147,28 @@ class RoomEntryMutationsTestCase(SkillboxTestCase):
errors errors
} }
} }
''' """
request = RequestFactory().get('/') request = RequestFactory().get("/")
request.user = self.yet_another_user request.user = self.yet_another_user
client = Client(schema=schema, context_value=request) client = Client(schema=schema, context_value=request)
new_title = 'new title, Alte!' new_title = "new title, Alte!"
result = client.execute(mutation, variables={ result = client.execute(
'input': { mutation,
'roomEntry': { variables={
'id': to_global_id('RoomEntryNode', self.room_entry.pk), "input": {
'title': new_title "roomEntry": {
"id": to_global_id("RoomEntryNode", self.room_entry.pk),
"title": new_title,
} }
} }
}) },
)
entry = RoomEntry.objects.get(pk=self.room_entry.pk) entry = RoomEntry.objects.get(pk=self.room_entry.pk)
self.assertIsNotNone(result.get('errors')) self.assertIsNotNone(result.get("errors"))
self.assertEqual(entry.title, self.room_entry.title) self.assertEqual(entry.title, self.room_entry.title)
def test_add_room_entry_not_owner_from_other_class(self): def test_add_room_entry_not_owner_from_other_class(self):
@ -171,39 +177,32 @@ class RoomEntryMutationsTestCase(SkillboxTestCase):
# title = graphene.String(required=True) # title = graphene.String(required=True)
# contents = graphene.List(ContentElementInput) # contents = graphene.List(ContentElementInput)
# room = graphene.ID(required=True) # room = graphene.ID(required=True)
room_entry = { room_entry = {"title": "Bad Actor!", "roomSlug": self.room.slug}
'title': 'Bad Actor!',
'roomSlug': self.room.slug
}
result = self.get_client(self.yet_another_user).execute(ADD_ROOM_ENTRY_MUTATION, variables={ result = self.get_client(self.yet_another_user).execute(
'input': { ADD_ROOM_ENTRY_MUTATION, variables={"input": {"roomEntry": room_entry}}
'roomEntry': room_entry )
}
})
self.assertIsNotNone(result.errors) self.assertIsNotNone(result.errors)
self.assertTrue('message' in result.errors[0]) self.assertTrue("message" in result.errors[0])
self.assertEqual(result.errors[0]['message'], 'You are in the wrong class') self.assertEqual(result.errors[0]["message"], "You are in the wrong class")
def test_add_room_entry(self): def test_add_room_entry(self):
self.assertEqual(RoomEntry.objects.count(), 1) self.assertEqual(RoomEntry.objects.count(), 1)
text_block = {"type": "text_block", "value": {"text": "<p>some text</p>"}} text_block = {"type": "text_block", "value": {"text": "<p>some text</p>"}}
subtitle_block = {"type": "subtitle", "value": {"text": "A subtitle"}} subtitle_block = {"type": "subtitle", "value": {"text": "A subtitle"}}
room_entry = { room_entry = {
'title': 'A room entry', "title": "A room entry",
'roomSlug': self.room.slug, "roomSlug": self.room.slug,
'contents': [text_block, subtitle_block] "contents": [text_block, subtitle_block],
} }
result = self.get_client(self.user).execute(ADD_ROOM_ENTRY_MUTATION, variables={ result = self.get_client(self.user).execute(
'input': { ADD_ROOM_ENTRY_MUTATION, variables={"input": {"roomEntry": room_entry}}
'roomEntry': room_entry )
}
})
self.assertIsNone(result.errors) self.assertIsNone(result.errors)
room_entry_data = result.data.get('addRoomEntry').get('roomEntry') room_entry_data = result.data.get("addRoomEntry").get("roomEntry")
contents = room_entry_data.get('contents') contents = room_entry_data.get("contents")
self.assertEqual(len(contents), 2) self.assertEqual(len(contents), 2)
text, subtitle = contents text, subtitle = contents
self.assertEqual(text.get('type'), 'text_block') self.assertEqual(text.get("type"), "text_block")
self.assertEqual(subtitle.get('type'), 'subtitle') self.assertEqual(subtitle.get("type"), "subtitle")
self.assertEqual(RoomEntry.objects.count(), 2) self.assertEqual(RoomEntry.objects.count(), 2)

View File

@ -1,4 +1,3 @@
from django.conf.urls import url
from django.urls import re_path from django.urls import re_path
from statistics.views import StatisticsView from statistics.views import StatisticsView

View File

@ -7,6 +7,7 @@
# #
# Created on 2019-10-02 # Created on 2019-10-02
# @author: chrigu <christian.cueni@iterativ.ch> # @author: chrigu <christian.cueni@iterativ.ch>
from unittest.mock import MagicMock
from django.contrib.sessions.middleware import SessionMiddleware from django.contrib.sessions.middleware import SessionMiddleware
from django.test import TestCase, RequestFactory from django.test import TestCase, RequestFactory
from graphene.test import Client from graphene.test import Client
@ -18,47 +19,47 @@ from users.models import Role
class BetaLoginTests(TestCase): class BetaLoginTests(TestCase):
def setUp(self): def setUp(self):
self.user = UserFactory(username='aschi@iterativ.ch', email='aschi@iterativ.ch') get_response = MagicMock()
self.teacher_role = Role.objects.create(key=Role.objects.TEACHER_KEY, name="Teacher Role") self.user = UserFactory(username="aschi@iterativ.ch", email="aschi@iterativ.ch")
self.teacher_role = Role.objects.create(
key=Role.objects.TEACHER_KEY, name="Teacher Role"
)
request = RequestFactory().post('/') request = RequestFactory().post("/")
# adding session # adding session
middleware = SessionMiddleware() middleware = SessionMiddleware(get_response)
middleware.process_request(request) middleware.process_request(request)
request.session.save() request.session.save()
self.client = Client(schema=schema, context_value=request) self.client = Client(schema=schema, context_value=request)
def make_login_mutation(self, username, password): def make_login_mutation(self, username, password):
mutation = ''' mutation = """
mutation BetaLogin($input: BetaLoginInput!){ mutation BetaLogin($input: BetaLoginInput!){
betaLogin(input: $input) { betaLogin(input: $input) {
success success
} }
} }
''' """
return self.client.execute(mutation, variables={ return self.client.execute(
'input': { mutation,
'usernameInput': username, variables={"input": {"usernameInput": username, "passwordInput": password}},
'passwordInput': password )
}
})
def test_user_can_login(self): def test_user_can_login(self):
password = 'test123' password = "test123"
self.user.set_password(password) self.user.set_password(password)
self.user.save() self.user.save()
result = self.make_login_mutation(self.user.email, password) result = self.make_login_mutation(self.user.email, password)
self.assertTrue(result.get('data').get('betaLogin').get('success')) self.assertTrue(result.get("data").get("betaLogin").get("success"))
self.assertTrue(self.user.is_authenticated) self.assertTrue(self.user.is_authenticated)
def test_user_cannot_login_with_invalid_password(self): def test_user_cannot_login_with_invalid_password(self):
password = 'test123' password = "test123"
self.user.set_password(password) self.user.set_password(password)
self.user.save() self.user.save()
result = self.make_login_mutation(self.user.email, 'test1234') result = self.make_login_mutation(self.user.email, "test1234")
self.assertEqual(result.get('errors')[0].get('message'), 'invalid_credentials') self.assertEqual(result.get("errors")[0].get("message"), "invalid_credentials")

View File

@ -1,3 +1,4 @@
from unittest.mock import MagicMock
from django.contrib.sessions.middleware import SessionMiddleware from django.contrib.sessions.middleware import SessionMiddleware
from django.test import TestCase, RequestFactory from django.test import TestCase, RequestFactory
from graphene.test import Client from graphene.test import Client
@ -8,20 +9,20 @@ from django.contrib.auth import authenticate
class PasswordUpdate(TestCase): class PasswordUpdate(TestCase):
def setUp(self): def setUp(self):
self.user = UserFactory(username='aschi') get_response = MagicMock()
self.user = UserFactory(username="aschi")
request = RequestFactory().get('/') request = RequestFactory().get("/")
request.user = self.user request.user = self.user
# adding session # adding session
middleware = SessionMiddleware() middleware = SessionMiddleware(get_response)
middleware.process_request(request) middleware.process_request(request)
request.session.save() request.session.save()
self.client = Client(schema=schema, context_value=request) self.client = Client(schema=schema, context_value=request)
def make_request(self, new_password, old_password='test'): def make_request(self, new_password, old_password="test"):
mutation = """
mutation = '''
mutation UpdatePassword($input: UpdatePasswordInput!) { mutation UpdatePassword($input: UpdatePasswordInput!) {
updatePassword(input: $input) { updatePassword(input: $input) {
success success
@ -33,102 +34,86 @@ class PasswordUpdate(TestCase):
} }
} }
} }
''' """
return self.client.execute(mutation, variables={ return self.client.execute(
'input': { mutation,
'passwordInput': { variables={
'oldPassword': old_password, "input": {
'newPassword': new_password "passwordInput": {
"oldPassword": old_password,
"newPassword": new_password,
} }
} }
}) },
)
def test_update_password(self): def test_update_password(self):
new_password = "Abcd123!"
new_password = 'Abcd123!'
result = self.make_request(new_password) result = self.make_request(new_password)
self.assertTrue(result.get('data').get('updatePassword').get('success')) self.assertTrue(result.get("data").get("updatePassword").get("success"))
user = authenticate(username=self.user.username, password=new_password) user = authenticate(username=self.user.username, password=new_password)
self.assertIsNotNone(user) self.assertIsNotNone(user)
def test_update_fails_with_short_password(self): def test_update_fails_with_short_password(self):
new_password = "Ab!d123"
new_password = 'Ab!d123'
result = self.make_request(new_password) result = self.make_request(new_password)
self.assertFalse(result.get('data').get('updatePassword').get('success')) self.assertFalse(result.get("data").get("updatePassword").get("success"))
self.assertEqual(result.get('data').get('updatePassword').get('errors')[0], { self.assertEqual(
'field': 'new_password', result.get("data").get("updatePassword").get("errors")[0],
'errors': [ {"field": "new_password", "errors": [{"code": "min_length"}]},
{'code': 'min_length'} )
]
})
def test_update_fails_with_no_special_character(self): def test_update_fails_with_no_special_character(self):
new_password = "Abcd1239"
new_password = 'Abcd1239'
result = self.make_request(new_password) result = self.make_request(new_password)
self.assertFalse(result.get('data').get('updatePassword').get('success')) self.assertFalse(result.get("data").get("updatePassword").get("success"))
self.assertEqual(result.get('data').get('updatePassword').get('errors')[0], { self.assertEqual(
'field': 'new_password', result.get("data").get("updatePassword").get("errors")[0],
'errors': [ {"field": "new_password", "errors": [{"code": "invalid"}]},
{'code': 'invalid'} )
]
})
def test_update_fails_with_no_digit(self): def test_update_fails_with_no_digit(self):
new_password = "Abcd!asddfg"
new_password = 'Abcd!asddfg'
result = self.make_request(new_password) result = self.make_request(new_password)
self.assertFalse(result.get('data').get('updatePassword').get('success')) self.assertFalse(result.get("data").get("updatePassword").get("success"))
self.assertEqual(result.get('data').get('updatePassword').get('errors')[0], { self.assertEqual(
'field': 'new_password', result.get("data").get("updatePassword").get("errors")[0],
'errors': [ {"field": "new_password", "errors": [{"code": "invalid"}]},
{'code': 'invalid'} )
]
})
def test_update_fails_with_no_lowercase_char(self): def test_update_fails_with_no_lowercase_char(self):
new_password = "45ABDC!AWSWS"
new_password = '45ABDC!AWSWS'
result = self.make_request(new_password) result = self.make_request(new_password)
self.assertFalse(result.get('data').get('updatePassword').get('success')) self.assertFalse(result.get("data").get("updatePassword").get("success"))
self.assertEqual(result.get('data').get('updatePassword').get('errors')[0], { self.assertEqual(
'field': 'new_password', result.get("data").get("updatePassword").get("errors")[0],
'errors': [ {"field": "new_password", "errors": [{"code": "invalid"}]},
{'code': 'invalid'} )
]
})
def test_update_fails_with_no_uppercase_char(self): def test_update_fails_with_no_uppercase_char(self):
new_password = "45aswed!aswdef"
new_password = '45aswed!aswdef'
result = self.make_request(new_password) result = self.make_request(new_password)
self.assertFalse(result.get('data').get('updatePassword').get('success')) self.assertFalse(result.get("data").get("updatePassword").get("success"))
self.assertEqual(result.get('data').get('updatePassword').get('errors')[0], { self.assertEqual(
'field': 'new_password', result.get("data").get("updatePassword").get("errors")[0],
'errors': [ {"field": "new_password", "errors": [{"code": "invalid"}]},
{'code': 'invalid'} )
]
})
def test_update_fails_with_wrong_old_password(self): def test_update_fails_with_wrong_old_password(self):
new_password = "Abcd123!"
result = self.make_request(new_password, "testttt")
new_password = 'Abcd123!' self.assertFalse(result.get("data").get("updatePassword").get("success"))
result = self.make_request(new_password, 'testttt') self.assertEqual(
result.get("data").get("updatePassword").get("errors")[0],
self.assertFalse(result.get('data').get('updatePassword').get('success')) {"field": "old_password", "errors": [{"code": "invalid"}]},
self.assertEqual(result.get('data').get('updatePassword').get('errors')[0], { )
'field': 'old_password',
'errors': [
{'code': 'invalid'}
]
})