Merged in feature/taskbase-spellcheck (pull request #45)
Feature/taskbase spellcheck Approved-by: Christian Cueni <christian.cueni@iterativ.ch>
This commit is contained in:
commit
542c7c6d84
|
|
@ -29,7 +29,7 @@ node_modules
|
|||
|
||||
# Backend
|
||||
staticfiles
|
||||
schema.json
|
||||
server/schema.json
|
||||
|
||||
# Wagtail assets
|
||||
server/documents
|
||||
|
|
|
|||
7
Pipfile
7
Pipfile
|
|
@ -13,8 +13,8 @@ coverage = "*"
|
|||
|
||||
[packages]
|
||||
factory-boy = "==2.11.0"
|
||||
wagtail_factories = {git = "https://github.com/mvantellingen/wagtail-factories.git",ref = "master"}
|
||||
django = "==2.0.6"
|
||||
wagtail_factories = "==2.0.0"
|
||||
django = "<3"
|
||||
whitenoise = "==4.0b4"
|
||||
psycopg2 = "==2.7.3.2"
|
||||
gunicorn = "==19.7.1"
|
||||
|
|
@ -37,6 +37,5 @@ newrelic = "*"
|
|||
sentry-sdk = "==0.7.2"
|
||||
"django-sendgrid-v5" = "==0.8.0"
|
||||
python-http-client = "==3.2.1"
|
||||
coverage = "*"
|
||||
graphql-relay = "*"
|
||||
ipython = "*"
|
||||
requests = "*"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "725dd26226fe58559f67b30a09dec72086dc4681a69f2f2672f5bd87c9ac74b8"
|
||||
"sha256": "e7807798e8b5c39d7c1bc57d61520f2c888da08d2b6061f07758e00b490fdbd6"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
|
|
@ -23,14 +23,6 @@
|
|||
],
|
||||
"version": "==7.0.0"
|
||||
},
|
||||
"appnope": {
|
||||
"hashes": [
|
||||
"sha256:5b26757dc6f79a3b7dc9fab95359328d5747fcb2409d331ea66d0272b90ab2a0",
|
||||
"sha256:8b995ffe925347a2138d7ac0fe77155e4311a0ea6d6da4f5128fe4b3cbe5ed71"
|
||||
],
|
||||
"markers": "sys_platform == 'darwin'",
|
||||
"version": "==0.1.0"
|
||||
},
|
||||
"backcall": {
|
||||
"hashes": [
|
||||
"sha256:38ecd85be2c1e78f77fd91700c76e14667dc21e2713b63876c0eb901196e01e4",
|
||||
|
|
@ -56,25 +48,25 @@
|
|||
},
|
||||
"boto3": {
|
||||
"hashes": [
|
||||
"sha256:08d949fede71c14db8b9b638edaa13831d79daed84e2da27750629fd606bdb57",
|
||||
"sha256:4d7c2cc266917cd0ff7e5e039158de80991e21696a2e8bf85201de2d06d7ceea"
|
||||
"sha256:27e221d3868f35687807e5c920f7e8d4872f722f64196a7fd274a06ad65beec0",
|
||||
"sha256:8ff4e3d9e5d6a26dd7494afc68dc96afe6b7bda88130cca84cd58702d888ed27"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.10.9"
|
||||
"version": "==1.11.10"
|
||||
},
|
||||
"botocore": {
|
||||
"hashes": [
|
||||
"sha256:61ad58e737e7a5d61308599606cd5a435cc3b97eb7fa693f99663c91bf1706d1",
|
||||
"sha256:8cb038c110822681925a1f5d9005dc2bbc4259fff89d4abfaaf803a3489d0ee3"
|
||||
"sha256:cf3144994191847e30ef76781af867009bdc233b3f1f4736615e5330687a891e",
|
||||
"sha256:f11ff8616f46ca04697df031e622c9ed50931b9d649d4e719f961e9d80771e8d"
|
||||
],
|
||||
"version": "==1.13.9"
|
||||
"version": "==1.14.10"
|
||||
},
|
||||
"certifi": {
|
||||
"hashes": [
|
||||
"sha256:e4f3620cfea4f83eedc95b24abd9cd56f3c4b146dd0177e83a21b4eb49e21e50",
|
||||
"sha256:fd7c7c74727ddcf00e9acd26bba8da604ffec95bf1c2144e67aff7a8b50e6cef"
|
||||
"sha256:017c25db2a153ce562900032d5bc68e9f191e44e9a0f762f373977de9df1fbb3",
|
||||
"sha256:25b64c7da4cd7479594d035c08c2d809eb4aab3a26e5a990ea98cc450c320f1f"
|
||||
],
|
||||
"version": "==2019.9.11"
|
||||
"version": "==2019.11.28"
|
||||
},
|
||||
"chardet": {
|
||||
"hashes": [
|
||||
|
|
@ -90,44 +82,6 @@
|
|||
],
|
||||
"version": "==7.0"
|
||||
},
|
||||
"coverage": {
|
||||
"hashes": [
|
||||
"sha256:08907593569fe59baca0bf152c43f3863201efb6113ecb38ce7e97ce339805a6",
|
||||
"sha256:0be0f1ed45fc0c185cfd4ecc19a1d6532d72f86a2bac9de7e24541febad72650",
|
||||
"sha256:141f08ed3c4b1847015e2cd62ec06d35e67a3ac185c26f7635f4406b90afa9c5",
|
||||
"sha256:19e4df788a0581238e9390c85a7a09af39c7b539b29f25c89209e6c3e371270d",
|
||||
"sha256:23cc09ed395b03424d1ae30dcc292615c1372bfba7141eb85e11e50efaa6b351",
|
||||
"sha256:245388cda02af78276b479f299bbf3783ef0a6a6273037d7c60dc73b8d8d7755",
|
||||
"sha256:331cb5115673a20fb131dadd22f5bcaf7677ef758741312bee4937d71a14b2ef",
|
||||
"sha256:386e2e4090f0bc5df274e720105c342263423e77ee8826002dcffe0c9533dbca",
|
||||
"sha256:3a794ce50daee01c74a494919d5ebdc23d58873747fa0e288318728533a3e1ca",
|
||||
"sha256:60851187677b24c6085248f0a0b9b98d49cba7ecc7ec60ba6b9d2e5574ac1ee9",
|
||||
"sha256:63a9a5fc43b58735f65ed63d2cf43508f462dc49857da70b8980ad78d41d52fc",
|
||||
"sha256:6b62544bb68106e3f00b21c8930e83e584fdca005d4fffd29bb39fb3ffa03cb5",
|
||||
"sha256:6ba744056423ef8d450cf627289166da65903885272055fb4b5e113137cfa14f",
|
||||
"sha256:7494b0b0274c5072bddbfd5b4a6c6f18fbbe1ab1d22a41e99cd2d00c8f96ecfe",
|
||||
"sha256:826f32b9547c8091679ff292a82aca9c7b9650f9fda3e2ca6bf2ac905b7ce888",
|
||||
"sha256:93715dffbcd0678057f947f496484e906bf9509f5c1c38fc9ba3922893cda5f5",
|
||||
"sha256:9a334d6c83dfeadae576b4d633a71620d40d1c379129d587faa42ee3e2a85cce",
|
||||
"sha256:af7ed8a8aa6957aac47b4268631fa1df984643f07ef00acd374e456364b373f5",
|
||||
"sha256:bf0a7aed7f5521c7ca67febd57db473af4762b9622254291fbcbb8cd0ba5e33e",
|
||||
"sha256:bf1ef9eb901113a9805287e090452c05547578eaab1b62e4ad456fcc049a9b7e",
|
||||
"sha256:c0afd27bc0e307a1ffc04ca5ec010a290e49e3afbe841c5cafc5c5a80ecd81c9",
|
||||
"sha256:dd579709a87092c6dbee09d1b7cfa81831040705ffa12a1b248935274aee0437",
|
||||
"sha256:df6712284b2e44a065097846488f66840445eb987eb81b3cc6e4149e7b6982e1",
|
||||
"sha256:e07d9f1a23e9e93ab5c62902833bf3e4b1f65502927379148b6622686223125c",
|
||||
"sha256:e2ede7c1d45e65e209d6093b762e98e8318ddeff95317d07a27a2140b80cfd24",
|
||||
"sha256:e4ef9c164eb55123c62411f5936b5c2e521b12356037b6e1c2617cef45523d47",
|
||||
"sha256:eca2b7343524e7ba246cab8ff00cab47a2d6d54ada3b02772e908a45675722e2",
|
||||
"sha256:eee64c616adeff7db37cc37da4180a3a5b6177f5c46b187894e633f088fb5b28",
|
||||
"sha256:ef824cad1f980d27f26166f86856efe11eff9912c4fed97d3804820d43fa550c",
|
||||
"sha256:efc89291bd5a08855829a3c522df16d856455297cf35ae827a37edac45f466a7",
|
||||
"sha256:fa964bae817babece5aa2e8c1af841bebb6d0b9add8e637548809d040443fee0",
|
||||
"sha256:ff37757e068ae606659c28c3bd0d923f9d29a85de79bf25b2b34b148473b5025"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==4.5.4"
|
||||
},
|
||||
"decorator": {
|
||||
"hashes": [
|
||||
"sha256:54c38050039232e1db4ad7375cfce6748d7b41c29e95a081c8a6d2c30364a2ce",
|
||||
|
|
@ -144,11 +98,11 @@
|
|||
},
|
||||
"django": {
|
||||
"hashes": [
|
||||
"sha256:3eb25c99df1523446ec2dc1b00e25eb2ecbdf42c9d8b0b8b32a204a8db9011f8",
|
||||
"sha256:69ff89fa3c3a8337015478a1a0744f52a9fef5d12c1efa01a01f99bcce9bf10c"
|
||||
"sha256:48522428f4a285cf265af969f4744c5ebb027c7f41958ba48b639ace2068ffe7",
|
||||
"sha256:a794f7a2f4b7c928eecfbc4ebad03712ff27fb545abe269bf01aa8500781eb1c"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.0.6"
|
||||
"version": "==2.1.15"
|
||||
},
|
||||
"django-appconf": {
|
||||
"hashes": [
|
||||
|
|
@ -159,11 +113,11 @@
|
|||
},
|
||||
"django-compressor": {
|
||||
"hashes": [
|
||||
"sha256:47c86347f75c64954a06afbbfc820a750619e10c23a49272b865020a407b7edd",
|
||||
"sha256:da9ee5ce4fc8b9211dcecd2229520514a4ba9ac3bcdc59b48092ec4d7f6b96b0"
|
||||
"sha256:57ac0a696d061e5fc6fbc55381d2050f353b973fb97eee5593f39247bc0f30af",
|
||||
"sha256:d2ed1c6137ddaac5536233ec0a819e14009553fee0a869bea65d03e5285ba74f"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.3"
|
||||
"version": "==2.4"
|
||||
},
|
||||
"django-cors-headers": {
|
||||
"hashes": [
|
||||
|
|
@ -191,17 +145,18 @@
|
|||
},
|
||||
"django-libsass": {
|
||||
"hashes": [
|
||||
"sha256:49db3334b87e1f7955c4f9fb9945bc296f8bfd27a14d6d89706e4b0e5dc5de1c"
|
||||
"sha256:38fab4ce1245542f3afd7248dc48f8a0b261f5f6c61e7cc43969a9c9079b5ffd",
|
||||
"sha256:3e74fd8e75ac0e6ebc0443efc3e530167981bf279fecc2294094c820ae266fbb"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.7"
|
||||
"version": "==0.8"
|
||||
},
|
||||
"django-modelcluster": {
|
||||
"hashes": [
|
||||
"sha256:59672386191d38c69d6f994c3f9aaab3ff93910ec71e78a0bb6aa9abd4d1b90a",
|
||||
"sha256:eea507f2dd8bd283600c1cfa4de6776501a28f199089bb00613c1621505e80cc"
|
||||
"sha256:09483ff1ede3cd87b56b0e6f732d33334c843adc6506dfed26c02998222751fe",
|
||||
"sha256:de1b5cd348fd4929491ef2a9ba29d9b5a3fccd3bf6a15218fa1aa5be49d06070"
|
||||
],
|
||||
"version": "==4.4"
|
||||
"version": "==4.4.1"
|
||||
},
|
||||
"django-sendgrid-v5": {
|
||||
"hashes": [
|
||||
|
|
@ -213,11 +168,11 @@
|
|||
},
|
||||
"django-storages": {
|
||||
"hashes": [
|
||||
"sha256:87287b7ad2e789cd603373439994e1ac6f94d9dc2e5f8173d2a87aa3ed458bd9",
|
||||
"sha256:f3b3def96493d3ccde37b864cea376472baf6e8a596504b209278801c510b807"
|
||||
"sha256:3103991c2ee8cef8a2ff096709973ffe7106183d211a79f22cf855f33533d924",
|
||||
"sha256:a59e9923cbce7068792f75344ed7727021ee4ac20f227cf17297d0d03d141e91"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.7.2"
|
||||
"version": "==1.9.1"
|
||||
},
|
||||
"django-taggit": {
|
||||
"hashes": [
|
||||
|
|
@ -228,9 +183,9 @@
|
|||
},
|
||||
"django-treebeard": {
|
||||
"hashes": [
|
||||
"sha256:c21db06a8d4943bf2a28d9d7a119058698fb76116df2679ecbf15a46a501de42"
|
||||
"sha256:83aebc34a9f06de7daaec330d858d1c47887e81be3da77e3541fe7368196dd8a"
|
||||
],
|
||||
"version": "==4.3"
|
||||
"version": "==4.3.1"
|
||||
},
|
||||
"djangorestframework": {
|
||||
"hashes": [
|
||||
|
|
@ -264,10 +219,10 @@
|
|||
},
|
||||
"faker": {
|
||||
"hashes": [
|
||||
"sha256:5902379d8df308a204fc11c4f621590ee83975805a6c7b2228203b9defa45250",
|
||||
"sha256:5e8c755c619f332d5ec28b7586389665f136bcf528e165eb925e87c06a63eda7"
|
||||
"sha256:047d4d1791bfb3756264da670d99df13d799bb36e7d88774b1585a82d05dbaec",
|
||||
"sha256:1b1a58961683b30c574520d0c739c4443e0ef6a185c04382e8cc888273dbebed"
|
||||
],
|
||||
"version": "==2.0.3"
|
||||
"version": "==4.0.0"
|
||||
},
|
||||
"future": {
|
||||
"hashes": [
|
||||
|
|
@ -292,19 +247,17 @@
|
|||
},
|
||||
"graphql-core": {
|
||||
"hashes": [
|
||||
"sha256:1488f2a5c2272dc9ba66e3042a6d1c30cea0db4c80bd1e911c6791ad6187d91b",
|
||||
"sha256:da64c472d720da4537a2e8de8ba859210b62841bd47a9be65ca35177f62fe0e4"
|
||||
"sha256:74a8f509ae8c4a58271f5d6b46d5c75b4aed116821ab62dea252d8041bfe057a",
|
||||
"sha256:c06e59153246dd48ddbf86ca94a8f045c1b71daf8154b4635e1a0e2e11d9b60b"
|
||||
],
|
||||
"version": "==2.2.1"
|
||||
"version": "==2.3.1"
|
||||
},
|
||||
"graphql-relay": {
|
||||
"hashes": [
|
||||
"sha256:0e94201af4089e1f81f07d7bd8f84799768e39d70fa1ea16d1df505b46cc6335",
|
||||
"sha256:75aa0758971e252964cb94068a4decd472d2a8295229f02189e3cbca1f10dbb5",
|
||||
"sha256:7fa74661246e826ef939ee92e768f698df167a7617361ab399901eaebf80dce6"
|
||||
"sha256:870b6b5304123a38a0b215a79eace021acce5a466bf40cd39fa18cb8528afabb",
|
||||
"sha256:ac514cb86db9a43014d7e73511d521137ac12cf0101b2eaa5f0a3da2e10d913d"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.0.0"
|
||||
"version": "==2.0.1"
|
||||
},
|
||||
"gunicorn": {
|
||||
"hashes": [
|
||||
|
|
@ -330,11 +283,11 @@
|
|||
},
|
||||
"ipython": {
|
||||
"hashes": [
|
||||
"sha256:dfd303b270b7b5232b3d08bd30ec6fd685d8a58cabd54055e3d69d8f029f7280",
|
||||
"sha256:ed7ebe1cba899c1c3ccad6f7f1c2d2369464cc77dba8eebc65e2043e19cda995"
|
||||
"sha256:d9459e7237e2e5858738ff9c3e26504b79899b58a6d49e574d352493d80684c6",
|
||||
"sha256:f6689108b1734501d3b59c84427259fd5ac5141afe2e846cfa8598eb811886c9"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==7.9.0"
|
||||
"version": "==7.12.0"
|
||||
},
|
||||
"ipython-genutils": {
|
||||
"hashes": [
|
||||
|
|
@ -345,10 +298,10 @@
|
|||
},
|
||||
"jedi": {
|
||||
"hashes": [
|
||||
"sha256:786b6c3d80e2f06fd77162a07fed81b8baa22dde5d62896a790a331d6ac21a27",
|
||||
"sha256:ba859c74fa3c966a22f2aeebe1b74ee27e2a462f56d3f5f7ca4a59af61bfe42e"
|
||||
"sha256:b4f4052551025c6b0b0b193b29a6ff7bdb74c52450631206c262aef9f7159ad2",
|
||||
"sha256:d5c871cb9360b414f981e7072c52c33258d598305280fef91c6cae34739d65d5"
|
||||
],
|
||||
"version": "==0.15.1"
|
||||
"version": "==0.16.0"
|
||||
},
|
||||
"jmespath": {
|
||||
"hashes": [
|
||||
|
|
@ -380,25 +333,25 @@
|
|||
},
|
||||
"newrelic": {
|
||||
"hashes": [
|
||||
"sha256:da9adab674d9fe7aa8fbabb6691b33fb7be94a32b6a80548ec7018be9df8ef65"
|
||||
"sha256:8283dd54299b3fd2818a262f38f9193a2ee52b2a02fecca1a1d04764be533c92"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==5.2.1.129"
|
||||
"version": "==5.6.0.135"
|
||||
},
|
||||
"parso": {
|
||||
"hashes": [
|
||||
"sha256:63854233e1fadb5da97f2744b6b24346d2750b85965e7e399bec1620232797dc",
|
||||
"sha256:666b0ee4a7a1220f65d367617f2cd3ffddff3e205f3f16a0284df30e774c2a9c"
|
||||
"sha256:56b2105a80e9c4df49de85e125feb6be69f49920e121406f15e7acde6c9dfc57",
|
||||
"sha256:951af01f61e6dccd04159042a0706a31ad437864ec6e25d0d7a96a9fbb9b0095"
|
||||
],
|
||||
"version": "==0.5.1"
|
||||
"version": "==0.6.1"
|
||||
},
|
||||
"pexpect": {
|
||||
"hashes": [
|
||||
"sha256:2094eefdfcf37a1fdbfb9aa090862c1a4878e5c7e0e7e7088bdb511c558e5cd1",
|
||||
"sha256:9e2c1fd0e6ee3a49b28f95d4b33bc389c89b20af6a1255906e90ff1262ce62eb"
|
||||
"sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937",
|
||||
"sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"
|
||||
],
|
||||
"markers": "sys_platform != 'win32'",
|
||||
"version": "==4.7.0"
|
||||
"version": "==4.8.0"
|
||||
},
|
||||
"pickleshare": {
|
||||
"hashes": [
|
||||
|
|
@ -440,18 +393,16 @@
|
|||
},
|
||||
"promise": {
|
||||
"hashes": [
|
||||
"sha256:2ebbfc10b7abf6354403ed785fe4f04b9dfd421eb1a474ac8d187022228332af",
|
||||
"sha256:348f5f6c3edd4fd47c9cd65aed03ac1b31136d375aa63871a57d3e444c85655c"
|
||||
"sha256:dfd18337c523ba4b6a58801c164c1904a9d4d1b1747c7d5dbf45b693a49d93d0"
|
||||
],
|
||||
"version": "==2.2.1"
|
||||
"version": "==2.3"
|
||||
},
|
||||
"prompt-toolkit": {
|
||||
"hashes": [
|
||||
"sha256:46642344ce457641f28fc9d1c9ca939b63dadf8df128b86f1b9860e59c73a5e4",
|
||||
"sha256:e7f8af9e3d70f514373bf41aa51bc33af12a6db3f71461ea47fea985defb2c31",
|
||||
"sha256:f15af68f66e664eaa559d4ac8a928111eebd5feda0c11738b5998045224829db"
|
||||
"sha256:a402e9bf468b63314e37460b68ba68243d55b2f8c4d0192f85a019af3945050e",
|
||||
"sha256:c93e53af97f630f12f5f62a3274e79527936ed466f038953dfa379d4941f651a"
|
||||
],
|
||||
"version": "==2.0.10"
|
||||
"version": "==3.0.3"
|
||||
},
|
||||
"psycopg2": {
|
||||
"hashes": [
|
||||
|
|
@ -499,18 +450,17 @@
|
|||
},
|
||||
"pygments": {
|
||||
"hashes": [
|
||||
"sha256:71e430bc85c88a430f000ac1d9b331d2407f681d6f6aec95e8bcfbc3df5b0127",
|
||||
"sha256:881c4c157e45f30af185c1ffe8d549d48ac9127433f2c380c24b84572ad66297"
|
||||
"sha256:2a3fe295e54a20164a9df49c75fa58526d3be48e14aceba6d6b1e8ac0bfd6f1b",
|
||||
"sha256:98c8aa5a9f778fcd1026a17361ddaf7330d1b7c62ae97c3bb0ae73e0b9b6b0fe"
|
||||
],
|
||||
"version": "==2.4.2"
|
||||
"version": "==2.5.2"
|
||||
},
|
||||
"python-dateutil": {
|
||||
"hashes": [
|
||||
"sha256:7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb",
|
||||
"sha256:c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e"
|
||||
"sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c",
|
||||
"sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"
|
||||
],
|
||||
"markers": "python_version >= '2.7'",
|
||||
"version": "==2.8.0"
|
||||
"version": "==2.8.1"
|
||||
},
|
||||
"python-dotenv": {
|
||||
"hashes": [
|
||||
|
|
@ -555,6 +505,7 @@
|
|||
"sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4",
|
||||
"sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.22.0"
|
||||
},
|
||||
"rjsmin": {
|
||||
|
|
@ -584,18 +535,17 @@
|
|||
},
|
||||
"s3transfer": {
|
||||
"hashes": [
|
||||
"sha256:6efc926738a3cd576c2a79725fed9afde92378aa5c6a957e3af010cb019fac9d",
|
||||
"sha256:b780f2411b824cb541dbcd2c713d0cb61c7d1bcadae204cdddda2b35cef493ba"
|
||||
"sha256:2525bae2a530195576da53671bae8ca8c55ee8e33bc2225a65e804476611ea5a",
|
||||
"sha256:4924e10451cc37901945806423d16c2c2040a6530645a614ed87e995ccec764c"
|
||||
],
|
||||
"version": "==0.2.1"
|
||||
"version": "==0.3.2"
|
||||
},
|
||||
"sendgrid": {
|
||||
"hashes": [
|
||||
"sha256:a9999878aad90e32d7b62464454adc70bcef40085c729355ea58717bb0ea0dbd",
|
||||
"sha256:cb0b21a83a54bc99d9befda1ea7b4f15fe8db362a152458e58abc5ce23d6d828",
|
||||
"sha256:f04fee009c750b47ab984f3c4a735facacc7fba902052d597f7e60b601e56bcc"
|
||||
"sha256:12ea8203c48c47b03dbe33e219408ca32c9259526d05b783418482d40f17943c",
|
||||
"sha256:5ad98598c13b8cf5545d20f6fb6ecf967a08b48e3e175affabd82cfc71522d01"
|
||||
],
|
||||
"version": "==6.1.0"
|
||||
"version": "==6.1.1"
|
||||
},
|
||||
"sentry-sdk": {
|
||||
"hashes": [
|
||||
|
|
@ -614,10 +564,10 @@
|
|||
},
|
||||
"six": {
|
||||
"hashes": [
|
||||
"sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c",
|
||||
"sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"
|
||||
"sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a",
|
||||
"sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c"
|
||||
],
|
||||
"version": "==1.12.0"
|
||||
"version": "==1.14.0"
|
||||
},
|
||||
"text-unidecode": {
|
||||
"hashes": [
|
||||
|
|
@ -650,11 +600,10 @@
|
|||
},
|
||||
"urllib3": {
|
||||
"hashes": [
|
||||
"sha256:3de946ffbed6e6746608990594d08faac602528ac7015ac28d33cee6a45b7398",
|
||||
"sha256:9a107b99a5393caf59c7aa3c1249c16e6879447533d0887f4336dde834c7be86"
|
||||
"sha256:2f3db8b19923a873b3e5256dc9c2dedfa883e33d87c690d9c7913e1f40673cdc",
|
||||
"sha256:87716c2d2a7121198ebcb7ce7cccf6ce5e9ba539041cfbaeecfb641dc0bf6acc"
|
||||
],
|
||||
"markers": "python_version >= '3.4'",
|
||||
"version": "==1.25.6"
|
||||
"version": "==1.25.8"
|
||||
},
|
||||
"wagtail": {
|
||||
"hashes": [
|
||||
|
|
@ -665,15 +614,19 @@
|
|||
"version": "==2.4"
|
||||
},
|
||||
"wagtail-factories": {
|
||||
"git": "https://github.com/mvantellingen/wagtail-factories.git",
|
||||
"ref": "819666151f8c83317bdd0019074173ba2ade85eb"
|
||||
"hashes": [
|
||||
"sha256:2198e791854ef3883812f532a4d1b364aae1c68abc58a48b8ecec8c61e4a151f",
|
||||
"sha256:416196b88dcdb2d2787926692d7eef7fa0664556900eb6166537026b085d9fbf"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.0.0"
|
||||
},
|
||||
"wcwidth": {
|
||||
"hashes": [
|
||||
"sha256:3df37372226d6e63e1b1e1eda15c594bca98a22d33a23832a90998faa96bc65e",
|
||||
"sha256:f4ebe71925af7b40a864553f761ed559b43544f8f71746c2d756c7fe788ade7c"
|
||||
"sha256:8fd29383f539be45b20bd4df0dc29c20ba48654a41e661925e612311e9f3c603",
|
||||
"sha256:f28b3e8a6483e5d49e7f8949ac1a78314e740333ae305b4ba5defd3e74fb37a8"
|
||||
],
|
||||
"version": "==0.1.7"
|
||||
"version": "==0.1.8"
|
||||
},
|
||||
"webencodings": {
|
||||
"hashes": [
|
||||
|
|
@ -699,21 +652,13 @@
|
|||
}
|
||||
},
|
||||
"develop": {
|
||||
"appnope": {
|
||||
"hashes": [
|
||||
"sha256:5b26757dc6f79a3b7dc9fab95359328d5747fcb2409d331ea66d0272b90ab2a0",
|
||||
"sha256:8b995ffe925347a2138d7ac0fe77155e4311a0ea6d6da4f5128fe4b3cbe5ed71"
|
||||
],
|
||||
"markers": "sys_platform == 'darwin'",
|
||||
"version": "==0.1.0"
|
||||
},
|
||||
"awscli": {
|
||||
"hashes": [
|
||||
"sha256:4a75cb44dc3dab14bc9bdb0d2731c37a5026bf0afa4acb620fec72c74e62915a",
|
||||
"sha256:90b0b3e91a900e4569bc47f29769522337c46ff50e35f9e4a41830fdb425f000"
|
||||
"sha256:4c49f085fb827ca1aeba5e6e5e39f6005110a0059b5c772aeb1d51c4f33c4028",
|
||||
"sha256:9459ac705c2a5d8724057492800c52084df714b624853eb3331087ecf8726a22"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.16.273"
|
||||
"version": "==1.17.9"
|
||||
},
|
||||
"backcall": {
|
||||
"hashes": [
|
||||
|
|
@ -724,56 +669,54 @@
|
|||
},
|
||||
"botocore": {
|
||||
"hashes": [
|
||||
"sha256:61ad58e737e7a5d61308599606cd5a435cc3b97eb7fa693f99663c91bf1706d1",
|
||||
"sha256:8cb038c110822681925a1f5d9005dc2bbc4259fff89d4abfaaf803a3489d0ee3"
|
||||
"sha256:cf3144994191847e30ef76781af867009bdc233b3f1f4736615e5330687a891e",
|
||||
"sha256:f11ff8616f46ca04697df031e622c9ed50931b9d649d4e719f961e9d80771e8d"
|
||||
],
|
||||
"version": "==1.13.9"
|
||||
"version": "==1.14.10"
|
||||
},
|
||||
"colorama": {
|
||||
"hashes": [
|
||||
"sha256:05eed71e2e327246ad6b38c540c4a3117230b19679b875190486ddd2d721422d",
|
||||
"sha256:f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48"
|
||||
],
|
||||
"markers": "python_version != '2.6' and python_version != '3.3'",
|
||||
"version": "==0.4.1"
|
||||
},
|
||||
"coverage": {
|
||||
"hashes": [
|
||||
"sha256:08907593569fe59baca0bf152c43f3863201efb6113ecb38ce7e97ce339805a6",
|
||||
"sha256:0be0f1ed45fc0c185cfd4ecc19a1d6532d72f86a2bac9de7e24541febad72650",
|
||||
"sha256:141f08ed3c4b1847015e2cd62ec06d35e67a3ac185c26f7635f4406b90afa9c5",
|
||||
"sha256:19e4df788a0581238e9390c85a7a09af39c7b539b29f25c89209e6c3e371270d",
|
||||
"sha256:23cc09ed395b03424d1ae30dcc292615c1372bfba7141eb85e11e50efaa6b351",
|
||||
"sha256:245388cda02af78276b479f299bbf3783ef0a6a6273037d7c60dc73b8d8d7755",
|
||||
"sha256:331cb5115673a20fb131dadd22f5bcaf7677ef758741312bee4937d71a14b2ef",
|
||||
"sha256:386e2e4090f0bc5df274e720105c342263423e77ee8826002dcffe0c9533dbca",
|
||||
"sha256:3a794ce50daee01c74a494919d5ebdc23d58873747fa0e288318728533a3e1ca",
|
||||
"sha256:60851187677b24c6085248f0a0b9b98d49cba7ecc7ec60ba6b9d2e5574ac1ee9",
|
||||
"sha256:63a9a5fc43b58735f65ed63d2cf43508f462dc49857da70b8980ad78d41d52fc",
|
||||
"sha256:6b62544bb68106e3f00b21c8930e83e584fdca005d4fffd29bb39fb3ffa03cb5",
|
||||
"sha256:6ba744056423ef8d450cf627289166da65903885272055fb4b5e113137cfa14f",
|
||||
"sha256:7494b0b0274c5072bddbfd5b4a6c6f18fbbe1ab1d22a41e99cd2d00c8f96ecfe",
|
||||
"sha256:826f32b9547c8091679ff292a82aca9c7b9650f9fda3e2ca6bf2ac905b7ce888",
|
||||
"sha256:93715dffbcd0678057f947f496484e906bf9509f5c1c38fc9ba3922893cda5f5",
|
||||
"sha256:9a334d6c83dfeadae576b4d633a71620d40d1c379129d587faa42ee3e2a85cce",
|
||||
"sha256:af7ed8a8aa6957aac47b4268631fa1df984643f07ef00acd374e456364b373f5",
|
||||
"sha256:bf0a7aed7f5521c7ca67febd57db473af4762b9622254291fbcbb8cd0ba5e33e",
|
||||
"sha256:bf1ef9eb901113a9805287e090452c05547578eaab1b62e4ad456fcc049a9b7e",
|
||||
"sha256:c0afd27bc0e307a1ffc04ca5ec010a290e49e3afbe841c5cafc5c5a80ecd81c9",
|
||||
"sha256:dd579709a87092c6dbee09d1b7cfa81831040705ffa12a1b248935274aee0437",
|
||||
"sha256:df6712284b2e44a065097846488f66840445eb987eb81b3cc6e4149e7b6982e1",
|
||||
"sha256:e07d9f1a23e9e93ab5c62902833bf3e4b1f65502927379148b6622686223125c",
|
||||
"sha256:e2ede7c1d45e65e209d6093b762e98e8318ddeff95317d07a27a2140b80cfd24",
|
||||
"sha256:e4ef9c164eb55123c62411f5936b5c2e521b12356037b6e1c2617cef45523d47",
|
||||
"sha256:eca2b7343524e7ba246cab8ff00cab47a2d6d54ada3b02772e908a45675722e2",
|
||||
"sha256:eee64c616adeff7db37cc37da4180a3a5b6177f5c46b187894e633f088fb5b28",
|
||||
"sha256:ef824cad1f980d27f26166f86856efe11eff9912c4fed97d3804820d43fa550c",
|
||||
"sha256:efc89291bd5a08855829a3c522df16d856455297cf35ae827a37edac45f466a7",
|
||||
"sha256:fa964bae817babece5aa2e8c1af841bebb6d0b9add8e637548809d040443fee0",
|
||||
"sha256:ff37757e068ae606659c28c3bd0d923f9d29a85de79bf25b2b34b148473b5025"
|
||||
"sha256:15cf13a6896048d6d947bf7d222f36e4809ab926894beb748fc9caa14605d9c3",
|
||||
"sha256:1daa3eceed220f9fdb80d5ff950dd95112cd27f70d004c7918ca6dfc6c47054c",
|
||||
"sha256:1e44a022500d944d42f94df76727ba3fc0a5c0b672c358b61067abb88caee7a0",
|
||||
"sha256:25dbf1110d70bab68a74b4b9d74f30e99b177cde3388e07cc7272f2168bd1477",
|
||||
"sha256:3230d1003eec018ad4a472d254991e34241e0bbd513e97a29727c7c2f637bd2a",
|
||||
"sha256:3dbb72eaeea5763676a1a1efd9b427a048c97c39ed92e13336e726117d0b72bf",
|
||||
"sha256:5012d3b8d5a500834783689a5d2292fe06ec75dc86ee1ccdad04b6f5bf231691",
|
||||
"sha256:51bc7710b13a2ae0c726f69756cf7ffd4362f4ac36546e243136187cfcc8aa73",
|
||||
"sha256:527b4f316e6bf7755082a783726da20671a0cc388b786a64417780b90565b987",
|
||||
"sha256:722e4557c8039aad9592c6a4213db75da08c2cd9945320220634f637251c3894",
|
||||
"sha256:76e2057e8ffba5472fd28a3a010431fd9e928885ff480cb278877c6e9943cc2e",
|
||||
"sha256:77afca04240c40450c331fa796b3eab6f1e15c5ecf8bf2b8bee9706cd5452fef",
|
||||
"sha256:7afad9835e7a651d3551eab18cbc0fdb888f0a6136169fbef0662d9cdc9987cf",
|
||||
"sha256:9bea19ac2f08672636350f203db89382121c9c2ade85d945953ef3c8cf9d2a68",
|
||||
"sha256:a8b8ac7876bc3598e43e2603f772d2353d9931709345ad6c1149009fd1bc81b8",
|
||||
"sha256:b0840b45187699affd4c6588286d429cd79a99d509fe3de0f209594669bb0954",
|
||||
"sha256:b26aaf69713e5674efbde4d728fb7124e429c9466aeaf5f4a7e9e699b12c9fe2",
|
||||
"sha256:b63dd43f455ba878e5e9f80ba4f748c0a2156dde6e0e6e690310e24d6e8caf40",
|
||||
"sha256:be18f4ae5a9e46edae3f329de2191747966a34a3d93046dbdf897319923923bc",
|
||||
"sha256:c312e57847db2526bc92b9bfa78266bfbaabac3fdcd751df4d062cd4c23e46dc",
|
||||
"sha256:c60097190fe9dc2b329a0eb03393e2e0829156a589bd732e70794c0dd804258e",
|
||||
"sha256:c62a2143e1313944bf4a5ab34fd3b4be15367a02e9478b0ce800cb510e3bbb9d",
|
||||
"sha256:cc1109f54a14d940b8512ee9f1c3975c181bbb200306c6d8b87d93376538782f",
|
||||
"sha256:cd60f507c125ac0ad83f05803063bed27e50fa903b9c2cfee3f8a6867ca600fc",
|
||||
"sha256:d513cc3db248e566e07a0da99c230aca3556d9b09ed02f420664e2da97eac301",
|
||||
"sha256:d649dc0bcace6fcdb446ae02b98798a856593b19b637c1b9af8edadf2b150bea",
|
||||
"sha256:d7008a6796095a79544f4da1ee49418901961c97ca9e9d44904205ff7d6aa8cb",
|
||||
"sha256:da93027835164b8223e8e5af2cf902a4c80ed93cb0909417234f4a9df3bcd9af",
|
||||
"sha256:e69215621707119c6baf99bda014a45b999d37602cb7043d943c76a59b05bf52",
|
||||
"sha256:ea9525e0fef2de9208250d6c5aeeee0138921057cd67fcef90fbed49c4d62d37",
|
||||
"sha256:fca1669d464f0c9831fd10be2eef6b86f5ebd76c724d1e0706ebdff86bb4adf0"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==4.5.4"
|
||||
"version": "==5.0.3"
|
||||
},
|
||||
"decorator": {
|
||||
"hashes": [
|
||||
|
|
@ -792,18 +735,18 @@
|
|||
},
|
||||
"ipdb": {
|
||||
"hashes": [
|
||||
"sha256:473fdd798a099765f093231a8b1fabfa95b0b682fce12de0c74b61a4b4d8ee57"
|
||||
"sha256:5d9a4a0e3b7027a158fc6f2929934341045b9c3b0b86ed5d7e84e409653f72fd"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==0.12.2"
|
||||
"version": "==0.12.3"
|
||||
},
|
||||
"ipython": {
|
||||
"hashes": [
|
||||
"sha256:dfd303b270b7b5232b3d08bd30ec6fd685d8a58cabd54055e3d69d8f029f7280",
|
||||
"sha256:ed7ebe1cba899c1c3ccad6f7f1c2d2369464cc77dba8eebc65e2043e19cda995"
|
||||
"sha256:d9459e7237e2e5858738ff9c3e26504b79899b58a6d49e574d352493d80684c6",
|
||||
"sha256:f6689108b1734501d3b59c84427259fd5ac5141afe2e846cfa8598eb811886c9"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==7.9.0"
|
||||
"version": "==7.12.0"
|
||||
},
|
||||
"ipython-genutils": {
|
||||
"hashes": [
|
||||
|
|
@ -814,10 +757,10 @@
|
|||
},
|
||||
"jedi": {
|
||||
"hashes": [
|
||||
"sha256:786b6c3d80e2f06fd77162a07fed81b8baa22dde5d62896a790a331d6ac21a27",
|
||||
"sha256:ba859c74fa3c966a22f2aeebe1b74ee27e2a462f56d3f5f7ca4a59af61bfe42e"
|
||||
"sha256:b4f4052551025c6b0b0b193b29a6ff7bdb74c52450631206c262aef9f7159ad2",
|
||||
"sha256:d5c871cb9360b414f981e7072c52c33258d598305280fef91c6cae34739d65d5"
|
||||
],
|
||||
"version": "==0.15.1"
|
||||
"version": "==0.16.0"
|
||||
},
|
||||
"jmespath": {
|
||||
"hashes": [
|
||||
|
|
@ -828,18 +771,18 @@
|
|||
},
|
||||
"parso": {
|
||||
"hashes": [
|
||||
"sha256:63854233e1fadb5da97f2744b6b24346d2750b85965e7e399bec1620232797dc",
|
||||
"sha256:666b0ee4a7a1220f65d367617f2cd3ffddff3e205f3f16a0284df30e774c2a9c"
|
||||
"sha256:56b2105a80e9c4df49de85e125feb6be69f49920e121406f15e7acde6c9dfc57",
|
||||
"sha256:951af01f61e6dccd04159042a0706a31ad437864ec6e25d0d7a96a9fbb9b0095"
|
||||
],
|
||||
"version": "==0.5.1"
|
||||
"version": "==0.6.1"
|
||||
},
|
||||
"pexpect": {
|
||||
"hashes": [
|
||||
"sha256:2094eefdfcf37a1fdbfb9aa090862c1a4878e5c7e0e7e7088bdb511c558e5cd1",
|
||||
"sha256:9e2c1fd0e6ee3a49b28f95d4b33bc389c89b20af6a1255906e90ff1262ce62eb"
|
||||
"sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937",
|
||||
"sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"
|
||||
],
|
||||
"markers": "sys_platform != 'win32'",
|
||||
"version": "==4.7.0"
|
||||
"version": "==4.8.0"
|
||||
},
|
||||
"pickleshare": {
|
||||
"hashes": [
|
||||
|
|
@ -850,11 +793,10 @@
|
|||
},
|
||||
"prompt-toolkit": {
|
||||
"hashes": [
|
||||
"sha256:46642344ce457641f28fc9d1c9ca939b63dadf8df128b86f1b9860e59c73a5e4",
|
||||
"sha256:e7f8af9e3d70f514373bf41aa51bc33af12a6db3f71461ea47fea985defb2c31",
|
||||
"sha256:f15af68f66e664eaa559d4ac8a928111eebd5feda0c11738b5998045224829db"
|
||||
"sha256:a402e9bf468b63314e37460b68ba68243d55b2f8c4d0192f85a019af3945050e",
|
||||
"sha256:c93e53af97f630f12f5f62a3274e79527936ed466f038953dfa379d4941f651a"
|
||||
],
|
||||
"version": "==2.0.10"
|
||||
"version": "==3.0.3"
|
||||
},
|
||||
"ptyprocess": {
|
||||
"hashes": [
|
||||
|
|
@ -865,44 +807,40 @@
|
|||
},
|
||||
"pyasn1": {
|
||||
"hashes": [
|
||||
"sha256:62cdade8b5530f0b185e09855dd422bc05c0bbff6b72ff61381c09dac7befd8c",
|
||||
"sha256:a9495356ca1d66ed197a0f72b41eb1823cf7ea8b5bd07191673e8147aecf8604"
|
||||
"sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d",
|
||||
"sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba"
|
||||
],
|
||||
"version": "==0.4.7"
|
||||
"version": "==0.4.8"
|
||||
},
|
||||
"pygments": {
|
||||
"hashes": [
|
||||
"sha256:71e430bc85c88a430f000ac1d9b331d2407f681d6f6aec95e8bcfbc3df5b0127",
|
||||
"sha256:881c4c157e45f30af185c1ffe8d549d48ac9127433f2c380c24b84572ad66297"
|
||||
"sha256:2a3fe295e54a20164a9df49c75fa58526d3be48e14aceba6d6b1e8ac0bfd6f1b",
|
||||
"sha256:98c8aa5a9f778fcd1026a17361ddaf7330d1b7c62ae97c3bb0ae73e0b9b6b0fe"
|
||||
],
|
||||
"version": "==2.4.2"
|
||||
"version": "==2.5.2"
|
||||
},
|
||||
"python-dateutil": {
|
||||
"hashes": [
|
||||
"sha256:7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb",
|
||||
"sha256:c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e"
|
||||
"sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c",
|
||||
"sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"
|
||||
],
|
||||
"markers": "python_version >= '2.7'",
|
||||
"version": "==2.8.0"
|
||||
"version": "==2.8.1"
|
||||
},
|
||||
"pyyaml": {
|
||||
"hashes": [
|
||||
"sha256:0113bc0ec2ad727182326b61326afa3d1d8280ae1122493553fd6f4397f33df9",
|
||||
"sha256:01adf0b6c6f61bd11af6e10ca52b7d4057dd0be0343eb9283c878cf3af56aee4",
|
||||
"sha256:5124373960b0b3f4aa7df1707e63e9f109b5263eca5976c66e08b1c552d4eaf8",
|
||||
"sha256:5ca4f10adbddae56d824b2c09668e91219bb178a1eee1faa56af6f99f11bf696",
|
||||
"sha256:7907be34ffa3c5a32b60b95f4d95ea25361c951383a894fec31be7252b2b6f34",
|
||||
"sha256:7ec9b2a4ed5cad025c2278a1e6a19c011c80a3caaac804fd2d329e9cc2c287c9",
|
||||
"sha256:87ae4c829bb25b9fe99cf71fbb2140c448f534e24c998cc60f39ae4f94396a73",
|
||||
"sha256:9de9919becc9cc2ff03637872a440195ac4241c80536632fffeb6a1e25a74299",
|
||||
"sha256:a5a85b10e450c66b49f98846937e8cfca1db3127a9d5d1e31ca45c3d0bef4c5b",
|
||||
"sha256:b0997827b4f6a7c286c01c5f60384d218dca4ed7d9efa945c3e1aa623d5709ae",
|
||||
"sha256:b631ef96d3222e62861443cc89d6563ba3eeb816eeb96b2629345ab795e53681",
|
||||
"sha256:bf47c0607522fdbca6c9e817a6e81b08491de50f3766a7a0e6a5be7905961b41",
|
||||
"sha256:f81025eddd0327c7d4cfe9b62cf33190e1e736cc6e97502b3ec425f574b3e7a8"
|
||||
"sha256:0e7f69397d53155e55d10ff68fdfb2cf630a35e6daf65cf0bdeaf04f127c09dc",
|
||||
"sha256:2e9f0b7c5914367b0916c3c104a024bb68f269a486b9d04a2e8ac6f6597b7803",
|
||||
"sha256:35ace9b4147848cafac3db142795ee42deebe9d0dad885ce643928e88daebdcc",
|
||||
"sha256:38a4f0d114101c58c0f3a88aeaa44d63efd588845c5a2df5290b73db8f246d15",
|
||||
"sha256:483eb6a33b671408c8529106df3707270bfacb2447bf8ad856a4b4f57f6e3075",
|
||||
"sha256:4b6be5edb9f6bb73680f5bf4ee08ff25416d1400fbd4535fe0069b2994da07cd",
|
||||
"sha256:7f38e35c00e160db592091751d385cd7b3046d6d51f578b29943225178257b31",
|
||||
"sha256:8100c896ecb361794d8bfdb9c11fce618c7cf83d624d73d5ab38aef3bc82d43f",
|
||||
"sha256:c0ee8eca2c582d29c3c2ec6e2c4f703d1b7f1fb10bc72317355a746057e7346c",
|
||||
"sha256:e4c015484ff0ff197564917b4b4246ca03f411b9bd7f16e02a2f586eb48b6d04",
|
||||
"sha256:ebc4ed52dcc93eeebeae5cf5deb2ae4347b3a81c3fa12b0b8c976544829396a4"
|
||||
],
|
||||
"markers": "python_version != '2.6' and python_version != '3.3'",
|
||||
"version": "==5.1.2"
|
||||
"version": "==5.2"
|
||||
},
|
||||
"rsa": {
|
||||
"hashes": [
|
||||
|
|
@ -913,17 +851,17 @@
|
|||
},
|
||||
"s3transfer": {
|
||||
"hashes": [
|
||||
"sha256:6efc926738a3cd576c2a79725fed9afde92378aa5c6a957e3af010cb019fac9d",
|
||||
"sha256:b780f2411b824cb541dbcd2c713d0cb61c7d1bcadae204cdddda2b35cef493ba"
|
||||
"sha256:2525bae2a530195576da53671bae8ca8c55ee8e33bc2225a65e804476611ea5a",
|
||||
"sha256:4924e10451cc37901945806423d16c2c2040a6530645a614ed87e995ccec764c"
|
||||
],
|
||||
"version": "==0.2.1"
|
||||
"version": "==0.3.2"
|
||||
},
|
||||
"six": {
|
||||
"hashes": [
|
||||
"sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c",
|
||||
"sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"
|
||||
"sha256:236bdbdce46e6e6a3d61a337c0f8b763ca1e8717c03b369e87a7ec7ce1319c0a",
|
||||
"sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c"
|
||||
],
|
||||
"version": "==1.12.0"
|
||||
"version": "==1.14.0"
|
||||
},
|
||||
"traitlets": {
|
||||
"hashes": [
|
||||
|
|
@ -934,18 +872,17 @@
|
|||
},
|
||||
"urllib3": {
|
||||
"hashes": [
|
||||
"sha256:3de946ffbed6e6746608990594d08faac602528ac7015ac28d33cee6a45b7398",
|
||||
"sha256:9a107b99a5393caf59c7aa3c1249c16e6879447533d0887f4336dde834c7be86"
|
||||
"sha256:2f3db8b19923a873b3e5256dc9c2dedfa883e33d87c690d9c7913e1f40673cdc",
|
||||
"sha256:87716c2d2a7121198ebcb7ce7cccf6ce5e9ba539041cfbaeecfb641dc0bf6acc"
|
||||
],
|
||||
"markers": "python_version >= '3.4'",
|
||||
"version": "==1.25.6"
|
||||
"version": "==1.25.8"
|
||||
},
|
||||
"wcwidth": {
|
||||
"hashes": [
|
||||
"sha256:3df37372226d6e63e1b1e1eda15c594bca98a22d33a23832a90998faa96bc65e",
|
||||
"sha256:f4ebe71925af7b40a864553f761ed559b43544f8f71746c2d756c7fe788ade7c"
|
||||
"sha256:8fd29383f539be45b20bd4df0dc29c20ba48654a41e661925e612311e9f3c603",
|
||||
"sha256:f28b3e8a6483e5d49e7f8949ac1a78314e740333ae305b4ba5defd3e74fb37a8"
|
||||
],
|
||||
"version": "==0.1.7"
|
||||
"version": "==0.1.8"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
20
README.md
20
README.md
|
|
@ -175,3 +175,23 @@ You can and should then push the tag to the repo
|
|||
You can later see the metadata of the tag with
|
||||
|
||||
git show release/v2019-09-10
|
||||
|
||||
|
||||
## Testing
|
||||
|
||||
## Mocking GraphQL calls
|
||||
|
||||
We use [cypress-graphql-mock](https://github.com/tgriesser/cypress-graphql-mock) for mocking GraphQL calls in Cypress tests.
|
||||
|
||||
For an example, please see `spellcheck.spec.js`.
|
||||
|
||||
There is a schema.json in the fixtures folder. For now it has been generated once, and if there is a significant update to the schema on the server, it has to be regenerated.
|
||||
|
||||
To generate a new schema, use the management command
|
||||
|
||||
```
|
||||
python manage.py graphql_schema --schema api.schema.schema --out schema.json --indent 4
|
||||
```
|
||||
|
||||
Then, remove the `data` property from the generated `schema.json`, so the `__schema` property is on the top level.
|
||||
Also remove the two objects with `"name": "__debug"` from the JSON file.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"assignments": {
|
||||
"edges": [
|
||||
{
|
||||
"node": {
|
||||
"id": "QXNzaWdubWVudE5vZGU6MQ==",
|
||||
"title": "Ein Auftragstitel",
|
||||
"assignment": "Ein Auftrag",
|
||||
"solution": null,
|
||||
"submission": {
|
||||
"id": "U3R1ZGVudFN1Ym1pc3Npb25Ob2RlOjE=",
|
||||
"text": "Hir ist ein Feler gewesen",
|
||||
"final": false,
|
||||
"document": "",
|
||||
"submissionFeedback": {
|
||||
"id": "U3VibWlzc2lvbkZlZWRiYWNrTm9kZTox",
|
||||
"text": "\ud83d\ude42\ud83d\ude10\ud83e\udd2c\ud83d\udc4d\ud83e\udd22\ud83e\udd22\ud83e\udd22\ud83e\udd22\ud83d\ude2e\ud83e\udd17",
|
||||
"teacher": {
|
||||
"firstName": "Nico",
|
||||
"lastName": "Zickgraf",
|
||||
"__typename": "UserNode"
|
||||
},
|
||||
"__typename": "SubmissionFeedbackNode"
|
||||
},
|
||||
"__typename": "StudentSubmissionNode"
|
||||
},
|
||||
"__typename": "AssignmentNode"
|
||||
},
|
||||
"__typename": "AssignmentNodeEdge"
|
||||
}
|
||||
],
|
||||
"__typename": "AssignmentNodeConnection"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
{
|
||||
"id": "TW9kdWxlTm9kZTozMQ==",
|
||||
"title": "Geld",
|
||||
"metaTitle": "Modul 2",
|
||||
"teaser": " Geld braucht jeder von uns im t\u00e4glichen Leben.",
|
||||
"intro": "\n <p>Jeder B\u00fcrger nutzt es. Nahezu jeden Tag. Kaum ein Tag vergeht, an dem wir nicht mit M\u00fcnzen oder Geldscheinen bezahlen, bargeldlose \u00dcberweisungen t\u00e4tigen oder andere Zahlungsmethoden verwenden. Doch was genau befindet sich da eigentlich in unserem Geldbeutel? Was ist das, was auf unseren Konten liegt und die Bezeichnung Geld tr\u00e4gt?</p>\n ",
|
||||
"slug": "geld",
|
||||
"heroImage": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z/C/HgAGgwJ/lK3Q6wAAAABJRU5ErkJggg==",
|
||||
"solutionsEnabled": false,
|
||||
"bookmark": null,
|
||||
"__typename": "ModuleNode",
|
||||
"assignments": {
|
||||
"edges": [],
|
||||
"__typename": "AssignmentNodeConnection"
|
||||
},
|
||||
"objectiveGroups": {
|
||||
"edges": [],
|
||||
"__typename": "ObjectiveGroupNodeConnection"
|
||||
},
|
||||
"chapters": {
|
||||
"edges": [
|
||||
{
|
||||
"node": {
|
||||
"id": "Q2hhcHRlck5vZGU6MzI=",
|
||||
"title": "2.1 Eine Welt ohne Geld?",
|
||||
"description": "",
|
||||
"bookmark": null,
|
||||
"contentBlocks": {
|
||||
"edges": [
|
||||
{
|
||||
"node": {
|
||||
"id": "Q29udGVudEJsb2NrTm9kZToxOQ==",
|
||||
"slug": "assignment",
|
||||
"title": "Assignment",
|
||||
"type": "NORMAL",
|
||||
"contents": [
|
||||
{
|
||||
"type": "assignment",
|
||||
"value": {
|
||||
"title": "Ein Auftragstitel",
|
||||
"assignment": "Ein Auftrag",
|
||||
"id": "QXNzaWdubWVudE5vZGU6MQ=="
|
||||
},
|
||||
"id": "df8212ee-3e82-49fa-977e-c4b60789163e"
|
||||
}
|
||||
],
|
||||
"userCreated": false,
|
||||
"mine": false,
|
||||
"bookmarks": [
|
||||
{
|
||||
"uuid": "df8212ee-3e82-49fa-977e-c4b60789163e",
|
||||
"note": {
|
||||
"id": "Tm90ZU5vZGU6Mw==",
|
||||
"text": "Noch eine Notiz",
|
||||
"__typename": "NoteNode"
|
||||
},
|
||||
"__typename": "ContentBlockBookmarkNode"
|
||||
}
|
||||
],
|
||||
"hiddenFor": {
|
||||
"edges": [],
|
||||
"__typename": "SchoolClassNodeConnection"
|
||||
},
|
||||
"visibleFor": {
|
||||
"edges": [],
|
||||
"__typename": "SchoolClassNodeConnection"
|
||||
},
|
||||
"__typename": "ContentBlockNode"
|
||||
},
|
||||
"__typename": "ContentBlockNodeEdge"
|
||||
}
|
||||
],
|
||||
"__typename": "ContentBlockNodeConnection"
|
||||
},
|
||||
"__typename": "ChapterNode"
|
||||
},
|
||||
"__typename": "ChapterNodeEdge"
|
||||
}
|
||||
],
|
||||
"__typename": "ChapterNodeConnection"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
{
|
||||
"id": "TW9kdWxlTm9kZToxNw==",
|
||||
"title": "Lohn und Budget",
|
||||
"metaTitle": "Modul 1",
|
||||
"teaser": "Die Berufsbildung ist ein neuer Lebensabschnit",
|
||||
"intro": "\n <p>Sie stehen am Anfang eines neuen Lebensabschnitts. In Ihrer Rolle als Berufslernende oder Berufslernender haben Sie Verantwortung übernommen.</p>\n <p>Wie erging es Ihnen am ersten Arbeits- und Schultag?</p>\n ",
|
||||
"slug": "lohn-und-budget",
|
||||
"heroImage": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z/C/HgAGgwJ/lK3Q6wAAAABJRU5ErkJggg==",
|
||||
"solutionsEnabled": false,
|
||||
"bookmark": {
|
||||
"note": null,
|
||||
"__typename": "ModuleBookmarkNode"
|
||||
},
|
||||
"__typename": "ModuleNode",
|
||||
"assignments": {
|
||||
"edges": [
|
||||
{
|
||||
"node": {
|
||||
"id": "QXNzaWdubWVudE5vZGU6MQ==",
|
||||
"title": "Ein Auftragstitel",
|
||||
"assignment": "Ein Auftrag",
|
||||
"solution": null,
|
||||
"submission": {
|
||||
"id": "U3R1ZGVudFN1Ym1pc3Npb25Ob2RlOjE=",
|
||||
"text": "Hir ist ein Feler gewesen",
|
||||
"final": false,
|
||||
"document": "",
|
||||
"submissionFeedback": {
|
||||
"id": "U3VibWlzc2lvbkZlZWRiYWNrTm9kZTox",
|
||||
"text": "🙂😐🤬👍🤢🤢🤢🤢😮🤗",
|
||||
"teacher": {
|
||||
"firstName": "Nico",
|
||||
"lastName": "Zickgraf",
|
||||
"__typename": "UserNode"
|
||||
},
|
||||
"__typename": "SubmissionFeedbackNode"
|
||||
},
|
||||
"__typename": "StudentSubmissionNode"
|
||||
},
|
||||
"__typename": "AssignmentNode"
|
||||
},
|
||||
"__typename": "AssignmentNodeEdge"
|
||||
}
|
||||
],
|
||||
"__typename": "AssignmentNodeConnection"
|
||||
},
|
||||
"objectiveGroups": {
|
||||
"edges": [],
|
||||
"__typename": "ObjectiveGroupNodeConnection"
|
||||
},
|
||||
"chapters": {
|
||||
"edges": [
|
||||
{
|
||||
"node": {
|
||||
"id": "Q2hhcHRlck5vZGU6MTg=",
|
||||
"title": "1.1 Lehrbeginn",
|
||||
"description": "Wie sieht Ihr Konsumverhalten aus?",
|
||||
"bookmark": {
|
||||
"note": {
|
||||
"id": "Tm90ZU5vZGU6Mg==",
|
||||
"text": "Chapter Chapter",
|
||||
"__typename": "NoteNode"
|
||||
},
|
||||
"__typename": "ChapterBookmarkNode"
|
||||
},
|
||||
"contentBlocks": {
|
||||
"edges": [
|
||||
{
|
||||
"node": {
|
||||
"id": "Q29udGVudEJsb2NrTm9kZToxOQ==",
|
||||
"slug": "assignment",
|
||||
"title": "Assignment",
|
||||
"type": "NORMAL",
|
||||
"contents": [
|
||||
{
|
||||
"type": "assignment",
|
||||
"value": {
|
||||
"title": "Ein Auftragstitel",
|
||||
"assignment": "Ein Auftrag",
|
||||
"id": "QXNzaWdubWVudE5vZGU6MQ=="
|
||||
},
|
||||
"id": "df8212ee-3e82-49fa-977e-c4b60789163e"
|
||||
}
|
||||
],
|
||||
"userCreated": false,
|
||||
"mine": false,
|
||||
"bookmarks": [
|
||||
{
|
||||
"uuid": "df8212ee-3e82-49fa-977e-c4b60789163e",
|
||||
"note": {
|
||||
"id": "Tm90ZU5vZGU6Mw==",
|
||||
"text": "Noch eine Notiz",
|
||||
"__typename": "NoteNode"
|
||||
},
|
||||
"__typename": "ContentBlockBookmarkNode"
|
||||
}
|
||||
],
|
||||
"hiddenFor": {
|
||||
"edges": [],
|
||||
"__typename": "SchoolClassNodeConnection"
|
||||
},
|
||||
"visibleFor": {
|
||||
"edges": [],
|
||||
"__typename": "SchoolClassNodeConnection"
|
||||
},
|
||||
"__typename": "ContentBlockNode"
|
||||
},
|
||||
"__typename": "ContentBlockNodeEdge"
|
||||
}
|
||||
],
|
||||
"__typename": "ContentBlockNodeConnection"
|
||||
},
|
||||
"__typename": "ChapterNode"
|
||||
},
|
||||
"__typename": "ChapterNodeEdge"
|
||||
}
|
||||
],
|
||||
"__typename": "ChapterNodeConnection"
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"correct": false,
|
||||
"results": [
|
||||
{
|
||||
"sentence": "Hir ist ein Feler gewesen",
|
||||
"offset": 0,
|
||||
"length": 3,
|
||||
"sentenceOffset": 0,
|
||||
"affected": "Hir",
|
||||
"corrected": "Dir",
|
||||
"__typename": "SpellCheckStepNode"
|
||||
},
|
||||
{
|
||||
"sentence": "Hir ist ein Feler gewesen",
|
||||
"offset": 12,
|
||||
"length": 5,
|
||||
"sentenceOffset": 0,
|
||||
"affected": "Feler",
|
||||
"corrected": "Fehler",
|
||||
"__typename": "SpellCheckStepNode"
|
||||
},
|
||||
{
|
||||
"sentence": "Hir ist ein Feler gewesen",
|
||||
"offset": 18,
|
||||
"length": 7,
|
||||
"sentenceOffset": 0,
|
||||
"affected": "gewesen",
|
||||
"corrected": "gewesen.",
|
||||
"__typename": "SpellCheckStepNode"
|
||||
}
|
||||
],
|
||||
"__typename": "SpellCheckPayload"
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
describe('Survey', () => {
|
||||
beforeEach(() => {
|
||||
// todo: mock all the graphql queries and mutations
|
||||
cy.exec("python ../server/manage.py prepare_bookmarks_for_cypress");
|
||||
|
||||
cy.viewport('macbook-15');
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ describe('Change Password Page', () => {
|
|||
const validationOldWrongMsg = 'Die Eingabe ist falsch';
|
||||
|
||||
beforeEach(function () {
|
||||
// todo: mock all the graphql queries and mutations
|
||||
cy.clearCookies();
|
||||
cy.visit('/me/profile');
|
||||
cy.login('rahel.cueni', 'test');
|
||||
|
|
|
|||
|
|
@ -1,24 +1,82 @@
|
|||
const schema = require('../fixtures/schema.json');
|
||||
const assignments = require('../fixtures/assignments.json');
|
||||
const lohnModule = require('../fixtures/module.json');
|
||||
const geldModule = require('../fixtures/module-geld.json');
|
||||
|
||||
describe('Current Module', () => {
|
||||
before(() => {
|
||||
cy.server();
|
||||
|
||||
cy.mockGraphql({
|
||||
schema: schema,
|
||||
// endpoint: '/api/graphql'
|
||||
operations: {
|
||||
MeQuery: variables => {
|
||||
return {
|
||||
me: {
|
||||
'lastModule': {
|
||||
// 'id': 'TW9kdWxlTm9kZToxNw==',
|
||||
'slug': 'lohn-und-budget',
|
||||
'__typename': 'ModuleNode'
|
||||
},
|
||||
'__typename': 'UserNode',
|
||||
'permissions': []
|
||||
}
|
||||
}
|
||||
},
|
||||
AssignmentsQuery: {
|
||||
assignments
|
||||
},
|
||||
ModulesQuery: variables => {
|
||||
let module;
|
||||
if (variables.slug === 'lohn-und-budget') {
|
||||
module = lohnModule;
|
||||
} else {
|
||||
module = geldModule
|
||||
}
|
||||
return {
|
||||
module
|
||||
}
|
||||
},
|
||||
UpdateLastModule: variables => {
|
||||
let module;
|
||||
if (variables.input.id === 'TW9kdWxlTm9kZToxNw==') {
|
||||
module = lohnModule
|
||||
} else {
|
||||
module = geldModule
|
||||
}
|
||||
|
||||
return {
|
||||
updateLastModule: {
|
||||
module,
|
||||
errors: null,
|
||||
__typename: 'UpdateLastModulePayload'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('is set correctly', () => {
|
||||
// cy.route('POST', '/api/graphql/').as('graphQL');
|
||||
cy.startGraphQLCapture();
|
||||
cy.viewport('macbook-15');
|
||||
|
||||
cy.visit('/module/lohn-und-budget');
|
||||
cy.login('nico.zickgraf', 'test');
|
||||
cy.apolloLogin('nico.zickgraf', 'test');
|
||||
cy.visit('/book/topic/geld-und-kauf');
|
||||
cy.contains('Modul 1').click();
|
||||
|
||||
cy.get('[data-cy=module-title]').should('contain', 'Lohn und Budget')
|
||||
cy.get('[data-cy=module-title]').should('contain', 'Lohn und Budget');
|
||||
|
||||
cy.visit('/');
|
||||
cy.waitFor('MeQuery');
|
||||
cy.get('[data-cy="home-link"]').click();
|
||||
cy.get('[data-cy="current-module-link"]').click();
|
||||
cy.get('[data-cy=module-title]').should('contain', 'Lohn und Budget')
|
||||
cy.get('[data-cy=module-title]').should('contain', 'Lohn und Budget');
|
||||
|
||||
cy.visit('/module/geld');
|
||||
cy.get('[data-cy=module-title]').should('contain', 'Geld')
|
||||
cy.visit('/book/topic/geld-und-kauf');
|
||||
cy.contains('Modul 2').click();
|
||||
cy.get('[data-cy=module-title]').should('contain', 'Geld');
|
||||
|
||||
cy.get('[data-cy="home-link"]').click();
|
||||
cy.get('[data-cy="current-module-link"]').click();
|
||||
cy.get('[data-cy=module-title]').should('contain', 'Geld')
|
||||
})
|
||||
})
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
describe('The Logged In Home Page', () => {
|
||||
it('successfully loads', () => {
|
||||
// todo: use graphql login
|
||||
cy.visit('/');
|
||||
cy.login('test', 'test');
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,53 @@
|
|||
const schema = require('../fixtures/schema.json');
|
||||
|
||||
describe('New project', () => {
|
||||
it('creates a new project and displays it', () => {
|
||||
cy.server();
|
||||
|
||||
cy.mockGraphql({
|
||||
schema: schema,
|
||||
operations: {
|
||||
ProjectsQuery: {
|
||||
projects: {
|
||||
edges: [
|
||||
{
|
||||
node: {
|
||||
id: 'UHJvamVjdE5vZGU6NjY=',
|
||||
title: 'Some random title',
|
||||
appearance: 'blue',
|
||||
description: 'This description rocks',
|
||||
slug: 'some-random-title',
|
||||
objectives: 'Git gud',
|
||||
final: false,
|
||||
student: {
|
||||
firstName: 'Rahel',
|
||||
lastName: 'Cueni',
|
||||
id: 'VXNlck5vZGU6NQ==',
|
||||
avatarUrl: '',
|
||||
__typename: 'UserNode'
|
||||
},
|
||||
entriesCount: 0,
|
||||
__typename: 'ProjectNode',
|
||||
},
|
||||
__typename: 'ProjectNodeEdge'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
AddProject: variables => ({
|
||||
addProject: {
|
||||
project: Object.assign({}, variables.input.project),
|
||||
errors: null,
|
||||
__typename: 'AddProjectPayload'
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
;
|
||||
|
||||
cy.viewport('macbook-15');
|
||||
cy.apolloLogin('rahel.cueni', 'test');
|
||||
cy.visit('/portfolio');
|
||||
cy.login('rahel.cueni', 'test');
|
||||
|
||||
cy.get('[data-cy=add-project-button]').click();
|
||||
cy.get('[data-cy=page-form-input-titel]').type('Some random title');
|
||||
|
|
|
|||
|
|
@ -1,11 +1,102 @@
|
|||
const schema = require('../fixtures/schema.json');
|
||||
|
||||
describe('Project Entry', () => {
|
||||
beforeEach(() => {
|
||||
cy.exec("python ../server/manage.py prepare_projects_for_cypress");
|
||||
|
||||
cy.viewport('macbook-15');
|
||||
cy.startGraphQLCapture();
|
||||
cy.login('rahel.cueni', 'test', true);
|
||||
cy.get('body').contains('Neues Wissen erwerben');
|
||||
cy.apolloLogin('rahel.cueni', 'test');
|
||||
|
||||
cy.mockGraphql({
|
||||
schema: schema,
|
||||
operations: {
|
||||
MeQuery: {
|
||||
me: {
|
||||
id: 'VXNlck5vZGU6NQ==',
|
||||
permissions: []
|
||||
}
|
||||
},
|
||||
ProjectsQuery: {
|
||||
projects: {
|
||||
edges: [{
|
||||
node: {
|
||||
id: 'UHJvamVjdE5vZGU6MzM=',
|
||||
title: 'Groot',
|
||||
appearance: 'red',
|
||||
'description': 'I am Groot',
|
||||
'slug': 'groot',
|
||||
'objectives': 'Be Groot\nBe awesome',
|
||||
'final': false,
|
||||
'student': {
|
||||
'firstName': 'Rahel',
|
||||
'lastName': 'Cueni',
|
||||
'id': 'VXNlck5vZGU6NQ==',
|
||||
'avatarUrl': '',
|
||||
'__typename': 'UserNode'
|
||||
},
|
||||
'entriesCount': 2,
|
||||
'__typename': 'ProjectNode'
|
||||
},
|
||||
'__typename': 'ProjectNodeEdge'
|
||||
}],
|
||||
'__typename': 'ProjectNodeConnection'
|
||||
}
|
||||
},
|
||||
ProjectQuery: {
|
||||
"project": {
|
||||
"id": "UHJvamVjdE5vZGU6MzY=",
|
||||
"title": "Groot",
|
||||
"appearance": "yellow",
|
||||
"description": "I am Groot",
|
||||
"slug": "groot",
|
||||
"objectives": "Be Groot\nBe awesome",
|
||||
"final": false,
|
||||
"student": {
|
||||
"firstName": "Rahel",
|
||||
"lastName": "Cueni",
|
||||
"id": "VXNlck5vZGU6NQ==",
|
||||
"avatarUrl": "",
|
||||
"__typename": "UserNode"
|
||||
},
|
||||
"entriesCount": 1,
|
||||
"__typename": "ProjectNode",
|
||||
"entries": {
|
||||
"edges": [{
|
||||
"node": {
|
||||
"id": "UHJvamVjdEVudHJ5Tm9kZTo2NQ==",
|
||||
"activity": "Kill Thanos",
|
||||
"reflection": "He sucks",
|
||||
"nextSteps": "Go for the head",
|
||||
"documentUrl": "",
|
||||
"__typename": "ProjectEntryNode",
|
||||
"created": "2020-01-20T15:20:31.262510+00:00"
|
||||
}, "__typename": "ProjectEntryNodeEdge"
|
||||
}], "__typename": "ProjectEntryNodeConnection"
|
||||
}
|
||||
}
|
||||
},
|
||||
AddProjectEntry: variables => ({
|
||||
addProjectEntry: {
|
||||
projectEntry: Object.assign({}, variables.input.projectEntry, {
|
||||
created: '2020-01-20T15:26:58.722773+00:00'
|
||||
}),
|
||||
errors: null,
|
||||
__typename: 'AddProjectEntryPayload'
|
||||
}
|
||||
}),
|
||||
UpdateProjectEntry: variables => ({
|
||||
updateProjectEntry: {
|
||||
projectEntry: variables.input.projectEntry,
|
||||
errors: null,
|
||||
__typename: 'UpdateProjectEntryPayload'
|
||||
}
|
||||
}),
|
||||
DeleteProjectEntry: {
|
||||
deleteProjectEntry: {
|
||||
success: true,
|
||||
__typename: 'DeleteProjectEntryPayload'
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should create a new project entry', () => {
|
||||
|
|
@ -22,7 +113,7 @@ describe('Project Entry', () => {
|
|||
cy.get('[data-cy=text-form-input]').type('Stay with Rocket\nMeet Quill');
|
||||
});
|
||||
cy.get('[data-cy=modal-save-button]').click();
|
||||
cy.waitFor('AddProjectEntryMutation');
|
||||
|
||||
cy.get('.project-entry:last-of-type').within(() => {
|
||||
cy.get('.project-entry__paragraph:first-of-type').contains('Join the Guardians')
|
||||
});
|
||||
|
|
@ -39,20 +130,19 @@ describe('Project Entry', () => {
|
|||
cy.get('[data-cy=text-form-input]').clear().type('Defeat Thanos');
|
||||
});
|
||||
cy.get('[data-cy=modal-save-button]').click();
|
||||
cy.waitFor('UpdateProjectEntry');
|
||||
cy.get('.project-entry__paragraph:first-of-type').contains('Defeat Thanos');
|
||||
});
|
||||
|
||||
it('should delete the last entry', () => {
|
||||
cy.visit('/portfolio/groot');
|
||||
|
||||
cy.get('.project-entry').should('have.length', 2);
|
||||
cy.get('.project-entry').should('have.length', 1);
|
||||
|
||||
cy.get('.project-entry:last-of-type').within(() => {
|
||||
cy.get('[data-cy=project-entry-more]').click();
|
||||
cy.get('[data-cy=delete-project-entry]').click();
|
||||
});
|
||||
|
||||
cy.get('.project-entry').should('have.length', 1);
|
||||
cy.get('.project-entry').should('have.length', 0);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
describe('The Room Page', () => {
|
||||
it('displays new room entry with author name', () => {
|
||||
// todo: mock all the graphql queries and mutations
|
||||
|
||||
cy.viewport('macbook-15');
|
||||
cy.visit('/room/ein-historisches-festival');
|
||||
cy.login('rahel.cueni', 'test');
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
describe('The Rooms Page', () => {
|
||||
// todo: mock all the graphql queries and mutations
|
||||
it('goes to the rooms page', () => {
|
||||
cy.visit('/rooms');
|
||||
cy.login('nico.zickgraf', 'test');
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
// todo: reenable with a script that does the mutations, or with a workaround for fetch request checking in cypress
|
||||
describe('Solutions', () => {
|
||||
// todo: mock all the graphql queries and mutations
|
||||
// todo: enable again
|
||||
|
||||
// // it('does not display the solution at first, then displays them after clicking', () => {
|
||||
// // cy.viewport('macbook-15');
|
||||
// // cy.login('nico.zickgraf', 'test');
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
const schema = require('../fixtures/schema.json');
|
||||
const assignments = require('../fixtures/assignments.json');
|
||||
const module = require('../fixtures/module.json');
|
||||
const spellCheck = require('../fixtures/spell-check.json');
|
||||
|
||||
describe('Spellcheck', () => {
|
||||
before(() => {
|
||||
cy.server();
|
||||
cy.mockGraphql({
|
||||
schema: schema,
|
||||
// endpoint: '/api/graphql'
|
||||
operations: {
|
||||
MeQuery: {
|
||||
me: {
|
||||
permissions: []
|
||||
}
|
||||
},
|
||||
AssignmentsQuery: {
|
||||
assignments
|
||||
},
|
||||
ModulesQuery: {
|
||||
module
|
||||
},
|
||||
SpellCheck: {
|
||||
spellCheck
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should highlight three errors', () => {
|
||||
cy.apolloLogin('rahel.cueni', 'test');
|
||||
cy.visit('/module/lohn-und-budget/');
|
||||
|
||||
cy.get('.spellcheck__correction').should('have.length', 0);
|
||||
|
||||
cy.get('.submission-form-container__spellcheck').click();
|
||||
|
||||
cy.get('.spellcheck__correction').should('have.length', 3);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,14 +1,57 @@
|
|||
const schema = require('../fixtures/schema.json');
|
||||
const module = require('../fixtures/module.json');
|
||||
|
||||
describe('Survey', () => {
|
||||
beforeEach(() => {
|
||||
cy.exec("python ../server/manage.py prepare_surveys_for_cypress");
|
||||
cy.server();
|
||||
|
||||
cy.mockGraphql({
|
||||
schema: schema,
|
||||
});
|
||||
|
||||
cy.viewport('macbook-15');
|
||||
cy.startGraphQLCapture();
|
||||
cy.login('rahel.cueni', 'test', true);
|
||||
cy.get('body').contains('Neues Wissen erwerben');
|
||||
|
||||
cy.apolloLogin('rahel.cueni', 'test');
|
||||
});
|
||||
|
||||
it('should display and fill out the survey', () => {
|
||||
|
||||
let answer = null;
|
||||
|
||||
cy.mockGraphqlOps({
|
||||
operations: {
|
||||
MeQuery: {
|
||||
me: {
|
||||
permissions: []
|
||||
}
|
||||
},
|
||||
ModuleQuery: variables => ({module}),
|
||||
SurveyQuery: () => ({
|
||||
survey: {
|
||||
id: 'U3VydmV5Tm9kZTox',
|
||||
title: 'Test',
|
||||
data: '{"pages": [{"name": "Seite 1", "elements": [{"name": "Fall 1", "type": "panel", "title": "Fall 1", "elements": [{"name": "A: Max gibt ihr das Geld und muss das Billardspiel absagen.", "type": "text", "placeHolder": "Passende Tugenden erfassen...", "correctAnswer": "Triss"}, {"name": "question2", "type": "text", "title": "B: Max gibt ihr das Geld nicht und geht Billard spielen.", "placeHolder": "Passende Tugenden erfassen...", "correctAnswer": "Jaskier"}], "description": "Max hat Ende Monat noch Fr. 20.\\u2013 \\u00fcbrig, die er gespart hat, um mit seinem besten Kumpel, der ein halbes Jahr im Ausland verweilte, Billard spielen zu gehen. Doch dann bittet ihn seine j\\u00fcngere Schwester um Geld. Sie hat ein unverhofftes Date mit einem jungen Mann, in den sie sich bereits vor Monaten unsterblich verliebt hat. Leider ist ihr Kontostand aber bereits auf Null."}]}, {"name": "Seite 2", "elements": [{"name": "panel1", "type": "panel", "title": "Fall 2", "elements": [{"name": "question1", "type": "text", "title": "A: Silvio bringt seinen Mitfahrer in Sicherheit.", "placeHolder": "Passende Tugenden erfassen...", "correctAnswer": "Yennefer", "useDisplayValuesInTitle": false}, {"name": "question3", "type": "text", "title": "B: Silvio sperrt die Strasse ab.", "placeHolder": "Passende Tugenden erfassen...", "correctAnswer": "Geralt"}], "description": "Auf der Autobahn brennt ein Lastwagen, der jederzeit explodieren kann. Silvio, dem Fahrer, bleiben nur noch wenige Minuten: Entweder bringt er seinen ohnm\\u00e4chtig gewordenen Mitfahrer in Sicherheit oder er sperrt die Strasse ab, die nach wie vor dicht befahren wird."}]}], "completeText": "Abschliessen", "showQuestionNumbers": "off"}',
|
||||
module: {
|
||||
id: 'TW9kdWxlTm9kZToxNw==',
|
||||
__typename: 'ModuleNode'
|
||||
},
|
||||
answer,
|
||||
__typename: 'SurveyNode'
|
||||
},
|
||||
|
||||
}),
|
||||
UpdateAnswer: variables => {
|
||||
answer = variables.input.answer;
|
||||
return {
|
||||
updateAnswer: {
|
||||
answer,
|
||||
__typename: 'UpdateAnswerPayload'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
cy.visit('/survey/U3VydmV5Tm9kZTox');
|
||||
|
||||
cy.get('.survey__panel-title').should('contain', 'Fall 1')
|
||||
|
|
@ -17,15 +60,12 @@ describe('Survey', () => {
|
|||
cy.get('#sq_101i').type('Demut');
|
||||
|
||||
cy.get('[value="Speichern & Weiter"]').click();
|
||||
//cy.get('.button--primary').click()
|
||||
|
||||
cy.get('#sq_102i').type('Keuschheit');
|
||||
cy.get('#sq_103i').type('Geduld');
|
||||
|
||||
cy.get('[value=Abschliessen]').click();
|
||||
|
||||
cy.waitFor('UpdateAnswer');
|
||||
|
||||
cy.visit('/survey/U3VydmV5Tm9kZTox');
|
||||
|
||||
cy.get('#sq_100i').should('have.value', 'Wohlwollen')
|
||||
|
|
|
|||
|
|
@ -23,9 +23,35 @@
|
|||
//
|
||||
// -- This is will overwrite an existing command --
|
||||
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
|
||||
// installed a fork of the original package, because of this issue:
|
||||
// https://github.com/tgriesser/cypress-graphql-mock/issues/23
|
||||
// todo: once above issue is fixed, go back to the original repo -> npm install cypress-graphql-mock
|
||||
// import 'cypress-graphql-mock';
|
||||
import '@iam4x/cypress-graphql-mock';
|
||||
|
||||
Cypress.Commands.add('apolloLogin', (username, password) => {
|
||||
const payload = {
|
||||
'operationName': 'Login',
|
||||
'variables': {
|
||||
'input': {
|
||||
'usernameInput': username,
|
||||
'passwordInput': password
|
||||
}
|
||||
},
|
||||
'query': 'mutation Login($input: LoginInput!) {\n login(input: $input) {\n success\n errors {\n field\n __typename\n }\n __typename\n }\n}\n'
|
||||
};
|
||||
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: '/api/graphql-public/',
|
||||
body: payload
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
// todo: replace with apollo call
|
||||
Cypress.Commands.add("login", (username, password, visitLogin=false) => {
|
||||
Cypress.Commands.add("login", (username, password, visitLogin = false) => {
|
||||
if (visitLogin) {
|
||||
cy.visit('/login');
|
||||
}
|
||||
|
|
@ -67,7 +93,7 @@ Cypress.Commands.add('startGraphQLCapture', () => {
|
|||
// from https://stackoverflow.com/questions/53814647/how-can-i-alias-specific-graphql-requests-in-cypress
|
||||
Cypress.Commands.add('waitFor', operationName => {
|
||||
cy.wait('@graphQL').then(({request}) => {
|
||||
if(request.body.operationName !== operationName) {
|
||||
if (request.body.operationName !== operationName) {
|
||||
return cy.waitFor(operationName);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ import './commands'
|
|||
// require('./commands')
|
||||
|
||||
// from https://stackoverflow.com/questions/49079005/how-to-stub-a-call-to-graphql-using-cypress#49088084
|
||||
Cypress.on('window:before:load', win => {
|
||||
win.fetch = null;
|
||||
win.Blob = null;
|
||||
});
|
||||
// Cypress.on('window:before:load', win => {
|
||||
// win.fetch = null;
|
||||
// win.Blob = null;
|
||||
// });
|
||||
|
|
|
|||
|
|
@ -2524,6 +2524,15 @@
|
|||
"lodash.once": "^4.1.1"
|
||||
}
|
||||
},
|
||||
"@iam4x/cypress-graphql-mock": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@iam4x/cypress-graphql-mock/-/cypress-graphql-mock-0.0.1.tgz",
|
||||
"integrity": "sha512-pi2nNDwX9o+63qbwK4ogUAk5oX2HunclFcQ1YCsTx4DBoAdudfiKUegyqFXrii+wtyDaXUa88UrkrudMMcnCbA==",
|
||||
"requires": {
|
||||
"graphql-tools": "^4.0.3",
|
||||
"tslib": "^1.9.3"
|
||||
}
|
||||
},
|
||||
"@jest/console": {
|
||||
"version": "24.7.1",
|
||||
"resolved": "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz",
|
||||
|
|
@ -7463,6 +7472,11 @@
|
|||
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
|
||||
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
|
||||
},
|
||||
"deprecated-decorator": {
|
||||
"version": "0.1.6",
|
||||
"resolved": "https://registry.npmjs.org/deprecated-decorator/-/deprecated-decorator-0.1.6.tgz",
|
||||
"integrity": "sha1-AJZjF7ehL+kvPMgx91g68ym4bDc="
|
||||
},
|
||||
"des.js": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz",
|
||||
|
|
@ -9742,6 +9756,60 @@
|
|||
"resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.10.1.tgz",
|
||||
"integrity": "sha512-jApXqWBzNXQ8jYa/HLkZJaVw9jgwNqZkywa2zfFn16Iv1Zb7ELNHkJaXHR7Quvd5SIGsy6Ny7SUKATgnu05uEg=="
|
||||
},
|
||||
"graphql-tools": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/graphql-tools/-/graphql-tools-4.0.6.tgz",
|
||||
"integrity": "sha512-jHLQw8x3xmSNRBCsaZqelXXsFfUSUSktSCUP8KYHiX1Z9qEuwcMpAf+FkdBzk8aTAFqOlPdNZ3OI4DKKqGKUqg==",
|
||||
"requires": {
|
||||
"apollo-link": "^1.2.3",
|
||||
"apollo-utilities": "^1.0.1",
|
||||
"deprecated-decorator": "^0.1.6",
|
||||
"iterall": "^1.1.3",
|
||||
"uuid": "^3.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"apollo-link": {
|
||||
"version": "1.2.13",
|
||||
"resolved": "https://registry.npmjs.org/apollo-link/-/apollo-link-1.2.13.tgz",
|
||||
"integrity": "sha512-+iBMcYeevMm1JpYgwDEIDt/y0BB7VWyvlm/7x+TIPNLHCTCMgcEgDuW5kH86iQZWo0I7mNwQiTOz+/3ShPFmBw==",
|
||||
"requires": {
|
||||
"apollo-utilities": "^1.3.0",
|
||||
"ts-invariant": "^0.4.0",
|
||||
"tslib": "^1.9.3",
|
||||
"zen-observable-ts": "^0.8.20"
|
||||
},
|
||||
"dependencies": {
|
||||
"apollo-utilities": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/apollo-utilities/-/apollo-utilities-1.3.3.tgz",
|
||||
"integrity": "sha512-F14aX2R/fKNYMvhuP2t9GD9fggID7zp5I96MF5QeKYWDWTrkRdHRp4+SVfXUVN+cXOaB/IebfvRtzPf25CM0zw==",
|
||||
"requires": {
|
||||
"@wry/equality": "^0.1.2",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
"ts-invariant": "^0.4.0",
|
||||
"tslib": "^1.10.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"tslib": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz",
|
||||
"integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"zen-observable-ts": {
|
||||
"version": "0.8.20",
|
||||
"resolved": "https://registry.npmjs.org/zen-observable-ts/-/zen-observable-ts-0.8.20.tgz",
|
||||
"integrity": "sha512-2rkjiPALhOtRaDX6pWyNqK1fnP5KkJJybYebopNSn6wDG1lxBoFs2+nwwXKoA6glHIrtwrfBBy6da0stkKtTAA==",
|
||||
"requires": {
|
||||
"tslib": "^1.9.3",
|
||||
"zen-observable": "^0.8.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"growl": {
|
||||
"version": "1.9.2",
|
||||
"resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz",
|
||||
|
|
@ -11500,7 +11568,6 @@
|
|||
"version": "1.1.11",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
"@babel/preset-env": "^7.5.4",
|
||||
"@babel/preset-stage-2": "^7.0.0",
|
||||
"@babel/runtime": "^7.5.4",
|
||||
"@iam4x/cypress-graphql-mock": "0.0.1",
|
||||
"apollo-cache-inmemory": "^1.6.5",
|
||||
"apollo-client": "^2.6.8",
|
||||
"apollo-link": "^1.2.13",
|
||||
|
|
|
|||
|
|
@ -13,20 +13,24 @@
|
|||
@saveInput="saveInput"
|
||||
@reopen="reopen"
|
||||
@changeDocumentUrl="changeDocumentUrl"
|
||||
@spellcheck="spellcheck"
|
||||
:user-input="submission"
|
||||
placeholder="Ergebnis erfassen"
|
||||
action="Ergebnis mit Lehrperson teilen"
|
||||
shared-msg="Das Ergebnis wurde mit der Lehrperson geteilt."
|
||||
:saved="!unsaved"
|
||||
>
|
||||
:spellcheck="true"
|
||||
>
|
||||
</submission-form>
|
||||
|
||||
<div v-if="this.assignment.submission.submissionFeedback" class="assignment__feedback">
|
||||
<p>{{feedbackText}}</p>
|
||||
</div>
|
||||
<spell-check :corrections="corrections" :text="submission.text"></spell-check>
|
||||
|
||||
<p v-if="this.assignment.submission.submissionFeedback" class="assignment__feedback" v-html="feedbackText">
|
||||
</p>
|
||||
</template>
|
||||
<template v-if="!isStudent">
|
||||
<router-link class="button button--primary" :to="{name: 'submissions', params: { id: assignment.id }}">Zu den Ergebnissen
|
||||
<router-link class="button button--primary" :to="{name: 'submissions', params: { id: assignment.id }}">Zu den
|
||||
Ergebnissen
|
||||
</router-link>
|
||||
</template>
|
||||
</div>
|
||||
|
|
@ -38,6 +42,7 @@
|
|||
import ME_QUERY from '@/graphql/gql/meQuery.gql';
|
||||
import UPDATE_ASSIGNMENT_MUTATION from '@/graphql/gql/mutations/updateAssignmentMutation.gql';
|
||||
import UPDATE_ASSIGNMENT_MUTATION_WITH_SUCCESS from '@/graphql/gql/mutations/updateAssignmentMutationWithSuccess.gql';
|
||||
import SPELL_CHECK_MUTATION from '@/graphql/gql/mutations/spellCheck.gql';
|
||||
import debounce from 'lodash/debounce';
|
||||
import cloneDeep from 'lodash/cloneDeep'
|
||||
|
||||
|
|
@ -48,6 +53,7 @@
|
|||
import DocumentBlock from '@/components/content-blocks/DocumentBlock';
|
||||
import Solution from '@/components/content-blocks/Solution';
|
||||
import SimpleFileUpload from '@/components/SimpleFileUpload';
|
||||
import SpellCheck from '@/components/content-blocks/assignment/SpellCheck';
|
||||
|
||||
export default {
|
||||
props: ['value'],
|
||||
|
|
@ -59,7 +65,8 @@
|
|||
FinalSubmission,
|
||||
Solution,
|
||||
SimpleFileUpload,
|
||||
SubmissionForm
|
||||
SubmissionForm,
|
||||
SpellCheck
|
||||
},
|
||||
|
||||
computed: {
|
||||
|
|
@ -83,7 +90,7 @@
|
|||
},
|
||||
feedbackText() {
|
||||
let feedback = this.assignment.submission.submissionFeedback;
|
||||
return `Feedback von ${feedback.teacher.firstName} ${feedback.teacher.lastName}: ${feedback.text}`;
|
||||
return `<span class="inline-title">Feedback von ${feedback.teacher.firstName} ${feedback.teacher.lastName}:</span> ${feedback.text}`;
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -129,6 +136,8 @@
|
|||
});
|
||||
}, 500),
|
||||
saveInput: function (answer) {
|
||||
// reset corrections on input
|
||||
this.corrections = '';
|
||||
this.unsaved = true;
|
||||
/*
|
||||
We update the assignment on this component, so the changes are reflected on it. The server does not return
|
||||
|
|
@ -142,6 +151,8 @@
|
|||
this._save(this.assignment.submission);
|
||||
},
|
||||
turnIn() {
|
||||
// reset corrections on turn in
|
||||
this.corrections = '';
|
||||
this.$apollo.mutate({
|
||||
mutation: UPDATE_ASSIGNMENT_MUTATION,
|
||||
variables: {
|
||||
|
|
@ -178,6 +189,21 @@
|
|||
final: false,
|
||||
}
|
||||
},
|
||||
spellcheck() {
|
||||
let self = this;
|
||||
this.$apollo.mutate({
|
||||
mutation: SPELL_CHECK_MUTATION,
|
||||
variables: {
|
||||
input: {
|
||||
assignment: this.assignment.id,
|
||||
text: this.assignment.submission.text
|
||||
}
|
||||
},
|
||||
update(store, {data: {spellCheck: {results}}}) {
|
||||
self.corrections = results;
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
apollo: {
|
||||
|
|
@ -212,7 +238,8 @@
|
|||
},
|
||||
inputType: 'text',
|
||||
unsaved: false,
|
||||
saving: 0
|
||||
saving: 0,
|
||||
corrections: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -256,8 +283,9 @@
|
|||
}
|
||||
|
||||
&__feedback {
|
||||
margin-top: $medium-spacing;
|
||||
@include regular-text;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,59 @@
|
|||
<template>
|
||||
<p class="spellcheck" v-if="corrections">
|
||||
<span class="inline-title">Rechtschreibung:</span> <span v-html="highlightedText"></span>
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: ['corrections', 'text'],
|
||||
|
||||
computed: {
|
||||
highlightedText() {
|
||||
if (!this.corrections) {
|
||||
return ''
|
||||
}
|
||||
let parts = [];
|
||||
let index = 0;
|
||||
[...this.corrections] // no side effects, as sort changes the source array
|
||||
.sort((e1, e2) => (e1.offset + e1.sentenceOffset) - (e2.offset + e2.sentenceOffset))
|
||||
.forEach(current => {
|
||||
let realOffset = current.offset + current.sentenceOffset;
|
||||
parts.push({
|
||||
correct: true,
|
||||
text: this.text.substring(index, realOffset)
|
||||
}, {
|
||||
correct: false,
|
||||
text: this.text.substring(realOffset, realOffset + current.length)
|
||||
});
|
||||
index = realOffset + current.length
|
||||
});
|
||||
parts.push({
|
||||
correct: true,
|
||||
text: this.text.substring(index, this.text.length + 1)
|
||||
});
|
||||
return parts
|
||||
.filter(part => part.text.length)
|
||||
.reduce((previous, part) => {
|
||||
if (part.correct) {
|
||||
return `${previous}${part.text}`;
|
||||
} else {
|
||||
return `${previous}<span class="spellcheck__correction">${part.text}</span>`;
|
||||
}
|
||||
}, '');
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "@/styles/_mixins.scss";
|
||||
|
||||
.spellcheck {
|
||||
@include regular-text;
|
||||
|
||||
&__correction {
|
||||
background: yellow;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,44 +1,50 @@
|
|||
<template>
|
||||
<div class="feedback__submission submission-form-container">
|
||||
<div class="submission-form-container__inputs">
|
||||
<submission-input
|
||||
@input="saveInput"
|
||||
:input-text="userInput.text"
|
||||
:saved="saved"
|
||||
:final="final"
|
||||
:placeholder="placeholder"
|
||||
:reopen="reopenSubmission"
|
||||
></submission-input>
|
||||
</div>
|
||||
|
||||
<div class="submission-form-container__actions" v-if="!final">
|
||||
<button class="submission-form-container__submit button button--primary button--white-bg"
|
||||
@click="$emit('turnIn')"
|
||||
>{{action}}
|
||||
</button>
|
||||
<div v-if="userInput.document">
|
||||
<document-block
|
||||
:value="{url: userInput.document}"
|
||||
show-trash-icon
|
||||
v-on:trash="changeDocumentUrl('')"
|
||||
></document-block>
|
||||
</div>
|
||||
|
||||
<simple-file-upload
|
||||
v-if="allowsDocuments"
|
||||
v-on:link-change-url="changeDocumentUrl"
|
||||
:value="userInput.document"
|
||||
class="submission-form-container__document"
|
||||
></simple-file-upload>
|
||||
<slot></slot>
|
||||
</div>
|
||||
|
||||
<final-submission
|
||||
v-if="final"
|
||||
:user-input="userInput"
|
||||
:shared-msg="sharedMsg"
|
||||
@reopen="$emit('reopen')"></final-submission>
|
||||
<div class="feedback__submission submission-form-container">
|
||||
<div class="submission-form-container__inputs">
|
||||
<submission-input
|
||||
@input="saveInput"
|
||||
:input-text="userInput.text"
|
||||
:saved="saved"
|
||||
:final="final"
|
||||
:placeholder="placeholder"
|
||||
:reopen="reopenSubmission"
|
||||
></submission-input>
|
||||
</div>
|
||||
|
||||
<div class="submission-form-container__actions" v-if="!final">
|
||||
<button class="submission-form-container__submit button button--primary button--white-bg"
|
||||
@click="$emit('turnIn')"
|
||||
>{{action}}
|
||||
</button>
|
||||
<button
|
||||
class="submission-form-container__submit submission-form-container__spellcheck button button--primary button--white-bg"
|
||||
v-if="spellcheck"
|
||||
@click="$emit('spellcheck')"
|
||||
>Rechtschreibung prüfen
|
||||
</button>
|
||||
<div v-if="userInput.document">
|
||||
<document-block
|
||||
:value="{url: userInput.document}"
|
||||
show-trash-icon
|
||||
v-on:trash="changeDocumentUrl('')"
|
||||
></document-block>
|
||||
</div>
|
||||
|
||||
<simple-file-upload
|
||||
v-if="allowsDocuments"
|
||||
v-on:link-change-url="changeDocumentUrl"
|
||||
:value="userInput.document"
|
||||
class="submission-form-container__document"
|
||||
></simple-file-upload>
|
||||
<slot></slot>
|
||||
</div>
|
||||
|
||||
<final-submission
|
||||
v-if="final"
|
||||
:user-input="userInput"
|
||||
:shared-msg="sharedMsg"
|
||||
@reopen="$emit('reopen')"></final-submission>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
|
@ -48,13 +54,6 @@
|
|||
import DocumentBlock from '@/components/content-blocks/DocumentBlock';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SubmissionInput,
|
||||
FinalSubmission,
|
||||
SimpleFileUpload,
|
||||
DocumentBlock
|
||||
},
|
||||
|
||||
props: {
|
||||
userInput: Object,
|
||||
saved: Boolean,
|
||||
|
|
@ -62,9 +61,20 @@
|
|||
action: String,
|
||||
reopen: Function,
|
||||
document: String,
|
||||
spellcheck: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
sharedMsg: String
|
||||
},
|
||||
|
||||
components: {
|
||||
SubmissionInput,
|
||||
FinalSubmission,
|
||||
SimpleFileUpload,
|
||||
DocumentBlock
|
||||
},
|
||||
|
||||
computed: {
|
||||
final() {
|
||||
return !!this.userInput && this.userInput.final
|
||||
|
|
@ -90,34 +100,35 @@
|
|||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import '@/styles/_mixins.scss';
|
||||
@import '@/styles/_mixins.scss';
|
||||
|
||||
.submission-form-container {
|
||||
.submission-form-container {
|
||||
|
||||
@include input-box-shadow;
|
||||
background-color: $color-white;
|
||||
border-radius: $input-border-radius;
|
||||
border: 1px solid $color-silver;
|
||||
padding: $medium-spacing;
|
||||
@include input-box-shadow;
|
||||
background-color: $color-white;
|
||||
border-radius: $input-border-radius;
|
||||
border: 1px solid $color-silver;
|
||||
padding: $medium-spacing;
|
||||
margin-bottom: $medium-spacing;
|
||||
|
||||
&__inputs {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
&__inputs {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
&__submit {
|
||||
margin-right: $medium-spacing;
|
||||
}
|
||||
&__submit {
|
||||
margin-right: $medium-spacing;
|
||||
}
|
||||
|
||||
&__actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
&__actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&__document {
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
&__document {
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -78,8 +78,6 @@ export default function (uri) {
|
|||
assignment: (_, args, {getCacheKey}) => getCacheKey({__typename: 'AssignmentNode', id: args.id}),
|
||||
objective: (_, args, {getCacheKey}) => getCacheKey({__typename: 'ObjectiveNode', id: args.id}),
|
||||
objectiveGroup: (_, args, {getCacheKey}) => getCacheKey({__typename: 'ObjectiveGroupNode', id: args.id}),
|
||||
// todo: remove, the new client seems to cache this correctly by itself
|
||||
// module: (_, args, {getCacheKey}) => getCacheKey({__typename: 'ModuleNode', id: args.slug}),
|
||||
projectEntry: (_, args, {getCacheKey}) => getCacheKey({__typename: 'ProjectEntryNode', id: args.id}),
|
||||
}
|
||||
}
|
||||
|
|
@ -93,6 +91,7 @@ export default function (uri) {
|
|||
try {
|
||||
return cache.originalReadQuery(...args);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#import "../fragments/projectParts.gql"
|
||||
mutation AddProjectMutation($input: AddProjectInput!){
|
||||
mutation AddProject($input: AddProjectInput!){
|
||||
addProject(input: $input){
|
||||
project {
|
||||
...ProjectParts
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#import "../fragments/projectEntryParts.gql"
|
||||
mutation AddProjectEntryMutation($input: AddProjectEntryInput!) {
|
||||
mutation AddProjectEntry($input: AddProjectEntryInput!) {
|
||||
addProjectEntry(input: $input) {
|
||||
projectEntry {
|
||||
...ProjectEntryParts
|
||||
|
|
|
|||
|
|
@ -0,0 +1,14 @@
|
|||
mutation SpellCheck($input: SpellCheckInput!) {
|
||||
spellCheck(input: $input) {
|
||||
correct
|
||||
results {
|
||||
sentence
|
||||
offset
|
||||
sentenceOffset
|
||||
length
|
||||
affected
|
||||
corrected
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -125,6 +125,11 @@
|
|||
line-height: $default-heading-line-height;
|
||||
}
|
||||
|
||||
@mixin inline-title {
|
||||
@include regular-text;
|
||||
color: $color-silver-dark;
|
||||
}
|
||||
|
||||
@mixin lead-paragraph {
|
||||
font-family: $serif-font-family;
|
||||
line-height: 1.4;
|
||||
|
|
|
|||
|
|
@ -71,3 +71,7 @@ input, textarea, select, button {
|
|||
margin-bottom: 7.5px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.inline-title {
|
||||
@include inline-title;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,9 +9,9 @@
|
|||
"resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz",
|
||||
"integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=",
|
||||
"requires": {
|
||||
"babel-runtime": "6.26.0",
|
||||
"core-js": "2.5.7",
|
||||
"regenerator-runtime": "0.10.5"
|
||||
"babel-runtime": "^6.26.0",
|
||||
"core-js": "^2.5.0",
|
||||
"regenerator-runtime": "^0.10.5"
|
||||
}
|
||||
},
|
||||
"babel-runtime": {
|
||||
|
|
@ -19,8 +19,8 @@
|
|||
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
|
||||
"integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
|
||||
"requires": {
|
||||
"core-js": "2.5.7",
|
||||
"regenerator-runtime": "0.11.1"
|
||||
"core-js": "^2.4.0",
|
||||
"regenerator-runtime": "^0.11.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"regenerator-runtime": {
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ from objectives.mutations import ObjectiveMutations
|
|||
from objectives.schema import ObjectivesQuery
|
||||
from portfolio.mutations import PortfolioMutations
|
||||
from portfolio.schema import PortfolioQuery
|
||||
from spellcheck.mutations import SpellCheckMutations
|
||||
from surveys.schema import SurveysQuery
|
||||
from surveys.mutations import SurveyMutations
|
||||
from rooms.mutations import RoomMutations
|
||||
|
|
@ -26,19 +27,18 @@ from registration.mutations_public import RegistrationMutations
|
|||
|
||||
|
||||
class Query(UsersQuery, AllUsersQuery, ModuleRoomsQuery, RoomsQuery, ObjectivesQuery, BookQuery, AssignmentsQuery,
|
||||
StudentSubmissionQuery, BasicKnowledgeQuery, PortfolioQuery, SurveysQuery,
|
||||
graphene.ObjectType):
|
||||
StudentSubmissionQuery, BasicKnowledgeQuery, PortfolioQuery, SurveysQuery, graphene.ObjectType):
|
||||
node = relay.Node.Field()
|
||||
|
||||
if settings.DEBUG:
|
||||
debug = graphene.Field(DjangoDebug, name='__debug')
|
||||
debug = graphene.Field(DjangoDebug, name='_debug')
|
||||
|
||||
|
||||
class Mutation(BookMutations, RoomMutations, AssignmentMutations, ObjectiveMutations, CoreMutations, PortfolioMutations,
|
||||
ProfileMutations, SurveyMutations, NoteMutations, RegistrationMutations, graphene.ObjectType):
|
||||
|
||||
ProfileMutations, SurveyMutations, NoteMutations, RegistrationMutations, SpellCheckMutations,
|
||||
graphene.ObjectType):
|
||||
if settings.DEBUG:
|
||||
debug = graphene.Field(DjangoDebug, name='__debug')
|
||||
debug = graphene.Field(DjangoDebug, name='_debug')
|
||||
|
||||
|
||||
schema = graphene.Schema(query=Query, mutation=Mutation)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 2.0.6 on 2019-12-11 10:30
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('assignments', '0010_auto_20191210_1427'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='assignment',
|
||||
name='taskbase_id',
|
||||
field=models.CharField(blank=True, max_length=255, null=True),
|
||||
),
|
||||
]
|
||||
|
|
@ -15,6 +15,7 @@ class Assignment(TimeStampedModel):
|
|||
on_delete=models.PROTECT) # probably don't want to delete all assignments if a user gets deleted
|
||||
module = models.ForeignKey('books.Module', related_name='assignments', on_delete=models.CASCADE)
|
||||
user_created = models.BooleanField(default=False)
|
||||
taskbase_id = models.CharField(max_length=255, null=True, blank=True)
|
||||
|
||||
panels = [
|
||||
FieldPanel('title'),
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import factory
|
|||
import wagtail_factories
|
||||
from django.contrib.auth import get_user_model
|
||||
from factory import CREATE_STRATEGY
|
||||
from wagtail.core import blocks
|
||||
from wagtail.core.models import Page
|
||||
from wagtail.core.rich_text import RichText
|
||||
|
||||
|
|
@ -96,6 +97,17 @@ class AssignmentBlockFactory(wagtail_factories.StructBlockFactory):
|
|||
class Meta:
|
||||
model = AssignmentBlock
|
||||
|
||||
@classmethod
|
||||
def _build(cls, model_class, *args, **kwargs):
|
||||
block = model_class()
|
||||
return blocks.StructValue(
|
||||
block,
|
||||
# todo: build in a more generic fashion
|
||||
[
|
||||
(name, kwargs['assignment']) for name, child_block in block.child_blocks.items()
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
class VideoBlockFactory(wagtail_factories.StructBlockFactory):
|
||||
url = factory.LazyAttribute(lambda x: 'https://www.youtube.com/watch?v=lO9d-AJai8Q')
|
||||
|
|
@ -139,7 +151,7 @@ class ContentBlockFactory(BasePageFactory):
|
|||
owner=user,
|
||||
module=module
|
||||
)
|
||||
kwargs['{}__{}__{}__{}'.format(stream_field_name, idx, block_type, 'assignment_id')] = assignment.id
|
||||
kwargs['{}__{}__{}__{}'.format(stream_field_name, idx, block_type, 'assignment')] = assignment
|
||||
|
||||
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ class UpdateSolutionVisibility(relay.ClientIDMutation):
|
|||
|
||||
class UpdateLastModule(relay.ClientIDMutation):
|
||||
class Input:
|
||||
# todo: use slug here too
|
||||
id = graphene.ID()
|
||||
|
||||
module = graphene.Field(ModuleNode)
|
||||
|
|
|
|||
|
|
@ -49,6 +49,19 @@ module_1_chapter_1 = {
|
|||
'title': '1.1 Lehrbeginn',
|
||||
'description': 'Wie sieht Ihr Konsumverhalten aus?',
|
||||
'content_blocks': [
|
||||
{
|
||||
'type': 'normal',
|
||||
'title': 'Assignment',
|
||||
'contents': [
|
||||
{
|
||||
'type': 'assignment',
|
||||
'value': {
|
||||
'assignment': 'Ein Auftrag',
|
||||
'title': 'Ein Auftragstitel'
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
'type': 'task',
|
||||
'title': 'Auftrag 1',
|
||||
|
|
|
|||
|
|
@ -252,7 +252,8 @@ AWS_STORAGE_BUCKET_NAME = os.environ.get('AWS_STORAGE_BUCKET_NAME')
|
|||
AWS_S3_FILE_OVERWRITE = False
|
||||
|
||||
# use with cloudfront
|
||||
AWS_S3_CUSTOM_DOMAIN = '{}.s3-{}.amazonaws.com'.format(AWS_STORAGE_BUCKET_NAME, os.environ.get('AWS_REGION', 'eu-west-1'))
|
||||
AWS_S3_CUSTOM_DOMAIN = '{}.s3-{}.amazonaws.com'.format(AWS_STORAGE_BUCKET_NAME,
|
||||
os.environ.get('AWS_REGION', 'eu-west-1'))
|
||||
if USE_AWS:
|
||||
DEFAULT_FILE_STORAGE = "storages.backends.s3boto3.S3Boto3Storage"
|
||||
# use with cloudfront
|
||||
|
|
@ -316,7 +317,6 @@ if not DEBUG and os.environ.get('SENTRY_DSN'):
|
|||
integrations=[DjangoIntegration()]
|
||||
)
|
||||
|
||||
|
||||
# LOGGING['handlers'] = {
|
||||
# 'sentry': {
|
||||
# 'level': 'ERROR', # ERROR, WARNING, INFO
|
||||
|
|
@ -360,3 +360,9 @@ EMAIL_BACKEND = 'sendgrid_backend.SendgridBackend'
|
|||
SENDGRID_API_KEY = os.environ.get("SENDGRID_API_KEY")
|
||||
SENDGRID_SANDBOX_MODE_IN_DEBUG = False
|
||||
DEFAULT_FROM_EMAIL = 'myskillbox <noreply@myskillbox.ch>'
|
||||
|
||||
TASKBASE_USER = os.environ.get("TASKBASE_USER")
|
||||
TASKBASE_PASSWORD = os.environ.get("TASKBASE_PASSWORD")
|
||||
TASKBASE_SUPERUSER = os.environ.get("TASKBASE_SUPERUSER")
|
||||
TASKBASE_SUPERPASSWORD = os.environ.get("TASKBASE_SUPERPASSWORD")
|
||||
TASKBASE_BASEURL = os.environ.get("TASKBASE_BASEURL")
|
||||
|
|
|
|||
|
|
@ -86,7 +86,6 @@ class RoomsQuery(object):
|
|||
|
||||
|
||||
class ModuleRoomsQuery(object):
|
||||
|
||||
module_room = graphene.Field(RoomNode, slug=graphene.String(), class_id=graphene.ID())
|
||||
|
||||
def resolve_module_room(self, info, **kwargs):
|
||||
|
|
|
|||
|
|
@ -0,0 +1,87 @@
|
|||
import json
|
||||
import re
|
||||
import requests
|
||||
|
||||
|
||||
# from spellcheck.client import TaskbaseClient
|
||||
# client = TaskbaseClient('info@iterativ.ch', 'myverysafepassword1234', 'https://dev-iterativ.taskbase.com')
|
||||
# client.spellcheck('aOciP9H7tNu7pLsR4ohllk', 'Dies ist ein Sats mit filen Felern')
|
||||
|
||||
class TaskbaseException(Exception):
|
||||
pass
|
||||
|
||||
class TaskbaseClient:
|
||||
# def __init__(self, resource_url):
|
||||
# # resource url should be in the form https://username:password@baseurl
|
||||
# pattern = re.compile(r'(\w+)://(\w+):(\w+)@([a-zA-Z0-9.]+)')
|
||||
# scheme, username, password, url = pattern.match(resource_url).groups()
|
||||
# self.username = username
|
||||
# self.password = password
|
||||
# self.token = None
|
||||
# self.base_url = '{}://{}'.format(scheme, url)
|
||||
def __init__(self, username, password, base_url):
|
||||
self.username = username
|
||||
self.password = password
|
||||
self.base_url = base_url
|
||||
|
||||
self.token = None
|
||||
|
||||
def login(self):
|
||||
payload = {
|
||||
'username': self.username,
|
||||
'password': self.password
|
||||
}
|
||||
response = requests.post('{}/api/login'.format(self.base_url), json=payload)
|
||||
data = response.json()
|
||||
self.token = data['accessToken']
|
||||
|
||||
def register_assignment(self, assignment):
|
||||
if self.token is None:
|
||||
self.login()
|
||||
|
||||
headers = {'Authorization': 'Bearer {}'.format(self.token), 'Content-Type': 'application/json'}
|
||||
payload = {'type': 'SPELL_CHECK'}
|
||||
# we first need to register the assignment via API, so we get an ID
|
||||
response = requests.post('{}/api/task'.format(self.base_url), json=payload, headers=headers)
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
assignment.taskbase_id = data['id']
|
||||
assignment.save()
|
||||
|
||||
payload = {
|
||||
"id": assignment.taskbase_id,
|
||||
"type": "SPELL_CHECK",
|
||||
"documentType": "SPELL_CHECK",
|
||||
"title": assignment.title,
|
||||
"description": assignment.assignment,
|
||||
"solutionSteps": [assignment.solution] if assignment.solution is not None else []
|
||||
}
|
||||
|
||||
# we can then update the task via API with the description, title and sample solution
|
||||
response = requests.post('{}/api/task/{}'.format(self.base_url, assignment.taskbase_id), json=payload,
|
||||
headers=headers)
|
||||
|
||||
if response.status_code != 200:
|
||||
raise TaskbaseException('Something went wrong')
|
||||
else: # todo: define what to do here
|
||||
raise TaskbaseException('Something went wrong')
|
||||
|
||||
def spellcheck(self, task, text):
|
||||
if self.token is None:
|
||||
self.login()
|
||||
|
||||
payload = {
|
||||
"taskId": task,
|
||||
"input": {
|
||||
"text": text,
|
||||
"type": "SPELL_CHECK"
|
||||
}
|
||||
}
|
||||
|
||||
headers = {'Authorization': 'Bearer {}'.format(self.token), 'Content-Type': 'application/json'}
|
||||
|
||||
response = requests.post('{}/api/grade'.format(self.base_url), json=payload, headers=headers)
|
||||
if response.status_code == 200:
|
||||
return response.content
|
||||
else: # todo: define what to do here
|
||||
raise Exception('Something went wrong')
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
import json
|
||||
|
||||
import graphene
|
||||
from django.conf import settings
|
||||
from graphene import relay
|
||||
|
||||
# class SpellCheckPartNode(graphene.ObjectType):
|
||||
# sentence = graphene.String()
|
||||
# offset = graphene.Int()
|
||||
# length = graphene.Int()
|
||||
# affected = graphene.String()
|
||||
# corrected = graphene.String()
|
||||
from api.utils import get_object
|
||||
from assignments.models import Assignment
|
||||
from spellcheck.client import TaskbaseClient
|
||||
|
||||
|
||||
def sentence_offset_to_snake_case(result):
|
||||
result['sentence_offset'] = result['sentenceOffset']
|
||||
return result
|
||||
|
||||
|
||||
class SpellCheckStepNode(graphene.ObjectType):
|
||||
# id = graphene.String()
|
||||
# part = graphene.Field(SpellCheckPartNode)
|
||||
sentence = graphene.String()
|
||||
offset = graphene.Int()
|
||||
sentence_offset = graphene.Int()
|
||||
length = graphene.Int()
|
||||
affected = graphene.String()
|
||||
corrected = graphene.String()
|
||||
|
||||
|
||||
class SpellCheck(relay.ClientIDMutation):
|
||||
class Input:
|
||||
text = graphene.String(required=True)
|
||||
assignment = graphene.ID(required=True)
|
||||
|
||||
results = graphene.List(SpellCheckStepNode)
|
||||
correct = graphene.Boolean()
|
||||
|
||||
@classmethod
|
||||
def mutate_and_get_payload(cls, root, info, **kwargs):
|
||||
user = info.context.user
|
||||
text = kwargs.get('text')
|
||||
assignment_id = kwargs.get('assignment')
|
||||
|
||||
assignment = get_object(Assignment, assignment_id)
|
||||
|
||||
client = TaskbaseClient(settings.TASKBASE_USER, settings.TASKBASE_PASSWORD, settings.TASKBASE_BASEURL)
|
||||
|
||||
if assignment.taskbase_id is None or assignment.taskbase_id == '':
|
||||
# we need to use another user (with more privileges) here, because why not
|
||||
superclient = TaskbaseClient(settings.TASKBASE_SUPERUSER, settings.TASKBASE_SUPERPASSWORD,
|
||||
settings.TASKBASE_BASEURL)
|
||||
superclient.register_assignment(assignment)
|
||||
|
||||
data = json.loads(client.spellcheck(assignment.taskbase_id, text))
|
||||
|
||||
# the property is called sentenceOffset, but graphene expects the property to be called sentence_offset.
|
||||
# we convert it manually here. fixme: is there a better way to declare this in the SpellCheckStepNode?
|
||||
transformed_results = list(map(lambda x: x['part'], data['steps']))
|
||||
return cls(correct=data['correct'] == 'CORRECT', results=[
|
||||
sentence_offset_to_snake_case(result) for result in transformed_results
|
||||
])
|
||||
|
||||
|
||||
class SpellCheckMutations:
|
||||
spell_check = SpellCheck.Field()
|
||||
Loading…
Reference in New Issue