diff --git a/Pipfile b/Pipfile index 005b119e..70701acd 100644 --- a/Pipfile +++ b/Pipfile @@ -10,6 +10,7 @@ python_version = '3.6' awscli = "*" ipdb = "*" coverage = "*" +django-silk = "*" [packages] factory-boy = "==2.11.0" diff --git a/Pipfile.lock b/Pipfile.lock index b5251119..d9958437 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "e7807798e8b5c39d7c1bc57d61520f2c888da08d2b6061f07758e00b490fdbd6" + "sha256": "ca4f635dc983134e4569df2af8f0d73f488211bc2a97d11c194f76279f942977" }, "pipfile-spec": 6, "requires": { @@ -48,18 +48,18 @@ }, "boto3": { "hashes": [ - "sha256:27e221d3868f35687807e5c920f7e8d4872f722f64196a7fd274a06ad65beec0", - "sha256:8ff4e3d9e5d6a26dd7494afc68dc96afe6b7bda88130cca84cd58702d888ed27" + "sha256:629ce3be236b6e0aed52358146eea9ffa7679d6cd1cc9b3e12332226270d6499", + "sha256:b1351e62136fae29be8fcbb1c4890f1d72017d57e33051d435a8bf9f71212fde" ], "index": "pypi", - "version": "==1.11.10" + "version": "==1.11.14" }, "botocore": { "hashes": [ - "sha256:cf3144994191847e30ef76781af867009bdc233b3f1f4736615e5330687a891e", - "sha256:f11ff8616f46ca04697df031e622c9ed50931b9d649d4e719f961e9d80771e8d" + "sha256:34ad4d73e6bef5c8ad956c66354611628cdebd431fe2927261ed9c068b9cfb7a", + "sha256:6570f2ba046956d5b548ab2346d32f713ecf8b8cb098a839d73fcf832ccfa223" ], - "version": "==1.14.10" + "version": "==1.14.14" }, "certifi": { "hashes": [ @@ -535,10 +535,10 @@ }, "s3transfer": { "hashes": [ - "sha256:2525bae2a530195576da53671bae8ca8c55ee8e33bc2225a65e804476611ea5a", - "sha256:4924e10451cc37901945806423d16c2c2040a6530645a614ed87e995ccec764c" + "sha256:2482b4259524933a022d59da830f51bd746db62f047d6eb213f2f8855dcb8a13", + "sha256:921a37e2aefc64145e7b73d50c71bb4f26f46e4c9f414dc648c6245ff92cf7db" ], - "version": "==0.3.2" + "version": "==0.3.3" }, "sendgrid": { "hashes": [ @@ -603,6 +603,7 @@ "sha256:2f3db8b19923a873b3e5256dc9c2dedfa883e33d87c690d9c7913e1f40673cdc", "sha256:87716c2d2a7121198ebcb7ce7cccf6ce5e9ba539041cfbaeecfb641dc0bf6acc" ], + "markers": "python_version != '3.4'", "version": "==1.25.8" }, "wagtail": { @@ -652,21 +653,26 @@ } }, "develop": { + "asgiref": { + "hashes": [ + "sha256:7e06d934a7718bf3975acbf87780ba678957b87c7adc056f13b6215d610695a0", + "sha256:ea448f92fc35a0ef4b1508f53a04c4670255a3f33d22a81c8fc9c872036adbe5" + ], + "version": "==3.2.3" + }, + "autopep8": { + "hashes": [ + "sha256:0f592a0447acea0c2b0a9602be1e4e3d86db52badd2e3c84f0193bfd89fd3a43" + ], + "version": "==1.5" + }, "awscli": { "hashes": [ -<<<<<<< HEAD - "sha256:4c49f085fb827ca1aeba5e6e5e39f6005110a0059b5c772aeb1d51c4f33c4028", - "sha256:9459ac705c2a5d8724057492800c52084df714b624853eb3331087ecf8726a22" + "sha256:2748af4e77728ced50d7d5bda0fa980449bd71eedff90ee643bee86ed4283d2f", + "sha256:9118015f4bbab1c671d9c9927d07b6f7eadb7e1e8bbb2b06dc849c3de578d692" ], "index": "pypi", - "version": "==1.17.9" -======= - "sha256:7ddb43a5423725adfabb752e21ac7d47c0b440a10128e9884f578848c2369555", - "sha256:e5617cb8244863566df1cb12564e439b224e88ea2270f27b28da82df093eba0a" - ], - "index": "pypi", - "version": "==1.17.11" ->>>>>>> Add hello page, add local mutation + "version": "==1.17.14" }, "backcall": { "hashes": [ @@ -677,24 +683,32 @@ }, "botocore": { "hashes": [ -<<<<<<< HEAD - "sha256:cf3144994191847e30ef76781af867009bdc233b3f1f4736615e5330687a891e", - "sha256:f11ff8616f46ca04697df031e622c9ed50931b9d649d4e719f961e9d80771e8d" + "sha256:34ad4d73e6bef5c8ad956c66354611628cdebd431fe2927261ed9c068b9cfb7a", + "sha256:6570f2ba046956d5b548ab2346d32f713ecf8b8cb098a839d73fcf832ccfa223" ], - "version": "==1.14.10" -======= - "sha256:5ad6f4b80f3151fc5aa940f89fb6bf2db3064bf8d3f8919f5b60f5c741054ba5", - "sha256:ac783a87bd90be8a4d08101bfc0d29a4b35fe0ced387f5c8bc91d01cdaa7a168" + "version": "==1.14.14" + }, + "certifi": { + "hashes": [ + "sha256:017c25db2a153ce562900032d5bc68e9f191e44e9a0f762f373977de9df1fbb3", + "sha256:25b64c7da4cd7479594d035c08c2d809eb4aab3a26e5a990ea98cc450c320f1f" ], - "version": "==1.14.11" ->>>>>>> Add hello page, add local mutation + "version": "==2019.11.28" + }, + "chardet": { + "hashes": [ + "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae", + "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691" + ], + "version": "==3.0.4" }, "colorama": { "hashes": [ - "sha256:05eed71e2e327246ad6b38c540c4a3117230b19679b875190486ddd2d721422d", - "sha256:f8ac84de7840f5b9c4e3347b3c1eaa50f7e49c2b07596221daec5edaabbd7c48" + "sha256:7d73d2a99753107a36ac6b455ee49046802e59d9d076ef8e47b61499fa29afff", + "sha256:e96da0d330793e2cb9485e9ddfd918d456036c7149416295932478192f4436a1" ], - "version": "==0.4.1" + "markers": "python_version != '3.4'", + "version": "==0.4.3" }, "coverage": { "hashes": [ @@ -740,6 +754,22 @@ ], "version": "==4.4.1" }, + "django": { + "hashes": [ + "sha256:48522428f4a285cf265af969f4744c5ebb027c7f41958ba48b639ace2068ffe7", + "sha256:a794f7a2f4b7c928eecfbc4ebad03712ff27fb545abe269bf01aa8500781eb1c" + ], + "index": "pypi", + "version": "==2.1.15" + }, + "django-silk": { + "hashes": [ + "sha256:9d5d66628689230288d1020de186b86e6f38583f611b5dd796ec988bb6a6333e", + "sha256:b0033ec3713882a5abb8b3db2b4392a746b83ce164ab7be568f0eeec4ba78a98" + ], + "index": "pypi", + "version": "==4.0.0" + }, "docutils": { "hashes": [ "sha256:6c4f696463b79f1fb8ba0c594b63840ebd41f059e92b31957c46b74a4599b6d0", @@ -748,6 +778,19 @@ ], "version": "==0.15.2" }, + "gprof2dot": { + "hashes": [ + "sha256:b43fe04ebb3dfe181a612bbfc69e90555b8957022ad6a466f0308ed9c7f22e99" + ], + "version": "==2019.11.30" + }, + "idna": { + "hashes": [ + "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", + "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c" + ], + "version": "==2.8" + }, "ipdb": { "hashes": [ "sha256:5d9a4a0e3b7027a158fc6f2929934341045b9c3b0b86ed5d7e84e409653f72fd" @@ -777,6 +820,13 @@ ], "version": "==0.16.0" }, + "jinja2": { + "hashes": [ + "sha256:93187ffbc7808079673ef52771baa950426fd664d3aad1d0fa3e95644360e250", + "sha256:b0eaf100007721b5c16c1fc1eecb87409464edc10469ddc9a22a27a99123be49" + ], + "version": "==2.11.1" + }, "jmespath": { "hashes": [ "sha256:3720a4b1bd659dd2eecad0666459b9788813e032b83e7ba58578e48254e0a0e6", @@ -784,6 +834,44 @@ ], "version": "==0.9.4" }, + "markupsafe": { + "hashes": [ + "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473", + "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161", + "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235", + "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5", + "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42", + "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff", + "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b", + "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1", + "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e", + "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183", + "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66", + "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b", + "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1", + "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15", + "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1", + "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e", + "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b", + "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905", + "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735", + "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d", + "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e", + "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d", + "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c", + "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21", + "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2", + "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5", + "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b", + "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6", + "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f", + "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f", + "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2", + "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7", + "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be" + ], + "version": "==1.1.1" + }, "parso": { "hashes": [ "sha256:56b2105a80e9c4df49de85e125feb6be69f49920e121406f15e7acde6c9dfc57", @@ -827,6 +915,13 @@ ], "version": "==0.4.8" }, + "pycodestyle": { + "hashes": [ + "sha256:95a2219d12372f05704562a14ec30bc76b05a5b297b21a5dfe3f6fac3491ae56", + "sha256:e40a936c9a450ad81df37f549d676d127b1b66000a6c500caa2b085bc0ca976c" + ], + "version": "==2.5.0" + }, "pygments": { "hashes": [ "sha256:2a3fe295e54a20164a9df49c75fa58526d3be48e14aceba6d6b1e8ac0bfd6f1b", @@ -841,6 +936,13 @@ ], "version": "==2.8.1" }, + "pytz": { + "hashes": [ + "sha256:1c557d7d0e871de1f5ccd5833f60fb2550652da6be2693c1e02300743d21500d", + "sha256:b02c06db6cf09c12dd25137e563b31700d3b80fcc4ad23abb7a315f2789819be" + ], + "version": "==2019.3" + }, "pyyaml": { "hashes": [ "sha256:0e7f69397d53155e55d10ff68fdfb2cf630a35e6daf65cf0bdeaf04f127c09dc", @@ -857,6 +959,14 @@ ], "version": "==5.2" }, + "requests": { + "hashes": [ + "sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4", + "sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31" + ], + "index": "pypi", + "version": "==2.22.0" + }, "rsa": { "hashes": [ "sha256:25df4e10c263fb88b5ace923dd84bf9aa7f5019687b5e55382ffcdb8bede9db5", @@ -866,10 +976,10 @@ }, "s3transfer": { "hashes": [ - "sha256:2525bae2a530195576da53671bae8ca8c55ee8e33bc2225a65e804476611ea5a", - "sha256:4924e10451cc37901945806423d16c2c2040a6530645a614ed87e995ccec764c" + "sha256:2482b4259524933a022d59da830f51bd746db62f047d6eb213f2f8855dcb8a13", + "sha256:921a37e2aefc64145e7b73d50c71bb4f26f46e4c9f414dc648c6245ff92cf7db" ], - "version": "==0.3.2" + "version": "==0.3.3" }, "six": { "hashes": [ @@ -878,6 +988,13 @@ ], "version": "==1.14.0" }, + "sqlparse": { + "hashes": [ + "sha256:40afe6b8d4b1117e7dff5504d7a8ce07d9a1b15aeeade8a2d10f130a834f8177", + "sha256:7c3dca29c022744e95b547e867cee89f4fce4373f3549ccd8797d8eb52cdb873" + ], + "version": "==0.3.0" + }, "traitlets": { "hashes": [ "sha256:70b4c6a1d9019d7b4f6846832288f86998aa3b9207c6821f3578a6a6a467fe44", @@ -890,6 +1007,7 @@ "sha256:2f3db8b19923a873b3e5256dc9c2dedfa883e33d87c690d9c7913e1f40673cdc", "sha256:87716c2d2a7121198ebcb7ce7cccf6ce5e9ba539041cfbaeecfb641dc0bf6acc" ], + "markers": "python_version != '3.4'", "version": "==1.25.8" }, "wcwidth": { diff --git a/client/cypress/fixtures/me.join-class.json b/client/cypress/fixtures/me.join-class.json new file mode 100644 index 00000000..0ab8c2b0 --- /dev/null +++ b/client/cypress/fixtures/me.join-class.json @@ -0,0 +1,35 @@ +{ + "me": { + "id": "VXNlck5vZGU6NQ==", + "pk": 5, + "username": "rahel.cueni", + "email": "rahel.cueni@skillbox.example", + "firstName": "Rahel", + "lastName": "Cueni", + "avatarUrl": "", + "lastModule": { + "id": "TW9kdWxlTm9kZToxNw==", + "slug": "lohn-und-budget", + "__typename": "ModuleNode" + }, + "selectedClass": { + "id": "U2Nob29sQ2xhc3NOb2RlOjI=", + "__typename": "SchoolClassNode" + }, + "schoolClasses": { + "edges": [ + { + "node": { + "id": "U2Nob29sQ2xhc3NOb2RlOjE=", + "name": "FLID2018a", + "__typename": "SchoolClassNode" + }, + "__typename": "SchoolClassNodeEdge" + } + ], + "__typename": "SchoolClassNodeConnection" + }, + "__typename": "UserNode", + "permissions": [] + } +} diff --git a/client/cypress/fixtures/me.new-student.json b/client/cypress/fixtures/me.new-student.json new file mode 100644 index 00000000..0568b0ab --- /dev/null +++ b/client/cypress/fixtures/me.new-student.json @@ -0,0 +1,19 @@ +{ + "me": { + "id": "VXNlck5vZGU6NQ==", + "pk": 5, + "username": "hansli", + "email": "hansli@skillbox.example", + "firstName": "Hansli", + "lastName": "Alleini", + "avatarUrl": "", + "lastModule": null, + "selectedClass": null, + "schoolClasses": { + "edges": [], + "__typename": "SchoolClassNodeConnection" + }, + "__typename": "UserNode", + "permissions": [] + } +} diff --git a/client/cypress/fixtures/schema.json b/client/cypress/fixtures/schema.json index a5e6c387..c72fcdd8 100644 --- a/client/cypress/fixtures/schema.json +++ b/client/cypress/fixtures/schema.json @@ -1,4 +1,5 @@ { + "data": { "__schema": { "queryType": { "name": "Query" @@ -3125,6 +3126,18 @@ }, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "expiryDate", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null } ], "inputFields": null, @@ -3350,6 +3363,18 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "code", + "description": "", + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "hiddenContentBlocks", "description": null, @@ -9385,6 +9410,33 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "joinClass", + "description": null, + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "JoinClassInput", + "ofType": null + } + }, + "defaultValue": null + } + ], + "type": { + "kind": "OBJECT", + "name": "JoinClassPayload", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "addProject", "description": null, @@ -10534,6 +10586,16 @@ }, "defaultValue": null }, + { + "name": "userIdInput", + "description": null, + "type": { + "kind": "SCALAR", + "name": "Int", + "ofType": null + }, + "defaultValue": null + }, { "name": "clientMutationId", "description": null, @@ -11609,6 +11671,88 @@ "enumValues": null, "possibleTypes": null }, + { + "kind": "OBJECT", + "name": "JoinClassPayload", + "description": null, + "fields": [ + { + "name": "success", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "Boolean", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "schoolClass", + "description": null, + "args": [], + "type": { + "kind": "OBJECT", + "name": "SchoolClassNode", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "clientMutationId", + "description": null, + "args": [], + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + } + ], + "inputFields": null, + "interfaces": [], + "enumValues": null, + "possibleTypes": null + }, + { + "kind": "INPUT_OBJECT", + "name": "JoinClassInput", + "description": null, + "fields": null, + "inputFields": [ + { + "name": "code", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null + }, + { + "name": "clientMutationId", + "description": null, + "type": { + "kind": "SCALAR", + "name": "String", + "ofType": null + }, + "defaultValue": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, { "kind": "OBJECT", "name": "AddProjectPayload", @@ -15826,5 +15970,5 @@ } ] } - -} + } +} \ No newline at end of file diff --git a/client/cypress/integration/bookmarks.spec.js b/client/cypress/integration/bookmarks.spec.js index 3ac32dae..eb8f0e39 100644 --- a/client/cypress/integration/bookmarks.spec.js +++ b/client/cypress/integration/bookmarks.spec.js @@ -1,4 +1,4 @@ -describe('Survey', () => { +describe('Bookmarks', () => { beforeEach(() => { // todo: mock all the graphql queries and mutations cy.exec("python ../server/manage.py prepare_bookmarks_for_cypress"); @@ -27,7 +27,6 @@ describe('Survey', () => { cy.get('@interviewContent').within(() => { cy.get('.bookmark-actions__edit-note').click(); - }); cy.get('[data-cy=bookmark-note]').within(() => { diff --git a/client/cypress/integration/join-class.spec.js b/client/cypress/integration/join-class.spec.js new file mode 100644 index 00000000..b8306154 --- /dev/null +++ b/client/cypress/integration/join-class.spec.js @@ -0,0 +1,49 @@ +const schema = require('../fixtures/schema.json'); +const me = require('../fixtures/me.join-class.json'); + +describe('Join Class', () => { + beforeEach(() => { + cy.server(); + + cy.mockGraphql({ + schema: schema, + }); + + cy.viewport('macbook-15'); + cy.apolloLogin('rahel.cueni', 'test'); + + }); + + it('should join class', () => { + cy.mockGraphqlOps({ + operations: { + MeQuery: me, + JoinClass: { + joinClass: { + success: true, + schoolClass: { + id: "U2Nob29sQ2xhc3NOb2RlOjI=", + name: "KF1A", + __typename: "SchoolClassNode" + } + } + } + } + }); + + + cy.visit('/me/profile'); + + cy.get('[data-cy=user-widget-avatar]').click(); + cy.get('[data-cy=class-selection]').click(); + cy.get('[data-cy=class-selection-entry]').should('have.length', 1); + + cy.get('[data-cy=join-class-link]').click(); + + cy.get('[data-cy=input-class-code]').type('XXXX'); + cy.get('[data-cy=join-class]').click(); + + cy.get('[data-cy=class-selection]').click(); + cy.get('[data-cy=class-selection-entry]').should('have.length', 2); + }) +}) diff --git a/client/cypress/integration/new-student.spec.js b/client/cypress/integration/new-student.spec.js new file mode 100644 index 00000000..873c0d93 --- /dev/null +++ b/client/cypress/integration/new-student.spec.js @@ -0,0 +1,38 @@ +const schema = require('../fixtures/schema.json'); +const me = require('../fixtures/me.new-student.json'); + +describe('New student', () => { + it('shows "Enter Code" page and adds the user to a class', () => { + + cy.server(); + + cy.mockGraphql({ + schema: schema, + }); + + + cy.apolloLogin('hansli', 'test'); + + cy.mockGraphqlOps({ + operations: { + MeQuery: me, + JoinClass: { + joinClass: { + success: true, + schoolClass: { + id: "U2Nob29sQ2xhc3NOb2RlOjI=", + name: "KF1A", + __typename: "SchoolClassNode" + } + } + } + } + }); + + cy.visit('/'); + cy.get('[data-cy=join-class-title]').should('contain', 'Zugangscode'); + cy.get('[data-cy=input-class-code]').type('XXXX'); + cy.get('[data-cy=join-class]').click(); + cy.get('[data-cy=class-list-title]').should('contain', 'Klassenliste'); + }); +}); diff --git a/client/cypress/integration/survey.spec.js b/client/cypress/integration/survey.spec.js index 97943eac..5c486fac 100644 --- a/client/cypress/integration/survey.spec.js +++ b/client/cypress/integration/survey.spec.js @@ -10,7 +10,6 @@ describe('Survey', () => { }); cy.viewport('macbook-15'); - cy.apolloLogin('rahel.cueni', 'test'); }); diff --git a/client/src/components/TopNavigation.vue b/client/src/components/ContentNavigation.vue similarity index 92% rename from client/src/components/TopNavigation.vue rename to client/src/components/ContentNavigation.vue index a6969d5b..aa982ccf 100644 --- a/client/src/components/TopNavigation.vue +++ b/client/src/components/ContentNavigation.vue @@ -59,15 +59,8 @@ display: flex; &__link { - font-size: 1.0625rem; padding: 0 24px; - font-family: $sans-serif-font-family; - font-weight: $font-weight-regular; - color: $color-silver-dark; - - &--active { - color: $color-brand; - } + @include default-link; } $parent: &; diff --git a/client/src/components/HeaderBar.vue b/client/src/components/HeaderBar.vue index 35ae07ac..e4f9e03b 100644 --- a/client/src/components/HeaderBar.vue +++ b/client/src/components/HeaderBar.vue @@ -1,11 +1,12 @@ @@ -127,5 +119,13 @@ .user-header { display: flex; + + &__current-class { + margin-right: $large-spacing; + } + + &__sidebar-link { + cursor: pointer; + } } diff --git a/client/src/components/UserWidget.vue b/client/src/components/UserWidget.vue index 7de9e75d..5c6109b5 100644 --- a/client/src/components/UserWidget.vue +++ b/client/src/components/UserWidget.vue @@ -1,36 +1,17 @@ @@ -45,11 +76,11 @@ width: $max-width; overflow: hidden; text-align: center; - border-radius: 50%; &__placeholder { height: $max-width; fill: $color-silver-dark; + border-radius: 50%; &--highlighted { fill: $color-brand; @@ -57,14 +88,14 @@ } &__image { + background-size: cover; + background-position: center center; + height: 100%; + width: 100%; + border: 0; + border-radius: 50%; - background-size: cover; - background-position: center center; - height: 100%; - width: 100%; - border: 0; - - &--landscape { + &--landscape { width: auto; height: $max-width; } @@ -75,10 +106,25 @@ height: 0; } - .fade-leave-active, .show-enter-active { + &__edit { + position: absolute; + box-sizing: border-box; + width: 34px; + height: 34px; + display: block; + left: 50%; + bottom: -7px; + transform: translateX(50%); + background-color: $color-white; + border-radius: 50%; + padding: 6px; + box-shadow: 0 3px 10px rgba(0, 0, 0, 0.12); + } + + .fade-leave-active, .show-enter-active { transition: opacity .5s; } - .fade-leave-to, .show-enter { + .fade-leave-to, .show-enter { opacity: 0; } diff --git a/client/src/components/profile/PasswordChange.vue b/client/src/components/profile/PasswordChange.vue index 3d48a364..1ea94ee5 100644 --- a/client/src/components/profile/PasswordChange.vue +++ b/client/src/components/profile/PasswordChange.vue @@ -1,4 +1,5 @@ @@ -29,7 +30,7 @@ } }, methods: { - resetPassword (passwords) { + resetPassword(passwords) { this.$apollo.mutate({ mutation: UPDATE_PASSWORD_MUTATION, variables: { @@ -37,7 +38,7 @@ passwordInput: passwords } } - }).then(({ data }) => { + }).then(({data}) => { if (data.updatePassword.success) { this.oldPasswordErrors = []; this.newPasswordErrors = []; @@ -56,14 +57,14 @@ console.log('fail', error) }); }, - handleOldPasswordError (error) { + handleOldPasswordError(error) { this.oldPasswordErrors = error.errors.map((fieldError) => { if (fieldError.code === 'invalid') { return 'Die Eingabe ist falsch' } }); }, - handleNewPasswordError (error) { + handleNewPasswordError(error) { this.newPasswordErrors = error.errors.map((fieldError) => { if (fieldError.code === 'invalid') { return 'Das Passwort muss Grossbuchstaben, Zahlen und Sonderzeichen beinhalten' diff --git a/client/src/components/profile/Profile.vue b/client/src/components/profile/Profile.vue index eb1303fc..3a372444 100644 --- a/client/src/components/profile/Profile.vue +++ b/client/src/components/profile/Profile.vue @@ -11,22 +11,18 @@ - + + diff --git a/client/src/components/profile/ProfileWidget.vue b/client/src/components/profile/ProfileWidget.vue new file mode 100644 index 00000000..a50698a1 --- /dev/null +++ b/client/src/components/profile/ProfileWidget.vue @@ -0,0 +1,53 @@ + + + + + diff --git a/client/src/components/ClassSelectionWidget.vue b/client/src/components/school-class/ClassSelectionWidget.vue similarity index 50% rename from client/src/components/ClassSelectionWidget.vue rename to client/src/components/school-class/ClassSelectionWidget.vue index 214d345a..c11f9dd9 100644 --- a/client/src/components/ClassSelectionWidget.vue +++ b/client/src/components/school-class/ClassSelectionWidget.vue @@ -1,31 +1,37 @@ + + diff --git a/client/src/graphql/client.js b/client/src/graphql/client.js index 9ae5251c..17128bd9 100644 --- a/client/src/graphql/client.js +++ b/client/src/graphql/client.js @@ -111,6 +111,10 @@ export default function (uri, networkErrorCallback) { helloEmail: { __typename: 'HelloEmail', email: '' + }, + sidebar: { + __typename: 'Sidebar', + open: false } } }); diff --git a/client/src/graphql/gql/local/mutations/toggleSidebar.gql b/client/src/graphql/gql/local/mutations/toggleSidebar.gql new file mode 100644 index 00000000..fc32729e --- /dev/null +++ b/client/src/graphql/gql/local/mutations/toggleSidebar.gql @@ -0,0 +1,3 @@ +mutation($open: Boolean!) { + toggleSidebar(open: $open) @client +} diff --git a/client/src/graphql/gql/local/sidebar.gql b/client/src/graphql/gql/local/sidebar.gql new file mode 100644 index 00000000..4cdb1bc6 --- /dev/null +++ b/client/src/graphql/gql/local/sidebar.gql @@ -0,0 +1,5 @@ +query Sidebar { + sidebar @client { + open + } +} diff --git a/client/src/graphql/gql/mutations/joinClass.gql b/client/src/graphql/gql/mutations/joinClass.gql new file mode 100644 index 00000000..025ff5b7 --- /dev/null +++ b/client/src/graphql/gql/mutations/joinClass.gql @@ -0,0 +1,9 @@ +mutation JoinClass($input: JoinClassInput!) { + joinClass(input: $input) { + success + schoolClass { + id + name + } + } +} diff --git a/client/src/graphql/resolvers.js b/client/src/graphql/resolvers.js index 27a60133..11cd35eb 100644 --- a/client/src/graphql/resolvers.js +++ b/client/src/graphql/resolvers.js @@ -1,5 +1,6 @@ import SCROLL_POSITION from '@/graphql/gql/local/scrollPosition.gql'; import HELLO_EMAIL from '@/graphql/gql/local/helloEmail.gql'; +import SIDEBAR from '@/graphql/gql/local/sidebar.gql'; export const resolvers = { Mutation: { @@ -15,5 +16,11 @@ export const resolvers = { cache.writeQuery({query: HELLO_EMAIL, data}); return data.helloEmail; }, + toggleSidebar: (_, {open}, {cache}) => { + const data = cache.readQuery({query: SIDEBAR}); + data.sidebar.open = open; + cache.writeQuery({query: SIDEBAR, data}); + return data.sidebar; + } } }; diff --git a/client/src/graphql/typedefs.js b/client/src/graphql/typedefs.js index f1e6c9ff..c17dd4a3 100644 --- a/client/src/graphql/typedefs.js +++ b/client/src/graphql/typedefs.js @@ -9,6 +9,11 @@ export const typeDefs = gql` email: String! } + + type Sidebar { + open: Boolean! + } + type Mutation { scrollTo(scrollTo: String!): ScrollPosition } diff --git a/client/src/layouts/BlankLayout.vue b/client/src/layouts/BlankLayout.vue index 0c7e4df8..932df5d7 100644 --- a/client/src/layouts/BlankLayout.vue +++ b/client/src/layouts/BlankLayout.vue @@ -1,5 +1,6 @@ @@ -14,9 +15,9 @@ diff --git a/client/src/layouts/DefaultLayout.vue b/client/src/layouts/DefaultLayout.vue index b29dabc7..33ca3f48 100644 --- a/client/src/layouts/DefaultLayout.vue +++ b/client/src/layouts/DefaultLayout.vue @@ -1,5 +1,6 @@