diff --git a/.gitignore b/.gitignore index 90ceb143..f11c4ce0 100644 --- a/.gitignore +++ b/.gitignore @@ -40,3 +40,5 @@ server/media/ # pyenv .python-version + +.coverage diff --git a/Pipfile b/Pipfile index af02de55..55793104 100644 --- a/Pipfile +++ b/Pipfile @@ -36,3 +36,4 @@ bleach = "*" newrelic = "*" sentry-sdk = "==0.7.2" "django-sendgrid-v5" = "*" +coverage = "*" diff --git a/Pipfile.lock b/Pipfile.lock index c1724977..3938e957 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "c0e186a3fb465dc3cb6985204c534ea52652af00103c61601d0f859bacdee533" + "sha256": "97ff5ca56ac835d40353e34e32ec8333ccb23822bcf971644b7641429d9774e1" }, "pipfile-spec": 6, "requires": { @@ -41,19 +41,18 @@ }, "boto3": { "hashes": [ - "sha256:39e9b6516a72864f5a6b69f38edac087cc4ba623095f4528b916620e63de32b3", - "sha256:a3eb22bb975a200a69084ec2bb69819e483ad531bf05e7b73861fc1b333aad42" + "sha256:3927beac97e5467f869d63d60920b83c2d39964f69fbf944bc1db724116bfe1a", + "sha256:be88cae6f16bb9fe3b850b6c8259b297f60b46855175cadae57594c9a403c582" ], "index": "pypi", - "version": "==1.9.120" + "version": "==1.9.124" }, "botocore": { "hashes": [ - "sha256:2bf8768887bfb008406eec725eecf6f174307dac00f5fad244cdd5d39c6c2147", - "sha256:c0f9c57e7a8c65f17a62a0926c3e73686f6ae1c08abf3b5a63cc3a5bcc4c437b" + "sha256:bb756a8da2c6e3ccf42dccb0ac71c1df2e07844db339183da06f4e0285b251d0", + "sha256:fc7560a2676df2f0bab4ef0638277b86e5a00944c2ce1c3bb124b3066e6d3d2a" ], - "markers": "python_version != '3.0.*' and python_version >= '2.6' and python_version != '3.1.*'", - "version": "==1.12.120" + "version": "==1.12.124" }, "certifi": { "hashes": [ @@ -74,9 +73,45 @@ "sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13", "sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7" ], - "markers": "python_version != '3.2.*' and python_version != '3.0.*' and python_version != '3.1.*' and python_version >= '2.7' and python_version != '3.3.*'", "version": "==7.0" }, + "coverage": { + "hashes": [ + "sha256:3684fabf6b87a369017756b551cef29e505cb155ddb892a7a29277b978da88b9", + "sha256:39e088da9b284f1bd17c750ac672103779f7954ce6125fd4382134ac8d152d74", + "sha256:3c205bc11cc4fcc57b761c2da73b9b72a59f8d5ca89979afb0c1c6f9e53c7390", + "sha256:465ce53a8c0f3a7950dfb836438442f833cf6663d407f37d8c52fe7b6e56d7e8", + "sha256:48020e343fc40f72a442c8a1334284620f81295256a6b6ca6d8aa1350c763bbe", + "sha256:5296fc86ab612ec12394565c500b412a43b328b3907c0d14358950d06fd83baf", + "sha256:5f61bed2f7d9b6a9ab935150a6b23d7f84b8055524e7be7715b6513f3328138e", + "sha256:68a43a9f9f83693ce0414d17e019daee7ab3f7113a70c79a3dd4c2f704e4d741", + "sha256:6b8033d47fe22506856fe450470ccb1d8ba1ffb8463494a15cfc96392a288c09", + "sha256:7ad7536066b28863e5835e8cfeaa794b7fe352d99a8cded9f43d1161be8e9fbd", + "sha256:7bacb89ccf4bedb30b277e96e4cc68cd1369ca6841bde7b005191b54d3dd1034", + "sha256:839dc7c36501254e14331bcb98b27002aa415e4af7ea039d9009409b9d2d5420", + "sha256:8f9a95b66969cdea53ec992ecea5406c5bd99c9221f539bca1e8406b200ae98c", + "sha256:932c03d2d565f75961ba1d3cec41ddde00e162c5b46d03f7423edcb807734eab", + "sha256:988529edadc49039d205e0aa6ce049c5ccda4acb2d6c3c5c550c17e8c02c05ba", + "sha256:998d7e73548fe395eeb294495a04d38942edb66d1fa61eb70418871bc621227e", + "sha256:9de60893fb447d1e797f6bf08fdf0dbcda0c1e34c1b06c92bd3a363c0ea8c609", + "sha256:9e80d45d0c7fcee54e22771db7f1b0b126fb4a6c0a2e5afa72f66827207ff2f2", + "sha256:a545a3dfe5082dc8e8c3eb7f8a2cf4f2870902ff1860bd99b6198cfd1f9d1f49", + "sha256:a5d8f29e5ec661143621a8f4de51adfb300d7a476224156a39a392254f70687b", + "sha256:aca06bfba4759bbdb09bf52ebb15ae20268ee1f6747417837926fae990ebc41d", + "sha256:bb23b7a6fd666e551a3094ab896a57809e010059540ad20acbeec03a154224ce", + "sha256:bfd1d0ae7e292105f29d7deaa9d8f2916ed8553ab9d5f39ec65bcf5deadff3f9", + "sha256:c62ca0a38958f541a73cf86acdab020c2091631c137bd359c4f5bddde7b75fd4", + "sha256:c709d8bda72cf4cd348ccec2a4881f2c5848fd72903c185f363d361b2737f773", + "sha256:c968a6aa7e0b56ecbd28531ddf439c2ec103610d3e2bf3b75b813304f8cb7723", + "sha256:df785d8cb80539d0b55fd47183264b7002077859028dfe3070cf6359bf8b2d9c", + "sha256:f406628ca51e0ae90ae76ea8398677a921b36f0bd71aab2099dfed08abd0322f", + "sha256:f46087bbd95ebae244a0eda01a618aff11ec7a069b15a3ef8f6b520db523dcf1", + "sha256:f8019c5279eb32360ca03e9fac40a12667715546eed5c5eb59eb381f2f501260", + "sha256:fc5f4d209733750afd2714e9109816a29500718b32dd9a5db01c0cb3a019b96a" + ], + "index": "pypi", + "version": "==4.5.3" + }, "dj-database-url": { "hashes": [ "sha256:7f4c78d2a090df8dfaf56d5d3ff7bbee17360436e4879558317e2314424864cd" @@ -209,14 +244,12 @@ "sha256:00b7011757c4907546f17d0e47df098b542ea2b04c966ee0e80a493aae2c13c8", "sha256:745ac8b9c9526e338696e07b7f2e206e5e317e5744e22fdd7c2894bf19af41f1" ], - "markers": "python_version != '3.2.*' and python_version >= '2.7' and python_version != '3.1.*' and python_version != '3.0.*'", "version": "==1.0.4" }, "future": { "hashes": [ "sha256:67045236dcfd6816dc439556d009594abf643e5eb48992e36beac09c2ca659b8" ], - "markers": "python_version != '3.1.*' and python_version != '3.2.*' and python_version != '3.0.*' and python_version >= '2.6'", "version": "==0.17.1" }, "graphene": { @@ -239,7 +272,6 @@ "sha256:889e869be5574d02af77baf1f30b5db9ca2959f1c9f5be7b2863ead5a3ec6181", "sha256:9462e22e32c7f03b667373ec0a84d95fba10e8ce2ead08f29fbddc63b671b0c1" ], - "markers": "python_version >= '2.6' and python_version != '3.0.*' and python_version != '3.1.*'", "version": "==2.1" }, "graphql-relay": { @@ -261,7 +293,6 @@ "sha256:20b159aa3badc9d5ee8f5c647e5efd02ed2a66ab8d354930bd9ff139fc1dc0a3", "sha256:66cb0dcfdbbc4f9c3ba1a63fdb511ffdbd4f513b2b6d81b80cd26ce6b3fb3736" ], - "markers": "python_version >= '2.6' and python_version != '3.0.*' and python_version != '3.1.*'", "version": "==1.0.1" }, "idna": { @@ -269,7 +300,6 @@ "sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407", "sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c" ], - "markers": "python_version != '3.2.*' and python_version != '3.0.*' and python_version != '3.1.*' and python_version >= '2.7' and python_version != '3.3.*'", "version": "==2.8" }, "jmespath": { @@ -298,15 +328,14 @@ "sha256:e8941881063691d50f9cc8b8d6d8fd7bec86a8c461b2a4fc87188a5fc44d6ba4", "sha256:f4b29b0c70d753c754a58aaad7c31ad3309ca4a26f9aa64e695157251f6832ad" ], - "markers": "python_version >= '2.6' and python_version != '3.0.*' and python_version != '3.1.*'", "version": "==0.18.0" }, "newrelic": { "hashes": [ - "sha256:b0f2ef6c817d9b5389cb3ef0f06037abbd1c1ed1a4ae04f293dadeb0f78ea924" + "sha256:1d08248dee0d33116a145de723a2ae86e57a10674145ce4c8af3c316423bd140" ], "index": "pypi", - "version": "==4.14.0.115" + "version": "==4.16.0.116" }, "pillow": { "hashes": [ @@ -344,7 +373,6 @@ "sha256:2ebbfc10b7abf6354403ed785fe4f04b9dfd421eb1a474ac8d187022228332af", "sha256:348f5f6c3edd4fd47c9cd65aed03ac1b31136d375aa63871a57d3e444c85655c" ], - "markers": "python_version >= '2.6' and python_version != '3.0.*' and python_version != '3.1.*'", "version": "==2.2.1" }, "psycopg2": { @@ -432,7 +460,6 @@ "sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e", "sha256:7bf2a778576d825600030a110f3c0e3e8edc51dfaafe1c146e39a2027784957b" ], - "markers": "python_version != '3.2.*' and python_version != '3.0.*' and python_version != '3.1.*' and python_version < '4' and python_version >= '2.7' and python_version != '3.3.*'", "version": "==2.21.0" }, "rjsmin": { @@ -453,7 +480,6 @@ "sha256:7b9ad3213bff7d357f888e0fab5101b56fa1a0548ee77d121c3a3dbfbef4cb2e", "sha256:f23d5cb7d862b104401d9021fc82e5fa0e0cf57b7660a1331425aab0c691d021" ], - "markers": "python_version != '3.0.*' and python_version >= '2.6' and python_version != '3.1.*'", "version": "==0.2.0" }, "sendgrid": { @@ -476,7 +502,6 @@ "sha256:5b06af87df13818d14f08a028e42f566640aef80805c3b50c5056b086e3c2b9c", "sha256:833b46966687b3de7f438c761ac475213e53b306740f1abfaa86e1d1aae56aa8" ], - "markers": "python_version >= '2.6' and python_version != '3.0.*' and python_version != '3.1.*'", "version": "==3.4.0.3" }, "six": { @@ -484,7 +509,6 @@ "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" ], - "markers": "python_version != '3.0.*' and python_version >= '2.6' and python_version != '3.1.*'", "version": "==1.12.0" }, "text-unidecode": { @@ -553,21 +577,13 @@ } }, "develop": { - "appnope": { - "hashes": [ - "sha256:5b26757dc6f79a3b7dc9fab95359328d5747fcb2409d331ea66d0272b90ab2a0", - "sha256:8b995ffe925347a2138d7ac0fe77155e4311a0ea6d6da4f5128fe4b3cbe5ed71" - ], - "markers": "sys_platform == 'darwin'", - "version": "==0.1.0" - }, "awscli": { "hashes": [ - "sha256:9cbc48eff6f8c9ee2072be2caf569dd5f18734d61e020556b792ba509bbb03f0", - "sha256:e0b9afc24c591ecb04d02a34d9e8d3508a4bd25c713d10a358cdad09abbbcf8e" + "sha256:87258e4719978f51dae8c62e15cd0486a778ddcb530645f3bc035239b800f184", + "sha256:fbd9dc00ecd7060f36e5768122c9293672b82748fa224cb13e22e6322532d8db" ], "index": "pypi", - "version": "==1.16.130" + "version": "==1.16.134" }, "backcall": { "hashes": [ @@ -578,11 +594,10 @@ }, "botocore": { "hashes": [ - "sha256:2bf8768887bfb008406eec725eecf6f174307dac00f5fad244cdd5d39c6c2147", - "sha256:c0f9c57e7a8c65f17a62a0926c3e73686f6ae1c08abf3b5a63cc3a5bcc4c437b" + "sha256:bb756a8da2c6e3ccf42dccb0ac71c1df2e07844db339183da06f4e0285b251d0", + "sha256:fc7560a2676df2f0bab4ef0638277b86e5a00944c2ce1c3bb124b3066e6d3d2a" ], - "markers": "python_version != '3.0.*' and python_version >= '2.6' and python_version != '3.1.*'", - "version": "==1.12.120" + "version": "==1.12.124" }, "colorama": { "hashes": [ @@ -633,7 +648,6 @@ "sha256:86156361c50488b84a3f148056ea716ca587df2f0de1d34750d35c21312725de", "sha256:f069f3a01830ca754ba5258fde2278454a0b5b79e0d7f5c13b3b97e57d4acff6" ], - "markers": "python_version != '3.0.*' and python_version >= '2.6' and python_version != '3.1.*'", "version": "==4.4.0" }, "docutils": { @@ -766,7 +780,6 @@ "sha256:7b9ad3213bff7d357f888e0fab5101b56fa1a0548ee77d121c3a3dbfbef4cb2e", "sha256:f23d5cb7d862b104401d9021fc82e5fa0e0cf57b7660a1331425aab0c691d021" ], - "markers": "python_version != '3.0.*' and python_version >= '2.6' and python_version != '3.1.*'", "version": "==0.2.0" }, "six": { @@ -774,7 +787,6 @@ "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" ], - "markers": "python_version != '3.0.*' and python_version >= '2.6' and python_version != '3.1.*'", "version": "==1.12.0" }, "traitlets": { diff --git a/bitbucket-pipelines.yml b/bitbucket-pipelines.yml index 981aa2a1..561e7856 100644 --- a/bitbucket-pipelines.yml +++ b/bitbucket-pipelines.yml @@ -36,7 +36,7 @@ aliases: - echo "This pipeline rules!" - *setup-tests - npm install --prefix client -# - npm run "install:cypress" --prefix client + # - npm run "install:cypress" --prefix client - psql -U $DATABASE_USER -h $DATABASE_HOST -c "create database $DATABASE_NAME" - python server/manage.py dummy_data - python server/manage.py runserver & @@ -55,6 +55,7 @@ pipelines: branches: master: - step: *unittest-python + - step: *cypress-test develop: - step: *unittest-python @@ -67,4 +68,5 @@ pipelines: custom: prod: - step: *unittest-python + - step: *cypress-test - step: *deploy-prod diff --git a/client/cypress/integration/login-page-spec.js b/client/cypress/integration/login-page-spec.js index 83d50dcf..ee32a857 100644 --- a/client/cypress/integration/login-page-spec.js +++ b/client/cypress/integration/login-page-spec.js @@ -9,7 +9,7 @@ describe('The Login Page', () => { cy.get('#id_password').type(`${password}{enter}`); cy.getCookie('sessionid').should('exist'); - cy.get('.start-page__title').should('contain', 'skillbox') + cy.get('.start-page__header').should('exist') }); // it('logs in programmatically without using the UI', () => { // cy.visit('/accounts/login/'); // have to get a csrf token by getting the base page first diff --git a/client/cypress/integration/new-project.spec.js b/client/cypress/integration/new-project.spec.js index b320e8bf..986038b8 100644 --- a/client/cypress/integration/new-project.spec.js +++ b/client/cypress/integration/new-project.spec.js @@ -1,5 +1,6 @@ describe('New project', () => { it('creates a new project and displays it', () => { + cy.viewport('macbook-15'); cy.login('rahel.cueni', 'test'); cy.visit('/portfolio'); diff --git a/client/index.html b/client/index.html index 7b0024b6..b94913b0 100644 --- a/client/index.html +++ b/client/index.html @@ -2,7 +2,7 @@ - + skillbox diff --git a/client/package-lock.json b/client/package-lock.json index 764af335..d6031d7f 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -3042,6 +3042,12 @@ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, + "moment": { + "version": "2.22.2", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", + "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=", + "dev": true + }, "supports-color": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.1.0.tgz", @@ -7191,10 +7197,9 @@ } }, "moment": { - "version": "2.22.2", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", - "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=", - "dev": true + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", + "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" }, "move-concurrently": { "version": "1.0.1", diff --git a/client/package.json b/client/package.json index 326d8fd5..ba340f11 100644 --- a/client/package.json +++ b/client/package.json @@ -51,6 +51,7 @@ "graphql-tag": "^2.9.2", "html-webpack-plugin": "^2.30.1", "lodash": "^4.17.10", + "moment": "^2.24.0", "node-notifier": "^5.1.2", "node-sass": "^4.9.2", "optimize-css-assets-webpack-plugin": "^3.2.0", diff --git a/client/src/App.vue b/client/src/App.vue index b80a48b6..1c73926d 100644 --- a/client/src/App.vue +++ b/client/src/App.vue @@ -1,7 +1,8 @@ @@ -10,6 +11,7 @@ import SimpleLayout from '@/layouts/SimpleLayout'; import BlankLayout from '@/layouts/BlankLayout'; import Modal from '@/components/Modal'; + import MobileNavigation from '@/components/MobileNavigation'; import NewContentBlockWizard from '@/components/content-block-form/NewContentBlockWizard'; import EditContentBlockWizard from '@/components/content-block-form/EditContentBlockWizard'; import NewRoomEntryWizard from '@/components/rooms/room-entries/NewRoomEntryWizard'; @@ -21,6 +23,8 @@ import FullscreenInfographic from '@/components/FullscreenInfographic'; import FullscreenVideo from '@/components/FullscreenVideo'; + import {mapGetters} from 'vuex'; + export default { name: 'App', @@ -29,6 +33,7 @@ SimpleLayout, BlankLayout, Modal, + MobileNavigation, NewContentBlockWizard, EditContentBlockWizard, NewRoomEntryWizard, @@ -45,9 +50,7 @@ layout() { return (this.$route.meta.layout || 'default') + '-layout'; }, - showModal() { - return this.$store.state.showModal - } + ...mapGetters(['showModal', 'showMobileNavigation']) }, mounted() { @@ -58,6 +61,18 @@ diff --git a/client/src/components/LogoutWidget.vue b/client/src/components/LogoutWidget.vue index 2889a985..bba0f6d4 100644 --- a/client/src/components/LogoutWidget.vue +++ b/client/src/components/LogoutWidget.vue @@ -32,7 +32,7 @@ &__logout { font-family: $sans-serif-font-family; line-height: 16px; - margin: 0 15px 0 20px; + margin: 0 15px 0 $large-spacing; background: none; color: inherit; border: none; diff --git a/client/src/components/MobileHeader.vue b/client/src/components/MobileHeader.vue new file mode 100644 index 00000000..d30a2b0a --- /dev/null +++ b/client/src/components/MobileHeader.vue @@ -0,0 +1,54 @@ + + + + + diff --git a/client/src/components/MobileNavigation.vue b/client/src/components/MobileNavigation.vue new file mode 100644 index 00000000..5219504d --- /dev/null +++ b/client/src/components/MobileNavigation.vue @@ -0,0 +1,118 @@ + + + + + diff --git a/client/src/components/Modal.vue b/client/src/components/Modal.vue index 51352e74..3fb0f7c8 100644 --- a/client/src/components/Modal.vue +++ b/client/src/components/Modal.vue @@ -59,9 +59,13 @@ border-radius: 12px; box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.15); border: 1px solid $color-lightgrey; - display: grid; + display: -ms-grid; + @supports (display: grid) { + display: grid; + } grid-template-rows: auto 1fr 65px; grid-template-areas: "header" "body" "footer"; + -ms-grid-rows: auto 1fr 65px; position: relative; &--hide-header { @@ -81,6 +85,7 @@ width: 95vw; height: auto; grid-template-rows: 1fr; + -ms-grid-rows: 1fr; grid-template-areas: "body"; overflow: hidden; } @@ -107,7 +112,11 @@ } &__backdrop { - display: grid; + display: flex; + justify-content: center; + @supports (display: grid) { + display: grid; + } position: fixed; top: 0; left: 0; @@ -119,12 +128,14 @@ &__header { grid-area: header; + -ms-grid-row: 1; padding: 10px $modal-lateral-padding; border-bottom: 1px solid $color-lightgrey; } &__body { grid-area: body; + -ms-grid-row: 2; padding: 10px $modal-lateral-padding; overflow: auto; box-sizing: border-box; @@ -150,6 +161,7 @@ &__footer { grid-area: footer; + -ms-grid-row: 3; border-top: 1px solid $color-lightgrey; padding: 16px $modal-lateral-padding; } diff --git a/client/src/components/NewsTeaser.vue b/client/src/components/NewsTeaser.vue index c2235dcd..d55a2cd3 100644 --- a/client/src/components/NewsTeaser.vue +++ b/client/src/components/NewsTeaser.vue @@ -4,8 +4,8 @@ {{title}} - {{date}} - + {{date}} + @@ -18,10 +18,21 @@ diff --git a/client/src/components/WidgetFooter.vue b/client/src/components/WidgetFooter.vue index ec3db215..52c232b5 100644 --- a/client/src/components/WidgetFooter.vue +++ b/client/src/components/WidgetFooter.vue @@ -38,6 +38,7 @@ diff --git a/client/src/components/page-form/PageForm.vue b/client/src/components/page-form/PageForm.vue index aa743655..69aca5b0 100644 --- a/client/src/components/page-form/PageForm.vue +++ b/client/src/components/page-form/PageForm.vue @@ -30,11 +30,19 @@ box-sizing: border-box; background-color: $color-white; border-radius: $default-border-radius; - display: grid; + display: flex; + flex-direction: column; + @supports (display: grid) { + display: grid; + } grid-template-rows: 1fr 55px; &__page { - display: grid; + display: flex; + justify-content: center; + @supports (display: grid) { + display: grid; + } justify-items: center; align-items: center; height: 100%; diff --git a/client/src/components/portfolio/ProjectWidget.vue b/client/src/components/portfolio/ProjectWidget.vue index 4c374265..9f6ff647 100644 --- a/client/src/components/portfolio/ProjectWidget.vue +++ b/client/src/components/portfolio/ProjectWidget.vue @@ -1,12 +1,12 @@