diff --git a/.travis.yml b/.travis.yml index a2aae3cdb..19ba3ff9d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ install: - yarn global add wait-on # Install Codecov - yarn install - - cp cypress.env.template.json cypress.env.json + - cp backend/.env.template backend/.env before_script: - docker-compose -f docker-compose.yml build --parallel @@ -63,14 +63,14 @@ before_deploy: deploy: - provider: script - script: scripts/docker_push.sh + script: bash scripts/docker_push.sh on: branch: master - provider: script - script: scripts/deploy.sh + script: bash scripts/deploy.sh on: branch: master - provider: script - script: scripts/github_release.sh + script: bash scripts/github_release.sh on: branch: master diff --git a/CHANGELOG.md b/CHANGELOG.md index 72ca59fad..9cc015aa4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,10 +4,102 @@ All notable changes to this project will be documented in this file. Dates are d Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). -#### [v0.1.11](https://github.com/Human-Connection/Human-Connection/compare/v0.1.10...v0.1.11) +#### [v0.1.12](https://github.com/Human-Connection/Human-Connection/compare/v0.1.10...v0.1.12) -> 25 November 2019 +> 10 December 2019 +- Show the comments again [`#2482`](https://github.com/Human-Connection/Human-Connection/pull/2482) +- Improve notification query performance by reducing db calls [`#2470`](https://github.com/Human-Connection/Human-Connection/pull/2470) +- Fix `Cannot read 'Post' of undefined` [`#2481`](https://github.com/Human-Connection/Human-Connection/pull/2481) +- Hope to fix our deployment with explicit call of `bash` [`#2480`](https://github.com/Human-Connection/Human-Connection/pull/2480) +- Revert layout changes image aspect ratio [`#2467`](https://github.com/Human-Connection/Human-Connection/pull/2467) +- Quick fix for null pointer error in User.vue [`#2472`](https://github.com/Human-Connection/Human-Connection/pull/2472) +- Checkbox 'no comercial + no political account' add to creat user account [`#2416`](https://github.com/Human-Connection/Human-Connection/pull/2416) +- Remove data-test attriubutes in non-dev env [`#2421`](https://github.com/Human-Connection/Human-Connection/pull/2421) +- build(deps-dev): bump @babel/preset-env from 7.7.4 to 7.7.6 [`#2452`](https://github.com/Human-Connection/Human-Connection/pull/2452) +- build(deps-dev): bump @babel/preset-env from 7.7.4 to 7.7.6 in /backend [`#2455`](https://github.com/Human-Connection/Human-Connection/pull/2455) +- build(deps-dev): bump @babel/cli from 7.7.4 to 7.7.5 in /backend [`#2458`](https://github.com/Human-Connection/Human-Connection/pull/2458) +- build(deps): bump @sentry/node from 5.10.1 to 5.10.2 in /backend [`#2473`](https://github.com/Human-Connection/Human-Connection/pull/2473) +- build(deps-dev): bump eslint-plugin-import from 2.18.2 to 2.19.1 in /backend [`#2474`](https://github.com/Human-Connection/Human-Connection/pull/2474) +- build(deps-dev): bump css-loader from 3.2.1 to 3.3.0 in /webapp [`#2475`](https://github.com/Human-Connection/Human-Connection/pull/2475) +- build(deps-dev): bump eslint-plugin-import from 2.18.2 to 2.19.1 in /webapp [`#2477`](https://github.com/Human-Connection/Human-Connection/pull/2477) +- Fix #2237, Comments 4 times as long before "show more" [`#2443`](https://github.com/Human-Connection/Human-Connection/pull/2443) +- Get rid of inconsistency with neode setup [`#2404`](https://github.com/Human-Connection/Human-Connection/pull/2404) +- Bump styleguide to version 0.5.22 [`#2468`](https://github.com/Human-Connection/Human-Connection/pull/2468) +- build(deps): bump nodemailer from 6.4.0 to 6.4.1 in /backend [`#2456`](https://github.com/Human-Connection/Human-Connection/pull/2456) +- build(deps-dev): bump eslint-loader from 3.0.2 to 3.0.3 in /webapp [`#2459`](https://github.com/Human-Connection/Human-Connection/pull/2459) +- build(deps-dev): bump @babel/core from 7.7.4 to 7.7.5 in /backend [`#2460`](https://github.com/Human-Connection/Human-Connection/pull/2460) +- build(deps-dev): bump @babel/core from 7.7.4 to 7.7.5 in /webapp [`#2461`](https://github.com/Human-Connection/Human-Connection/pull/2461) +- build(deps-dev): bump @babel/preset-env from 7.7.4 to 7.7.6 in /webapp [`#2463`](https://github.com/Human-Connection/Human-Connection/pull/2463) +- build(deps-dev): bump async-validator from 3.2.2 to 3.2.3 in /webapp [`#2464`](https://github.com/Human-Connection/Human-Connection/pull/2464) +- build(deps): bump styleguide from `808b3c5` to `7ef8340` [`#2465`](https://github.com/Human-Connection/Human-Connection/pull/2465) +- Paginate moderations page without losing filtering [`#2466`](https://github.com/Human-Connection/Human-Connection/pull/2466) +- Update it.json [`#2451`](https://github.com/Human-Connection/Human-Connection/pull/2451) +- build(deps): bump metascraper from 5.8.8 to 5.8.9 in /backend [`#2304`](https://github.com/Human-Connection/Human-Connection/pull/2304) +- build(deps): bump metascraper-video from 5.8.7 to 5.8.9 in /backend [`#2303`](https://github.com/Human-Connection/Human-Connection/pull/2303) +- build(deps): bump neo4j-graphql-js from 2.9.3 to 2.10.0 in /backend [`#2440`](https://github.com/Human-Connection/Human-Connection/pull/2440) +- Hide Donations Bar [`#2422`](https://github.com/Human-Connection/Human-Connection/pull/2422) +- build(deps): bump @sentry/node from 5.10.0 to 5.10.1 in /backend [`#2436`](https://github.com/Human-Connection/Human-Connection/pull/2436) +- build(deps-dev): bump cypress-cucumber-preprocessor from 1.17.0 to 1.18.0 [`#2437`](https://github.com/Human-Connection/Human-Connection/pull/2437) +- build(deps-dev): bump apollo-server-testing from 2.9.12 to 2.9.13 in /backend [`#2439`](https://github.com/Human-Connection/Human-Connection/pull/2439) +- build(deps): bump apollo-server from 2.9.12 to 2.9.13 in /backend [`#2441`](https://github.com/Human-Connection/Human-Connection/pull/2441) +- Eliminate database calls for reports query [`#2435`](https://github.com/Human-Connection/Human-Connection/pull/2435) +- Use babel-loader with vue-svg-loader [`#2430`](https://github.com/Human-Connection/Human-Connection/pull/2430) +- Remove disable from reports.disable Query [`#2432`](https://github.com/Human-Connection/Human-Connection/pull/2432) +- 2253 fix scroll layout issue [`#2317`](https://github.com/Human-Connection/Human-Connection/pull/2317) +- Update test description [`#2424`](https://github.com/Human-Connection/Human-Connection/pull/2424) +- Update yarn.lock after pulling in latest changes [`#2419`](https://github.com/Human-Connection/Human-Connection/pull/2419) +- Update privacy path [`#2417`](https://github.com/Human-Connection/Human-Connection/pull/2417) +- Add browserstack logo to attributions [`#2431`](https://github.com/Human-Connection/Human-Connection/pull/2431) +- build(deps): bump @sentry/node from 5.9.0 to 5.10.0 in /backend [`#2428`](https://github.com/Human-Connection/Human-Connection/pull/2428) +- build(deps): bump nodemailer from 6.3.1 to 6.4.0 in /backend [`#2427`](https://github.com/Human-Connection/Human-Connection/pull/2427) +- List and protocol moderation [`#1954`](https://github.com/Human-Connection/Human-Connection/pull/1954) +- fix: Re-enable webfinger feature [`#2335`](https://github.com/Human-Connection/Human-Connection/pull/2335) +- Close neo4j driver sessions [`#2402`](https://github.com/Human-Connection/Human-Connection/pull/2402) +- feat: swap user name<=>handle for discriminability [`#2385`](https://github.com/Human-Connection/Human-Connection/pull/2385) +- build(deps-dev): bump @storybook/vue from 5.2.6 to 5.2.8 in /webapp [`#2397`](https://github.com/Human-Connection/Human-Connection/pull/2397) +- build(deps-dev): bump @storybook/addon-actions from 5.2.6 to 5.2.8 in /webapp [`#2398`](https://github.com/Human-Connection/Human-Connection/pull/2398) +- Fix German translation of "Shouts" [`#2400`](https://github.com/Human-Connection/Human-Connection/pull/2400) +- build(deps): bump tiptap-extensions from 1.28.4 to 1.28.5 in /webapp [`#2407`](https://github.com/Human-Connection/Human-Connection/pull/2407) +- build(deps-dev): bump @storybook/addon-a11y from 5.2.7 to 5.2.8 in /webapp [`#2406`](https://github.com/Human-Connection/Human-Connection/pull/2406) +- build(deps-dev): bump css-loader from 3.2.0 to 3.2.1 in /webapp [`#2405`](https://github.com/Human-Connection/Human-Connection/pull/2405) +- build(deps-dev): bump @storybook/addon-notes from 5.2.6 to 5.2.8 in /webapp [`#2399`](https://github.com/Human-Connection/Human-Connection/pull/2399) +- build(deps-dev): bump eslint from 6.7.1 to 6.7.2 in /webapp [`#2393`](https://github.com/Human-Connection/Human-Connection/pull/2393) +- build(deps-dev): bump @vue/cli-shared-utils from 4.0.5 to 4.1.1 in /webapp [`#2374`](https://github.com/Human-Connection/Human-Connection/pull/2374) +- build(deps-dev): bump eslint-plugin-jest from 23.0.5 to 23.1.1 in /webapp [`#2392`](https://github.com/Human-Connection/Human-Connection/pull/2392) +- Terms of use extended with dot - no commercial use [`#2316`](https://github.com/Human-Connection/Human-Connection/pull/2316) +- build(deps-dev): bump cypress-cucumber-preprocessor from 1.16.2 to 1.17.0 [`#2389`](https://github.com/Human-Connection/Human-Connection/pull/2389) +- Lokalise: Translations update [`#2380`](https://github.com/Human-Connection/Human-Connection/pull/2380) +- build(deps-dev): bump @storybook/addon-a11y from 5.2.6 to 5.2.7 in /webapp [`#2391`](https://github.com/Human-Connection/Human-Connection/pull/2391) +- build(deps-dev): bump eslint-plugin-jest from 23.0.5 to 23.1.1 in /backend [`#2390`](https://github.com/Human-Connection/Human-Connection/pull/2390) +- build(deps-dev): bump eslint from 6.7.1 to 6.7.2 in /backend [`#2388`](https://github.com/Human-Connection/Human-Connection/pull/2388) +- build(deps-dev): bump @vue/server-test-utils from 1.0.0-beta.29 to 1.0.0-beta.30 in /webapp [`#2379`](https://github.com/Human-Connection/Human-Connection/pull/2379) +- build(deps): bump neo4j from 3.5.12-enterprise to 3.5.13-enterprise in /neo4j [`#2377`](https://github.com/Human-Connection/Human-Connection/pull/2377) +- build(deps-dev): bump @babel/cli from 7.7.0 to 7.7.4 in /backend [`#2366`](https://github.com/Human-Connection/Human-Connection/pull/2366) +- build(deps-dev): bump cypress-plugin-retries from 1.4.0 to 1.5.0 [`#2360`](https://github.com/Human-Connection/Human-Connection/pull/2360) +- No public registration in development so that backend test pass [`#2382`](https://github.com/Human-Connection/Human-Connection/pull/2382) +- Don't remove sub-addresses in emails [`#2375`](https://github.com/Human-Connection/Human-Connection/pull/2375) +- refactor: Remove obsolete code about invitation codes [`#2333`](https://github.com/Human-Connection/Human-Connection/pull/2333) +- build(deps): bump @nuxtjs/apollo from 4.0.0-rc17 to 4.0.0-rc18 in /webapp [`#2373`](https://github.com/Human-Connection/Human-Connection/pull/2373) +- build(deps): bump graphql-shield from 7.0.2 to 7.0.4 in /backend [`#2372`](https://github.com/Human-Connection/Human-Connection/pull/2372) +- build(deps-dev): bump cypress from 3.6.1 to 3.7.0 [`#2371`](https://github.com/Human-Connection/Human-Connection/pull/2371) +- build(deps-dev): bump @babel/core from 7.7.2 to 7.7.4 in /backend [`#2359`](https://github.com/Human-Connection/Human-Connection/pull/2359) +- build(deps): bump apollo-server from 2.9.11 to 2.9.12 in /backend [`#2357`](https://github.com/Human-Connection/Human-Connection/pull/2357) +- build(deps-dev): bump eslint-plugin-jest from 23.0.4 to 23.0.5 in /webapp [`#2369`](https://github.com/Human-Connection/Human-Connection/pull/2369) +- build(deps): bump @hapi/joi from 16.1.7 to 16.1.8 in /backend [`#2368`](https://github.com/Human-Connection/Human-Connection/pull/2368) +- build(deps-dev): bump eslint-plugin-jest from 23.0.4 to 23.0.5 in /backend [`#2365`](https://github.com/Human-Connection/Human-Connection/pull/2365) +- build(deps-dev): bump @babel/plugin-proposal-throw-expressions from 7.2.0 to 7.7.4 in /backend [`#2339`](https://github.com/Human-Connection/Human-Connection/pull/2339) +- refactor: Close session in isAuthor permission [`#2334`](https://github.com/Human-Connection/Human-Connection/pull/2334) +- build(deps): bump date-fns from 2.7.0 to 2.8.1 in /webapp [`#2323`](https://github.com/Human-Connection/Human-Connection/pull/2323) +- 1967 component tests content view [`#2169`](https://github.com/Human-Connection/Human-Connection/pull/2169) +- If an admin searches for a user by email, don't crash if no user can be found [`#2295`](https://github.com/Human-Connection/Human-Connection/pull/2295) +- Migrate styleguide icons [`#2288`](https://github.com/Human-Connection/Human-Connection/pull/2288) +- build(deps-dev): bump eslint from 6.6.0 to 6.7.1 in /backend [`#2358`](https://github.com/Human-Connection/Human-Connection/pull/2358) +- build(deps-dev): bump @babel/preset-env from 7.7.1 to 7.7.4 in /backend [`#2341`](https://github.com/Human-Connection/Human-Connection/pull/2341) +- build(deps-dev): bump @babel/core from 7.7.2 to 7.7.4 in /webapp [`#2340`](https://github.com/Human-Connection/Human-Connection/pull/2340) +- build(deps): bump date-fns from 2.7.0 to 2.8.1 in /backend [`#2322`](https://github.com/Human-Connection/Human-Connection/pull/2322) +- build(deps): bump validator from 12.0.0 to 12.1.0 in /webapp [`#2319`](https://github.com/Human-Connection/Human-Connection/pull/2319) +- Update to version 0.1.11 with bug fixes [`#2354`](https://github.com/Human-Connection/Human-Connection/pull/2354) - Fix updating post by adding/changing image bug submits form [`#2350`](https://github.com/Human-Connection/Human-Connection/pull/2350) - Add shoutedBy_some to _PostFilter [`#2353`](https://github.com/Human-Connection/Human-Connection/pull/2353) - build(deps-dev): bump date-fns from 2.8.0 to 2.8.1 [`#2342`](https://github.com/Human-Connection/Human-Connection/pull/2342) @@ -71,7 +163,9 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). - build(deps-dev): bump eslint from 5.16.0 to 6.6.0 in /webapp [`#2205`](https://github.com/Human-Connection/Human-Connection/pull/2205) - Add locale to undefined to null [`#2233`](https://github.com/Human-Connection/Human-Connection/pull/2233) - Update to version 0.1.10 [`#2231`](https://github.com/Human-Connection/Human-Connection/pull/2231) +- Merge pull request #2443 from Human-Connection/2237-longer-comments [`#2237`](https://github.com/Human-Connection/Human-Connection/issues/2237) - fix #2329: Normalize email on login in the backend [`#2329`](https://github.com/Human-Connection/Human-Connection/issues/2329) +- Fix #2294 [`#2294`](https://github.com/Human-Connection/Human-Connection/issues/2294) - Merge pull request #2078 from Human-Connection/fix-2042-back-link [`#2042`](https://github.com/Human-Connection/Human-Connection/issues/2042) - Tell github-linguists to ignore snapshots [`978347b`](https://github.com/Human-Connection/Human-Connection/commit/978347ba7b5a6aa1bc915ada972ffffa2816d37c) - Lokalise: update of webapp/locales/ru.json [`906e851`](https://github.com/Human-Connection/Human-Connection/commit/906e8518bf060134150187fb1574ac50ffd502f6) @@ -135,8 +229,8 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). - Update feature template [`#2116`](https://github.com/Human-Connection/Human-Connection/pull/2116) - Update to version 0.1.9 [`#2114`](https://github.com/Human-Connection/Human-Connection/pull/2114) - remove package-lock.json [`3cf3c31`](https://github.com/Human-Connection/Human-Connection/commit/3cf3c31808dc6ae59fb9c6ec33e9e178c5556438) -- add current file [`26c0d4d`](https://github.com/Human-Connection/Human-Connection/commit/26c0d4d83e4418a2378e05b66b6b47461f82735f) -- Finish portuguese translations [`15c671c`](https://github.com/Human-Connection/Human-Connection/commit/15c671c4a8aae86317896ca30601389504bce9e1) +- Extract AvatarMenu into its own component [`994a0b0`](https://github.com/Human-Connection/Human-Connection/commit/994a0b049d1803784d9c06383872f1c9e33095a0) +- Add notifications page with Notifications in table [`7cdc12f`](https://github.com/Human-Connection/Human-Connection/commit/7cdc12f4b9943062e15a874dd39f8a50142b6c61) #### [v0.1.9](https://github.com/Human-Connection/Human-Connection/compare/v0.1.8...v0.1.9) @@ -200,9 +294,9 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). - Fix #2042 Back Link To Login Page [`#2042`](https://github.com/Human-Connection/Human-Connection/issues/2042) - Merge pull request #2043 from Human-Connection/fix-1993 [`#1993`](https://github.com/Human-Connection/Human-Connection/issues/1993) - fix #1993 [`#1993`](https://github.com/Human-Connection/Human-Connection/issues/1993) +- Prepare backend for next implementation step [`7b32243`](https://github.com/Human-Connection/Human-Connection/commit/7b3224327e67a2895e4bc15b8987b13c6f57f015) - first implementation [`aeae72f`](https://github.com/Human-Connection/Human-Connection/commit/aeae72f6918861aa2a4c64d0b32c847d9e857e93) - build(deps-dev): bump eslint-plugin-jest in /backend [`6c1bd53`](https://github.com/Human-Connection/Human-Connection/commit/6c1bd535ac482eb0a05d21e227a476800717a19e) -- add migration plan to webapp readme [`8816f7b`](https://github.com/Human-Connection/Human-Connection/commit/8816f7be2a9662bc1333e37b306dee6b964fc2e0) #### [v0.1.8](https://github.com/Human-Connection/Human-Connection/compare/0.1.7...v0.1.8) @@ -224,7 +318,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). - Update to version 0.1.7 [`#2015`](https://github.com/Human-Connection/Human-Connection/pull/2015) - Update to version 0.1.8 [`d45264b`](https://github.com/Human-Connection/Human-Connection/commit/d45264b3afa1557c2205e7ca1b77c778ee37ab5a) - build(deps): bump @nuxtjs/apollo in /webapp [`26c21b5`](https://github.com/Human-Connection/Human-Connection/commit/26c21b5b76c96206d98ff6bbfdbd1ca973ffcd4f) -- build(deps-dev): bump @storybook/addon-actions in /webapp [`7e95d37`](https://github.com/Human-Connection/Human-Connection/commit/7e95d376a311a5ede6351d577d30e25aea9cb65d) +- Finish redesign of moderators report list [`15d28aa`](https://github.com/Human-Connection/Human-Connection/commit/15d28aa8ef84788aa640aac67838380bfacf63b7) #### [0.1.7](https://github.com/Human-Connection/Human-Connection/compare/0.1.6...0.1.7) diff --git a/VERSION b/VERSION index 20f49513e..0e24a92ff 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.1.11 +0.1.12 diff --git a/backend/package.json b/backend/package.json index d1045a577..21b5587d5 100644 --- a/backend/package.json +++ b/backend/package.json @@ -33,7 +33,7 @@ }, "dependencies": { "@hapi/joi": "^16.1.8", - "@sentry/node": "^5.10.1", + "@sentry/node": "^5.10.2", "apollo-cache-inmemory": "~1.6.3", "apollo-client": "~2.6.4", "apollo-link-context": "~1.0.19", @@ -81,10 +81,10 @@ "minimatch": "^3.0.4", "mustache": "^3.1.0", "neo4j-driver": "~1.7.6", - "neo4j-graphql-js": "^2.10.0", + "neo4j-graphql-js": "^2.10.1", "neode": "^0.3.3", "node-fetch": "~2.6.0", - "nodemailer": "^6.4.1", + "nodemailer": "^6.4.2", "nodemailer-html-to-text": "^3.1.0", "npm-run-all": "~4.1.5", "request": "~2.88.0", @@ -97,11 +97,11 @@ "xregexp": "^4.2.4" }, "devDependencies": { - "@babel/cli": "~7.7.4", + "@babel/cli": "~7.7.5", "@babel/core": "~7.7.5", "@babel/node": "~7.7.4", "@babel/plugin-proposal-throw-expressions": "^7.7.4", - "@babel/preset-env": "~7.7.4", + "@babel/preset-env": "~7.7.6", "@babel/register": "~7.7.0", "apollo-server-testing": "~2.9.13", "babel-core": "~7.0.0-0", @@ -112,14 +112,14 @@ "eslint": "~6.7.2", "eslint-config-prettier": "~6.7.0", "eslint-config-standard": "~14.1.0", - "eslint-plugin-import": "~2.18.2", + "eslint-plugin-import": "~2.19.1", "eslint-plugin-jest": "~23.1.1", "eslint-plugin-node": "~10.0.0", "eslint-plugin-prettier": "~3.1.1", "eslint-plugin-promise": "~4.2.1", "eslint-plugin-standard": "~4.0.1", "jest": "~24.9.0", - "nodemon": "~2.0.1", + "nodemon": "~2.0.2", "prettier": "~1.19.1", "supertest": "~4.0.2" } diff --git a/backend/src/bootstrap/neo4j.js b/backend/src/bootstrap/neo4j.js index f9e3a997d..404e8a2c0 100644 --- a/backend/src/bootstrap/neo4j.js +++ b/backend/src/bootstrap/neo4j.js @@ -1,15 +1,17 @@ import { v1 as neo4j } from 'neo4j-driver' import CONFIG from './../config' -import setupNeode from './neode' +import Neode from 'neode' +import models from '../models' let driver +const defaultOptions = { + uri: CONFIG.NEO4J_URI, + username: CONFIG.NEO4J_USERNAME, + password: CONFIG.NEO4J_PASSWORD, +} export function getDriver(options = {}) { - const { - uri = CONFIG.NEO4J_URI, - username = CONFIG.NEO4J_USERNAME, - password = CONFIG.NEO4J_PASSWORD, - } = options + const { uri, username, password } = { ...defaultOptions, ...options } if (!driver) { driver = neo4j.driver(uri, neo4j.auth.basic(username, password)) } @@ -17,10 +19,11 @@ export function getDriver(options = {}) { } let neodeInstance -export function neode() { +export function getNeode(options = {}) { if (!neodeInstance) { - const { NEO4J_URI: uri, NEO4J_USERNAME: username, NEO4J_PASSWORD: password } = CONFIG - neodeInstance = setupNeode({ uri, username, password }) + const { uri, username, password } = { ...defaultOptions, ...options } + neodeInstance = new Neode(uri, username, password).with(models) + return neodeInstance } return neodeInstance } diff --git a/backend/src/bootstrap/neode.js b/backend/src/bootstrap/neode.js deleted file mode 100644 index 65a2074be..000000000 --- a/backend/src/bootstrap/neode.js +++ /dev/null @@ -1,9 +0,0 @@ -import Neode from 'neode' -import models from '../models' - -export default function setupNeode(options) { - const { uri, username, password } = options - const neodeInstance = new Neode(uri, username, password) - neodeInstance.with(models) - return neodeInstance -} diff --git a/backend/src/jwt/decode.spec.js b/backend/src/jwt/decode.spec.js index 9ea858304..7aa703d97 100644 --- a/backend/src/jwt/decode.spec.js +++ b/backend/src/jwt/decode.spec.js @@ -1,5 +1,5 @@ import Factory from '../seed/factories/index' -import { getDriver, neode as getNeode } from '../bootstrap/neo4j' +import { getDriver, getNeode } from '../bootstrap/neo4j' import decode from './decode' const factory = Factory() diff --git a/backend/src/middleware/hashtags/hashtagsMiddleware.spec.js b/backend/src/middleware/hashtags/hashtagsMiddleware.spec.js index 6e97f34c4..0fa1e2dc5 100644 --- a/backend/src/middleware/hashtags/hashtagsMiddleware.spec.js +++ b/backend/src/middleware/hashtags/hashtagsMiddleware.spec.js @@ -1,7 +1,7 @@ import { gql } from '../../helpers/jest' import Factory from '../../seed/factories' import { createTestClient } from 'apollo-server-testing' -import { neode, getDriver } from '../../bootstrap/neo4j' +import { getNeode, getDriver } from '../../bootstrap/neo4j' import createServer from '../../server' let server @@ -11,7 +11,7 @@ let hashtagingUser let authenticatedUser const factory = Factory() const driver = getDriver() -const instance = neode() +const neode = getNeode() const categoryIds = ['cat9'] const createPostMutation = gql` mutation($id: ID, $title: String!, $postContent: String!, $categoryIds: [ID]!) { @@ -36,7 +36,7 @@ beforeAll(() => { context: () => { return { user: authenticatedUser, - neode: instance, + neode, driver, } }, @@ -48,14 +48,14 @@ beforeAll(() => { }) beforeEach(async () => { - hashtagingUser = await instance.create('User', { + hashtagingUser = await neode.create('User', { id: 'you', name: 'Al Capone', slug: 'al-capone', email: 'test@example.org', password: '1234', }) - await instance.create('Category', { + await neode.create('Category', { id: 'cat9', name: 'Democracy & Politics', icon: 'university', diff --git a/backend/src/middleware/notifications/notificationsMiddleware.spec.js b/backend/src/middleware/notifications/notificationsMiddleware.spec.js index 2122d009b..53fa80ce8 100644 --- a/backend/src/middleware/notifications/notificationsMiddleware.spec.js +++ b/backend/src/middleware/notifications/notificationsMiddleware.spec.js @@ -1,7 +1,7 @@ import { gql } from '../../helpers/jest' import Factory from '../../seed/factories' import { createTestClient } from 'apollo-server-testing' -import { neode, getDriver } from '../../bootstrap/neo4j' +import { getNeode, getDriver } from '../../bootstrap/neo4j' import createServer from '../../server' let server @@ -11,7 +11,7 @@ let notifiedUser let authenticatedUser const factory = Factory() const driver = getDriver() -const instance = neode() +const neode = getNeode() const categoryIds = ['cat9'] const createPostMutation = gql` mutation($id: ID, $title: String!, $postContent: String!, $categoryIds: [ID]!) { @@ -44,7 +44,7 @@ beforeAll(() => { context: () => { return { user: authenticatedUser, - neode: instance, + neode: neode, driver, } }, @@ -56,14 +56,14 @@ beforeAll(() => { }) beforeEach(async () => { - notifiedUser = await instance.create('User', { + notifiedUser = await neode.create('User', { id: 'you', name: 'Al Capone', slug: 'al-capone', email: 'test@example.org', password: '1234', }) - await instance.create('Category', { + await neode.create('Category', { id: 'cat9', name: 'Democracy & Politics', icon: 'university', @@ -146,7 +146,7 @@ describe('notifications', () => { describe('commenter is not me', () => { beforeEach(async () => { commentContent = 'Commenters comment.' - commentAuthor = await instance.create('User', { + commentAuthor = await neode.create('User', { id: 'commentAuthor', name: 'Mrs Comment', slug: 'mrs-comment', @@ -228,7 +228,7 @@ describe('notifications', () => { }) beforeEach(async () => { - postAuthor = await instance.create('User', { + postAuthor = await neode.create('User', { id: 'postAuthor', name: 'Mrs Post', slug: 'mrs-post', @@ -432,7 +432,7 @@ describe('notifications', () => { beforeEach(async () => { commentContent = 'One mention about me with @al-capone.' - commentAuthor = await instance.create('User', { + commentAuthor = await neode.create('User', { id: 'commentAuthor', name: 'Mrs Comment', slug: 'mrs-comment', @@ -442,7 +442,7 @@ describe('notifications', () => { }) it('sends only one notification with reason mentioned_in_comment', async () => { - postAuthor = await instance.create('User', { + postAuthor = await neode.create('User', { id: 'MrPostAuthor', name: 'Mr Author', slug: 'mr-author', @@ -518,7 +518,7 @@ describe('notifications', () => { await postAuthor.relateTo(notifiedUser, 'blocked') commentContent = 'One mention about me with @al-capone.' - commentAuthor = await instance.create('User', { + commentAuthor = await neode.create('User', { id: 'commentAuthor', name: 'Mrs Comment', slug: 'mrs-comment', diff --git a/backend/src/middleware/orderByMiddleware.spec.js b/backend/src/middleware/orderByMiddleware.spec.js index a7b31da0a..129f3a8b4 100644 --- a/backend/src/middleware/orderByMiddleware.spec.js +++ b/backend/src/middleware/orderByMiddleware.spec.js @@ -1,6 +1,6 @@ import { gql } from '../helpers/jest' import Factory from '../seed/factories' -import { neode as getNeode, getDriver } from '../bootstrap/neo4j' +import { getNeode, getDriver } from '../bootstrap/neo4j' import { createTestClient } from 'apollo-server-testing' import createServer from '../server' diff --git a/backend/src/middleware/permissionsMiddleware.js b/backend/src/middleware/permissionsMiddleware.js index 57f6c7d0c..18f7c7c2f 100644 --- a/backend/src/middleware/permissionsMiddleware.js +++ b/backend/src/middleware/permissionsMiddleware.js @@ -1,11 +1,11 @@ import { rule, shield, deny, allow, or } from 'graphql-shield' -import { neode } from '../bootstrap/neo4j' +import { getNeode } from '../bootstrap/neo4j' import CONFIG from '../config' const debug = !!CONFIG.DEBUG const allowExternalErrors = true -const instance = neode() +const neode = getNeode() const isAuthenticated = rule({ cache: 'contextual', @@ -36,7 +36,7 @@ const isMyOwn = rule({ const isMySocialMedia = rule({ cache: 'no_cache', })(async (_, args, { user }) => { - let socialMedia = await instance.find('SocialMedia', args.id) + let socialMedia = await neode.find('SocialMedia', args.id) socialMedia = await socialMedia.toJson() return socialMedia.ownedBy.node.id === user.id }) diff --git a/backend/src/middleware/permissionsMiddleware.spec.js b/backend/src/middleware/permissionsMiddleware.spec.js index 340766136..60aff961d 100644 --- a/backend/src/middleware/permissionsMiddleware.spec.js +++ b/backend/src/middleware/permissionsMiddleware.spec.js @@ -2,7 +2,7 @@ import { createTestClient } from 'apollo-server-testing' import createServer from '../server' import Factory from '../seed/factories' import { gql } from '../helpers/jest' -import { getDriver, neode as getNeode } from '../bootstrap/neo4j' +import { getDriver, getNeode } from '../bootstrap/neo4j' const factory = Factory() const instance = getNeode() diff --git a/backend/src/middleware/slugifyMiddleware.spec.js b/backend/src/middleware/slugifyMiddleware.spec.js index 02699f7b2..1c2e59317 100644 --- a/backend/src/middleware/slugifyMiddleware.spec.js +++ b/backend/src/middleware/slugifyMiddleware.spec.js @@ -1,6 +1,6 @@ import Factory from '../seed/factories' import { gql } from '../helpers/jest' -import { neode as getNeode, getDriver } from '../bootstrap/neo4j' +import { getNeode, getDriver } from '../bootstrap/neo4j' import createServer from '../server' import { createTestClient } from 'apollo-server-testing' diff --git a/backend/src/middleware/softDelete/softDeleteMiddleware.spec.js b/backend/src/middleware/softDelete/softDeleteMiddleware.spec.js index 1c97cb874..b7c16dfd3 100644 --- a/backend/src/middleware/softDelete/softDeleteMiddleware.spec.js +++ b/backend/src/middleware/softDelete/softDeleteMiddleware.spec.js @@ -1,6 +1,6 @@ import Factory from '../../seed/factories' import { gql } from '../../helpers/jest' -import { neode as getNeode, getDriver } from '../../bootstrap/neo4j' +import { getNeode, getDriver } from '../../bootstrap/neo4j' import createServer from '../../server' import { createTestClient } from 'apollo-server-testing' diff --git a/backend/src/middleware/validation/validationMiddleware.spec.js b/backend/src/middleware/validation/validationMiddleware.spec.js index 97bb6254b..c3d0512ad 100644 --- a/backend/src/middleware/validation/validationMiddleware.spec.js +++ b/backend/src/middleware/validation/validationMiddleware.spec.js @@ -1,6 +1,6 @@ import { gql } from '../../helpers/jest' import Factory from '../../seed/factories' -import { neode as getNeode, getDriver } from '../../bootstrap/neo4j' +import { getNeode, getDriver } from '../../bootstrap/neo4j' import { createTestClient } from 'apollo-server-testing' import createServer from '../../server' diff --git a/backend/src/models/User.spec.js b/backend/src/models/User.spec.js index 7c4a26c55..332e6a3ea 100644 --- a/backend/src/models/User.spec.js +++ b/backend/src/models/User.spec.js @@ -1,8 +1,8 @@ import Factory from '../seed/factories' -import { neode } from '../bootstrap/neo4j' +import { getNeode } from '../bootstrap/neo4j' const factory = Factory() -const instance = neode() +const neode = getNeode() afterEach(async () => { await factory.cleanDatabase() @@ -10,7 +10,7 @@ afterEach(async () => { describe('role', () => { it('defaults to `user`', async () => { - const user = await instance.create('User', { name: 'John' }) + const user = await neode.create('User', { name: 'John' }) await expect(user.toJson()).resolves.toEqual( expect.objectContaining({ role: 'user', @@ -21,7 +21,7 @@ describe('role', () => { describe('slug', () => { it('normalizes to lowercase letters', async () => { - const user = await instance.create('User', { slug: 'Matt' }) + const user = await neode.create('User', { slug: 'Matt' }) await expect(user.toJson()).resolves.toEqual( expect.objectContaining({ slug: 'matt', @@ -30,9 +30,9 @@ describe('slug', () => { }) it('must be unique', async done => { - await instance.create('User', { slug: 'Matt' }) + await neode.create('User', { slug: 'Matt' }) try { - await expect(instance.create('User', { slug: 'Matt' })).rejects.toThrow('already exists') + await expect(neode.create('User', { slug: 'Matt' })).rejects.toThrow('already exists') done() } catch (error) { throw new Error(` @@ -54,7 +54,7 @@ describe('slug', () => { describe('characters', () => { const createUser = attrs => { - return instance.create('User', attrs).then(user => user.toJson()) + return neode.create('User', attrs).then(user => user.toJson()) } it('-', async () => { diff --git a/backend/src/schema/resolvers/comments.spec.js b/backend/src/schema/resolvers/comments.spec.js index d2692aa8a..e2d20d1bd 100644 --- a/backend/src/schema/resolvers/comments.spec.js +++ b/backend/src/schema/resolvers/comments.spec.js @@ -2,7 +2,7 @@ import Factory from '../../seed/factories' import { gql } from '../../helpers/jest' import { createTestClient } from 'apollo-server-testing' import createServer from '../../server' -import { neode as getNeode, getDriver } from '../../bootstrap/neo4j' +import { getNeode, getDriver } from '../../bootstrap/neo4j' const driver = getDriver() const neode = getNeode() diff --git a/backend/src/schema/resolvers/donations.spec.js b/backend/src/schema/resolvers/donations.spec.js index 9e701059d..d8dd5db06 100644 --- a/backend/src/schema/resolvers/donations.spec.js +++ b/backend/src/schema/resolvers/donations.spec.js @@ -1,7 +1,7 @@ import { createTestClient } from 'apollo-server-testing' import Factory from '../../seed/factories' import { gql } from '../../helpers/jest' -import { neode as getNeode, getDriver } from '../../bootstrap/neo4j' +import { getNeode, getDriver } from '../../bootstrap/neo4j' import createServer from '../../server' let mutate, query, authenticatedUser, variables diff --git a/backend/src/schema/resolvers/emails.spec.js b/backend/src/schema/resolvers/emails.spec.js index 156007435..82ce43337 100644 --- a/backend/src/schema/resolvers/emails.spec.js +++ b/backend/src/schema/resolvers/emails.spec.js @@ -1,6 +1,6 @@ import Factory from '../../seed/factories' import { gql } from '../../helpers/jest' -import { getDriver, neode as getNeode } from '../../bootstrap/neo4j' +import { getDriver, getNeode } from '../../bootstrap/neo4j' import createServer from '../../server' import { createTestClient } from 'apollo-server-testing' diff --git a/backend/src/schema/resolvers/follow.js b/backend/src/schema/resolvers/follow.js index ada417cff..0416fe3d2 100644 --- a/backend/src/schema/resolvers/follow.js +++ b/backend/src/schema/resolvers/follow.js @@ -1,4 +1,4 @@ -import { neode as getNeode } from '../../bootstrap/neo4j' +import { getNeode } from '../../bootstrap/neo4j' const neode = getNeode() diff --git a/backend/src/schema/resolvers/follow.spec.js b/backend/src/schema/resolvers/follow.spec.js index 8402842e2..ff884666e 100644 --- a/backend/src/schema/resolvers/follow.spec.js +++ b/backend/src/schema/resolvers/follow.spec.js @@ -1,6 +1,6 @@ import { createTestClient } from 'apollo-server-testing' import Factory from '../../seed/factories' -import { getDriver, neode as getNeode } from '../../bootstrap/neo4j' +import { getDriver, getNeode } from '../../bootstrap/neo4j' import createServer from '../../server' import { gql } from '../../helpers/jest' diff --git a/backend/src/schema/resolvers/helpers/Resolver.js b/backend/src/schema/resolvers/helpers/Resolver.js index 03c0d4176..64ba60f5e 100644 --- a/backend/src/schema/resolvers/helpers/Resolver.js +++ b/backend/src/schema/resolvers/helpers/Resolver.js @@ -1,9 +1,9 @@ -import { neode } from '../../../bootstrap/neo4j' +import log from './databaseLogger' export const undefinedToNullResolver = list => { const resolvers = {} list.forEach(key => { - resolvers[key] = async (parent, params, context, resolveInfo) => { + resolvers[key] = async parent => { return typeof parent[key] === 'undefined' ? null : parent[key] } }) @@ -11,7 +11,6 @@ export const undefinedToNullResolver = list => { } export default function Resolver(type, options = {}) { - const instance = neode() const { idAttribute = 'id', undefinedToNull = [], @@ -22,32 +21,49 @@ export default function Resolver(type, options = {}) { } = options const _hasResolver = (resolvers, { key, connection }, { returnType }) => { - return async (parent, params, context, resolveInfo) => { + return async (parent, params, { driver, cypherParams }, resolveInfo) => { if (typeof parent[key] !== 'undefined') return parent[key] const id = parent[idAttribute] - const statement = `MATCH(:${type} {${idAttribute}: {id}})${connection} RETURN related` - const result = await instance.cypher(statement, { id }) - let response = result.records.map(r => r.get('related').properties) - if (returnType === 'object') response = response[0] || null - return response + const session = driver.session() + const readTxResultPromise = session.readTransaction(async txc => { + const cypher = ` + MATCH(:${type} {${idAttribute}: $id})${connection} + RETURN related {.*} as related + ` + const result = await txc.run(cypher, { id, cypherParams }) + log(result) + return result.records.map(r => r.get('related')) + }) + try { + let response = await readTxResultPromise + if (returnType === 'object') response = response[0] || null + return response + } finally { + session.close() + } } } const booleanResolver = obj => { const resolvers = {} for (const [key, condition] of Object.entries(obj)) { - resolvers[key] = async (parent, params, { cypherParams }, resolveInfo) => { + resolvers[key] = async (parent, params, { cypherParams, driver }, resolveInfo) => { if (typeof parent[key] !== 'undefined') return parent[key] - const result = await instance.cypher( - ` - ${condition.replace('this', 'this {id: $parent.id}')} as ${key}`, - { - parent, - cypherParams, - }, - ) - const [record] = result.records - return record.get(key) + const id = parent[idAttribute] + const session = driver.session() + const readTxResultPromise = session.readTransaction(async txc => { + const nodeCondition = condition.replace('this', 'this {id: $id}') + const cypher = `${nodeCondition} as ${key}` + const result = await txc.run(cypher, { id, cypherParams }) + log(result) + const [response] = result.records.map(r => r.get(key)) + return response + }) + try { + return await readTxResultPromise + } finally { + session.close() + } } } return resolvers @@ -56,16 +72,25 @@ export default function Resolver(type, options = {}) { const countResolver = obj => { const resolvers = {} for (const [key, connection] of Object.entries(obj)) { - resolvers[key] = async (parent, params, context, resolveInfo) => { + resolvers[key] = async (parent, params, { driver, cypherParams }, resolveInfo) => { if (typeof parent[key] !== 'undefined') return parent[key] - const id = parent[idAttribute] - const statement = ` - MATCH(u:${type} {${idAttribute}: {id}})${connection} - RETURN COUNT(DISTINCT(related)) as count - ` - const result = await instance.cypher(statement, { id }) - const [response] = result.records.map(r => r.get('count').toNumber()) - return response + const session = driver.session() + const readTxResultPromise = session.readTransaction(async txc => { + const id = parent[idAttribute] + const cypher = ` + MATCH(u:${type} {${idAttribute}: $id})${connection} + RETURN COUNT(DISTINCT(related)) as count + ` + const result = await txc.run(cypher, { id, cypherParams }) + log(result) + const [response] = result.records.map(r => r.get('count').toNumber()) + return response + }) + try { + return await readTxResultPromise + } finally { + session.close() + } } } return resolvers diff --git a/backend/src/schema/resolvers/helpers/databaseLogger.js b/backend/src/schema/resolvers/helpers/databaseLogger.js new file mode 100644 index 000000000..1e97b4d72 --- /dev/null +++ b/backend/src/schema/resolvers/helpers/databaseLogger.js @@ -0,0 +1,15 @@ +import Debug from 'debug' +const debugCypher = Debug('human-connection:neo4j:cypher') +const debugStats = Debug('human-connection:neo4j:stats') + +export default function log(response) { + const { statement, counters, resultConsumedAfter, resultAvailableAfter } = response.summary + const { text, parameters } = statement + debugCypher('%s', text) + debugCypher('%o', parameters) + debugStats('%o', counters) + debugStats('%o', { + resultConsumedAfter: resultConsumedAfter.toNumber(), + resultAvailableAfter: resultAvailableAfter.toNumber(), + }) +} diff --git a/backend/src/schema/resolvers/locations.spec.js b/backend/src/schema/resolvers/locations.spec.js index 51dafcc2e..f4a846afd 100644 --- a/backend/src/schema/resolvers/locations.spec.js +++ b/backend/src/schema/resolvers/locations.spec.js @@ -1,6 +1,6 @@ import Factory from '../../seed/factories' import { gql } from '../../helpers/jest' -import { neode as getNeode, getDriver } from '../../bootstrap/neo4j' +import { getNeode, getDriver } from '../../bootstrap/neo4j' import createServer from '../../server' import { createTestClient } from 'apollo-server-testing' diff --git a/backend/src/schema/resolvers/moderation.spec.js b/backend/src/schema/resolvers/moderation.spec.js index 5e280a6f5..f76cbdf46 100644 --- a/backend/src/schema/resolvers/moderation.spec.js +++ b/backend/src/schema/resolvers/moderation.spec.js @@ -1,7 +1,7 @@ import { createTestClient } from 'apollo-server-testing' import Factory from '../../seed/factories' import { gql } from '../../helpers/jest' -import { neode as getNeode, getDriver } from '../../bootstrap/neo4j' +import { getNeode, getDriver } from '../../bootstrap/neo4j' import createServer from '../../server' const factory = Factory() diff --git a/backend/src/schema/resolvers/notifications.js b/backend/src/schema/resolvers/notifications.js index 7f9c52e1e..eca12900d 100644 --- a/backend/src/schema/resolvers/notifications.js +++ b/backend/src/schema/resolvers/notifications.js @@ -1,3 +1,5 @@ +import log from './helpers/databaseLogger' + const resourceTypes = ['Post', 'Comment'] const transformReturnType = record => { @@ -42,16 +44,29 @@ export default { } const offset = args.offset && typeof args.offset === 'number' ? `SKIP ${args.offset}` : '' const limit = args.first && typeof args.first === 'number' ? `LIMIT ${args.first}` : '' - const cypher = ` - MATCH (resource {deleted: false, disabled: false})-[notification:NOTIFIED]->(user:User {id:$id}) - ${whereClause} - RETURN resource, notification, user - ${orderByClause} - ${offset} ${limit} - ` + + const readTxResultPromise = session.readTransaction(async transaction => { + const notificationsTransactionResponse = await transaction.run( + ` + MATCH (resource {deleted: false, disabled: false})-[notification:NOTIFIED]->(user:User {id:$id}) + ${whereClause} + WITH user, notification, resource, + [(resource)<-[:WROTE]-(author:User) | author {.*}] as authors, + [(resource)-[:COMMENTS]->(post:Post)<-[:WROTE]-(author:User) | post{.*, author: properties(author)} ] as posts + WITH resource, user, notification, authors, posts, + resource {.*, __typename: labels(resource)[0], author: authors[0], post: posts[0]} as finalResource + RETURN notification {.*, from: finalResource, to: properties(user)} + ${orderByClause} + ${offset} ${limit} + `, + { id: currentUser.id }, + ) + log(notificationsTransactionResponse) + return notificationsTransactionResponse.records.map(record => record.get('notification')) + }) try { - const result = await session.run(cypher, { id: currentUser.id }) - return result.records.map(transformReturnType) + const notifications = await readTxResultPromise + return notifications } finally { session.close() } @@ -68,6 +83,7 @@ export default { RETURN resource, notification, user ` const result = await session.run(cypher, { resourceId: args.id, id: currentUser.id }) + log(result) const notifications = await result.records.map(transformReturnType) return notifications[0] } finally { diff --git a/backend/src/schema/resolvers/notifications.spec.js b/backend/src/schema/resolvers/notifications.spec.js index 24b8280bd..89bbd2528 100644 --- a/backend/src/schema/resolvers/notifications.spec.js +++ b/backend/src/schema/resolvers/notifications.spec.js @@ -184,6 +184,7 @@ describe('given some notifications', () => { data: { notifications: expect.arrayContaining(expected), }, + errors: undefined, }) }) }) @@ -233,7 +234,10 @@ describe('given some notifications', () => { ` await expect( mutate({ mutation: deletePostMutation, variables: { id: 'p3' } }), - ).resolves.toMatchObject({ data: { DeletePost: { id: 'p3', deleted: true } } }) + ).resolves.toMatchObject({ + data: { DeletePost: { id: 'p3', deleted: true } }, + errors: undefined, + }) authenticatedUser = await user.toJson() } @@ -242,11 +246,12 @@ describe('given some notifications', () => { query({ query: notificationQuery, variables: { ...variables, read: false } }), ).resolves.toMatchObject({ data: { notifications: [expect.any(Object), expect.any(Object)] }, + errors: undefined, }) await deletePostAction() await expect( query({ query: notificationQuery, variables: { ...variables, read: false } }), - ).resolves.toMatchObject({ data: { notifications: [] } }) + ).resolves.toMatchObject({ data: { notifications: [] }, errors: undefined }) }) }) }) diff --git a/backend/src/schema/resolvers/passwordReset.spec.js b/backend/src/schema/resolvers/passwordReset.spec.js index 97aa6a020..a1968d288 100644 --- a/backend/src/schema/resolvers/passwordReset.spec.js +++ b/backend/src/schema/resolvers/passwordReset.spec.js @@ -1,6 +1,6 @@ import Factory from '../../seed/factories' import { gql } from '../../helpers/jest' -import { neode as getNeode, getDriver } from '../../bootstrap/neo4j' +import { getNeode, getDriver } from '../../bootstrap/neo4j' import createPasswordReset from './helpers/createPasswordReset' import createServer from '../../server' import { createTestClient } from 'apollo-server-testing' diff --git a/backend/src/schema/resolvers/posts.spec.js b/backend/src/schema/resolvers/posts.spec.js index 98475b182..752602fd9 100644 --- a/backend/src/schema/resolvers/posts.spec.js +++ b/backend/src/schema/resolvers/posts.spec.js @@ -1,7 +1,7 @@ import { createTestClient } from 'apollo-server-testing' import Factory from '../../seed/factories' import { gql } from '../../helpers/jest' -import { neode as getNeode, getDriver } from '../../bootstrap/neo4j' +import { getNeode, getDriver } from '../../bootstrap/neo4j' import createServer from '../../server' const driver = getDriver() diff --git a/backend/src/schema/resolvers/registration.js b/backend/src/schema/resolvers/registration.js index 206c8db74..9d5d5f09a 100644 --- a/backend/src/schema/resolvers/registration.js +++ b/backend/src/schema/resolvers/registration.js @@ -1,12 +1,12 @@ import { UserInputError } from 'apollo-server' -import { neode } from '../../bootstrap/neo4j' +import { getNeode } from '../../bootstrap/neo4j' import fileUpload from './fileUpload' import encryptPassword from '../../helpers/encryptPassword' import generateNonce from './helpers/generateNonce' import existingEmailAddress from './helpers/existingEmailAddress' import normalizeEmail from './helpers/normalizeEmail' -const instance = neode() +const neode = getNeode() export default { Mutation: { @@ -16,7 +16,7 @@ export default { let emailAddress = await existingEmailAddress({ args, context }) if (emailAddress) return emailAddress try { - emailAddress = await instance.create('EmailAddress', args) + emailAddress = await neode.create('EmailAddress', args) return emailAddress.toJson() } catch (e) { throw new UserInputError(e.message) @@ -32,7 +32,7 @@ export default { let { nonce, email } = args email = normalizeEmail(email) - const result = await instance.cypher( + const result = await neode.cypher( ` MATCH(email:EmailAddress {nonce: {nonce}, email: {email}}) WHERE NOT (email)-[:BELONGS_TO]->() @@ -40,12 +40,12 @@ export default { `, { nonce, email }, ) - const emailAddress = await instance.hydrateFirst(result, 'email', instance.model('Email')) + const emailAddress = await neode.hydrateFirst(result, 'email', neode.model('Email')) if (!emailAddress) throw new UserInputError('Invalid email or nonce') args = await fileUpload(args, { file: 'avatarUpload', url: 'avatar' }) args = await encryptPassword(args) try { - const user = await instance.create('User', args) + const user = await neode.create('User', args) await Promise.all([ user.relateTo(emailAddress, 'primaryEmail'), emailAddress.relateTo(user, 'belongsTo'), diff --git a/backend/src/schema/resolvers/registration.spec.js b/backend/src/schema/resolvers/registration.spec.js index 35b16b9bb..8f3a7ac39 100644 --- a/backend/src/schema/resolvers/registration.spec.js +++ b/backend/src/schema/resolvers/registration.spec.js @@ -1,6 +1,6 @@ import Factory from '../../seed/factories' import { gql } from '../../helpers/jest' -import { getDriver, neode as getNeode } from '../../bootstrap/neo4j' +import { getDriver, getNeode } from '../../bootstrap/neo4j' import createServer from '../../server' import { createTestClient } from 'apollo-server-testing' diff --git a/backend/src/schema/resolvers/reports.js b/backend/src/schema/resolvers/reports.js index a1d98bb41..0565c4d8a 100644 --- a/backend/src/schema/resolvers/reports.js +++ b/backend/src/schema/resolvers/reports.js @@ -1,3 +1,5 @@ +import log from './helpers/databaseLogger' + const transformReturnType = record => { return { ...record.get('report').properties, @@ -11,12 +13,11 @@ const transformReturnType = record => { export default { Mutation: { fileReport: async (_parent, params, context, _resolveInfo) => { - let createdRelationshipWithNestedAttributes const { resourceId, reasonCategory, reasonDescription } = params const { driver, user } = context const session = driver.session() - const reportWriteTxResultPromise = session.writeTransaction(async txc => { - const reportTransactionResponse = await txc.run( + const reportWriteTxResultPromise = session.writeTransaction(async transaction => { + const reportTransactionResponse = await transaction.run( ` MATCH (submitter:User {id: $submitterId}) MATCH (resource {id: $resourceId}) @@ -36,23 +37,23 @@ export default { reasonDescription, }, ) + log(reportTransactionResponse) return reportTransactionResponse.records.map(transformReturnType) }) try { - const txResult = await reportWriteTxResultPromise - if (!txResult[0]) return null - createdRelationshipWithNestedAttributes = txResult[0] + const [createdRelationshipWithNestedAttributes] = await reportWriteTxResultPromise + if (!createdRelationshipWithNestedAttributes) return null + return createdRelationshipWithNestedAttributes } finally { session.close() } - return createdRelationshipWithNestedAttributes }, }, Query: { reports: async (_parent, params, context, _resolveInfo) => { const { driver } = context const session = driver.session() - let reports, orderByClause, filterClause + let orderByClause, filterClause switch (params.orderBy) { case 'createdAt_asc': orderByClause = 'ORDER BY report.createdAt ASC' @@ -81,8 +82,8 @@ export default { params.offset && typeof params.offset === 'number' ? `SKIP ${params.offset}` : '' const limit = params.first && typeof params.first === 'number' ? `LIMIT ${params.first}` : '' - const reportReadTxPromise = session.readTransaction(async tx => { - const allReportsTransactionResponse = await tx.run( + const reportReadTxPromise = session.readTransaction(async transaction => { + const allReportsTransactionResponse = await transaction.run( ` MATCH (report:Report)-[:BELONGS_TO]->(resource) WHERE (resource:User OR resource:Post OR resource:Comment) @@ -100,16 +101,15 @@ export default { ${offset} ${limit} `, ) + log(allReportsTransactionResponse) return allReportsTransactionResponse.records.map(record => record.get('report')) }) try { - const txResult = await reportReadTxPromise - if (!txResult[0]) return null - reports = txResult + const reports = await reportReadTxPromise + return reports } finally { session.close() } - return reports }, }, Report: { @@ -118,23 +118,23 @@ export default { const session = context.driver.session() const { id } = parent let filed - const readTxPromise = session.readTransaction(async tx => { - const allReportsTransactionResponse = await tx.run( + const readTxPromise = session.readTransaction(async transaction => { + const filedReportsTransactionResponse = await transaction.run( ` - MATCH (submitter:User)-[filed:FILED]->(report:Report {id: $id}) - RETURN filed, submitter + MATCH (submitter:User)-[filed:FILED]->(report:Report {id: $id}) + RETURN filed, submitter `, { id }, ) - return allReportsTransactionResponse.records.map(record => ({ + log(filedReportsTransactionResponse) + return filedReportsTransactionResponse.records.map(record => ({ submitter: record.get('submitter').properties, filed: record.get('filed').properties, })) }) try { - const txResult = await readTxPromise - if (!txResult[0]) return null - filed = txResult.map(reportedRecord => { + const filedReports = await readTxPromise + filed = filedReports.map(reportedRecord => { const { submitter, filed } = reportedRecord const relationshipWithNestedAttributes = { ...filed, @@ -152,8 +152,8 @@ export default { const session = context.driver.session() const { id } = parent let reviewed - const readTxPromise = session.readTransaction(async tx => { - const allReportsTransactionResponse = await tx.run( + const readTxPromise = session.readTransaction(async transaction => { + const reviewedReportsTransactionResponse = await transaction.run( ` MATCH (resource)<-[:BELONGS_TO]-(report:Report {id: $id})<-[review:REVIEWED]-(moderator:User) RETURN moderator, review @@ -161,14 +161,15 @@ export default { `, { id }, ) - return allReportsTransactionResponse.records.map(record => ({ + log(reviewedReportsTransactionResponse) + return reviewedReportsTransactionResponse.records.map(record => ({ review: record.get('review').properties, moderator: record.get('moderator').properties, })) }) try { - const txResult = await readTxPromise - reviewed = txResult.map(reportedRecord => { + const reviewedReports = await readTxPromise + reviewed = reviewedReports.map(reportedRecord => { const { review, moderator } = reportedRecord const relationshipWithNestedAttributes = { ...review, diff --git a/backend/src/schema/resolvers/reports.spec.js b/backend/src/schema/resolvers/reports.spec.js index c0a9d3afb..8b1bb925d 100644 --- a/backend/src/schema/resolvers/reports.spec.js +++ b/backend/src/schema/resolvers/reports.spec.js @@ -2,7 +2,7 @@ import { createTestClient } from 'apollo-server-testing' import createServer from '../.././server' import Factory from '../../seed/factories' import { gql } from '../../helpers/jest' -import { getDriver, neode as getNeode } from '../../bootstrap/neo4j' +import { getDriver, getNeode } from '../../bootstrap/neo4j' const factory = Factory() const instance = getNeode() @@ -21,7 +21,6 @@ describe('file a report on a resource', () => { id createdAt updatedAt - disable closed rule resource { @@ -489,7 +488,6 @@ describe('file a report on a resource', () => { id createdAt updatedAt - disable closed resource { __typename @@ -624,7 +622,6 @@ describe('file a report on a resource', () => { id: expect.any(String), createdAt: expect.any(String), updatedAt: expect.any(String), - disable: false, closed: false, resource: { __typename: 'User', @@ -645,7 +642,6 @@ describe('file a report on a resource', () => { id: expect.any(String), createdAt: expect.any(String), updatedAt: expect.any(String), - disable: false, closed: false, resource: { __typename: 'Post', @@ -666,7 +662,6 @@ describe('file a report on a resource', () => { id: expect.any(String), createdAt: expect.any(String), updatedAt: expect.any(String), - disable: false, closed: false, resource: { __typename: 'Comment', diff --git a/backend/src/schema/resolvers/rewards.js b/backend/src/schema/resolvers/rewards.js index 74c7860e4..4d5d62aea 100644 --- a/backend/src/schema/resolvers/rewards.js +++ b/backend/src/schema/resolvers/rewards.js @@ -1,11 +1,11 @@ -import { neode } from '../../bootstrap/neo4j' +import { getNeode } from '../../bootstrap/neo4j' import { UserInputError } from 'apollo-server' -const instance = neode() +const neode = getNeode() const getUserAndBadge = async ({ badgeKey, userId }) => { - const user = await instance.first('User', 'id', userId) - const badge = await instance.first('Badge', 'id', badgeKey) + const user = await neode.first('User', 'id', userId) + const badge = await neode.first('Badge', 'id', badgeKey) if (!user) throw new UserInputError("Couldn't find a user with that id") if (!badge) throw new UserInputError("Couldn't find a badge with that id") return { user, badge } diff --git a/backend/src/schema/resolvers/rewards.spec.js b/backend/src/schema/resolvers/rewards.spec.js index 2dcdd5b53..e6f67ecab 100644 --- a/backend/src/schema/resolvers/rewards.spec.js +++ b/backend/src/schema/resolvers/rewards.spec.js @@ -1,7 +1,7 @@ import { createTestClient } from 'apollo-server-testing' import Factory from '../../seed/factories' import { gql } from '../../helpers/jest' -import { neode as getNeode, getDriver } from '../../bootstrap/neo4j' +import { getNeode, getDriver } from '../../bootstrap/neo4j' import createServer from '../../server' const factory = Factory() diff --git a/backend/src/schema/resolvers/shout.spec.js b/backend/src/schema/resolvers/shout.spec.js index f39e4d137..e747946aa 100644 --- a/backend/src/schema/resolvers/shout.spec.js +++ b/backend/src/schema/resolvers/shout.spec.js @@ -1,7 +1,7 @@ import { createTestClient } from 'apollo-server-testing' import Factory from '../../seed/factories' import { gql } from '../../helpers/jest' -import { neode as getNeode, getDriver } from '../../bootstrap/neo4j' +import { getNeode, getDriver } from '../../bootstrap/neo4j' import createServer from '../../server' let mutate, query, authenticatedUser, variables diff --git a/backend/src/schema/resolvers/socialMedia.js b/backend/src/schema/resolvers/socialMedia.js index 49aa6788d..c206778e5 100644 --- a/backend/src/schema/resolvers/socialMedia.js +++ b/backend/src/schema/resolvers/socialMedia.js @@ -1,14 +1,14 @@ -import { neode } from '../../bootstrap/neo4j' +import { getNeode } from '../../bootstrap/neo4j' import Resolver from './helpers/Resolver' -const instance = neode() +const neode = getNeode() export default { Mutation: { CreateSocialMedia: async (object, params, context, resolveInfo) => { const [user, socialMedia] = await Promise.all([ - instance.find('User', context.user.id), - instance.create('SocialMedia', params), + neode.find('User', context.user.id), + neode.create('SocialMedia', params), ]) await socialMedia.relateTo(user, 'ownedBy') const response = await socialMedia.toJson() @@ -16,14 +16,14 @@ export default { return response }, UpdateSocialMedia: async (object, params, context, resolveInfo) => { - const socialMedia = await instance.find('SocialMedia', params.id) + const socialMedia = await neode.find('SocialMedia', params.id) await socialMedia.update({ url: params.url }) const response = await socialMedia.toJson() return response }, DeleteSocialMedia: async (object, { id }, context, resolveInfo) => { - const socialMedia = await instance.find('SocialMedia', id) + const socialMedia = await neode.find('SocialMedia', id) if (!socialMedia) return null await socialMedia.delete() return socialMedia.toJson() diff --git a/backend/src/schema/resolvers/socialMedia.spec.js b/backend/src/schema/resolvers/socialMedia.spec.js index 092139747..8f6d91d43 100644 --- a/backend/src/schema/resolvers/socialMedia.spec.js +++ b/backend/src/schema/resolvers/socialMedia.spec.js @@ -2,11 +2,11 @@ import { createTestClient } from 'apollo-server-testing' import createServer from '../../server' import Factory from '../../seed/factories' import { gql } from '../../helpers/jest' -import { neode, getDriver } from '../../bootstrap/neo4j' +import { getNeode, getDriver } from '../../bootstrap/neo4j' const driver = getDriver() const factory = Factory() -const instance = neode() +const neode = getNeode() describe('SocialMedia', () => { let socialMediaAction, someUser, ownerNode, owner @@ -27,15 +27,15 @@ describe('SocialMedia', () => { const newUrl = 'https://twitter.com/bullerby' const setUpSocialMedia = async () => { - const socialMediaNode = await instance.create('SocialMedia', { url }) + const socialMediaNode = await neode.create('SocialMedia', { url }) await socialMediaNode.relateTo(ownerNode, 'ownedBy') return socialMediaNode.toJson() } beforeEach(async () => { - const someUserNode = await instance.create('User', userParams) + const someUserNode = await neode.create('User', userParams) someUser = await someUserNode.toJson() - ownerNode = await instance.create('User', ownerParams) + ownerNode = await neode.create('User', ownerParams) owner = await ownerNode.toJson() socialMediaAction = async (user, mutation, variables) => { diff --git a/backend/src/schema/resolvers/statistics.spec.js b/backend/src/schema/resolvers/statistics.spec.js index 7ffa8ebd0..48baf00cd 100644 --- a/backend/src/schema/resolvers/statistics.spec.js +++ b/backend/src/schema/resolvers/statistics.spec.js @@ -1,7 +1,7 @@ import { createTestClient } from 'apollo-server-testing' import Factory from '../../seed/factories' import { gql } from '../../helpers/jest' -import { neode as getNeode, getDriver } from '../../bootstrap/neo4j' +import { getNeode, getDriver } from '../../bootstrap/neo4j' import createServer from '../../server' let query, authenticatedUser diff --git a/backend/src/schema/resolvers/user_management.js b/backend/src/schema/resolvers/user_management.js index 4c4c3fc90..d5c6cd5ad 100644 --- a/backend/src/schema/resolvers/user_management.js +++ b/backend/src/schema/resolvers/user_management.js @@ -1,10 +1,10 @@ import encode from '../../jwt/encode' import bcrypt from 'bcryptjs' import { AuthenticationError } from 'apollo-server' -import { neode } from '../../bootstrap/neo4j' +import { getNeode } from '../../bootstrap/neo4j' import normalizeEmail from './helpers/normalizeEmail' -const instance = neode() +const neode = getNeode() export default { Query: { @@ -13,7 +13,7 @@ export default { }, currentUser: async (object, params, ctx, resolveInfo) => { if (!ctx.user) return null - const user = await instance.find('User', ctx.user.id) + const user = await neode.find('User', ctx.user.id) return user.toJson() }, }, @@ -53,7 +53,7 @@ export default { } }, changePassword: async (_, { oldPassword, newPassword }, { driver, user }) => { - const currentUser = await instance.find('User', user.id) + const currentUser = await neode.find('User', user.id) const encryptedPassword = currentUser.get('encryptedPassword') if (!(await bcrypt.compareSync(oldPassword, encryptedPassword))) { diff --git a/backend/src/schema/resolvers/user_management.spec.js b/backend/src/schema/resolvers/user_management.spec.js index e67b90c8d..3527e5dc2 100644 --- a/backend/src/schema/resolvers/user_management.spec.js +++ b/backend/src/schema/resolvers/user_management.spec.js @@ -5,7 +5,7 @@ import { gql } from '../../helpers/jest' import { createTestClient } from 'apollo-server-testing' import createServer, { context } from '../../server' import encode from '../../jwt/encode' -import { neode as getNeode } from '../../bootstrap/neo4j' +import { getNeode } from '../../bootstrap/neo4j' const factory = Factory() const neode = getNeode() diff --git a/backend/src/schema/resolvers/users.js b/backend/src/schema/resolvers/users.js index c44e3f44b..d8d5fbb73 100644 --- a/backend/src/schema/resolvers/users.js +++ b/backend/src/schema/resolvers/users.js @@ -1,10 +1,10 @@ import { neo4jgraphql } from 'neo4j-graphql-js' import fileUpload from './fileUpload' -import { neode } from '../../bootstrap/neo4j' +import { getNeode } from '../../bootstrap/neo4j' import { UserInputError, ForbiddenError } from 'apollo-server' import Resolver from './helpers/Resolver' -const instance = neode() +const neode = getNeode() export const getBlockedUsers = async context => { const { neode } = context @@ -73,7 +73,7 @@ export default { block: async (object, args, context, resolveInfo) => { const { user: currentUser } = context if (currentUser.id === args.id) return null - await instance.cypher( + await neode.cypher( ` MATCH(u:User {id: $currentUser.id})-[r:FOLLOWS]->(b:User {id: $args.id}) DELETE r @@ -81,8 +81,8 @@ export default { { currentUser, args }, ) const [user, blockedUser] = await Promise.all([ - instance.find('User', currentUser.id), - instance.find('User', args.id), + neode.find('User', currentUser.id), + neode.find('User', args.id), ]) await user.relateTo(blockedUser, 'blocked') return blockedUser.toJson() @@ -90,14 +90,14 @@ export default { unblock: async (object, args, context, resolveInfo) => { const { user: currentUser } = context if (currentUser.id === args.id) return null - await instance.cypher( + await neode.cypher( ` MATCH(u:User {id: $currentUser.id})-[r:BLOCKED]->(b:User {id: $args.id}) DELETE r `, { currentUser, args }, ) - const blockedUser = await instance.find('User', args.id) + const blockedUser = await neode.find('User', args.id) return blockedUser.toJson() }, UpdateUser: async (object, args, context, resolveInfo) => { @@ -111,7 +111,7 @@ export default { } args = await fileUpload(args, { file: 'avatarUpload', url: 'avatar' }) try { - const user = await instance.find('User', args.id) + const user = await neode.find('User', args.id) if (!user) return null await user.update({ ...args, updatedAt: new Date().toISOString() }) return user.toJson() @@ -173,7 +173,7 @@ export default { if (typeof parent.email !== 'undefined') return parent.email const { id } = parent const statement = `MATCH(u:User {id: {id}})-[:PRIMARY_EMAIL]->(e:EmailAddress) RETURN e` - const result = await instance.cypher(statement, { id }) + const result = await neode.cypher(statement, { id }) const [{ email }] = result.records.map(r => r.get('e').properties) return email }, diff --git a/backend/src/schema/resolvers/users.spec.js b/backend/src/schema/resolvers/users.spec.js index 483c70214..26e977a31 100644 --- a/backend/src/schema/resolvers/users.spec.js +++ b/backend/src/schema/resolvers/users.spec.js @@ -1,6 +1,6 @@ import Factory from '../../seed/factories' import { gql } from '../../helpers/jest' -import { neode as getNeode, getDriver } from '../../bootstrap/neo4j' +import { getNeode, getDriver } from '../../bootstrap/neo4j' import createServer from '../../server' import { createTestClient } from 'apollo-server-testing' diff --git a/backend/src/schema/resolvers/users/blockedUsers.spec.js b/backend/src/schema/resolvers/users/blockedUsers.spec.js index e0ab00448..11bcb823d 100644 --- a/backend/src/schema/resolvers/users/blockedUsers.spec.js +++ b/backend/src/schema/resolvers/users/blockedUsers.spec.js @@ -2,11 +2,11 @@ import { createTestClient } from 'apollo-server-testing' import createServer from '../../../server' import Factory from '../../../seed/factories' import { gql } from '../../../helpers/jest' -import { neode, getDriver } from '../../../bootstrap/neo4j' +import { getNeode, getDriver } from '../../../bootstrap/neo4j' const driver = getDriver() const factory = Factory() -const instance = neode() +const neode = getNeode() let currentUser let blockedUser @@ -20,7 +20,7 @@ beforeEach(() => { return { user: authenticatedUser, driver, - neode: instance, + neode, cypherParams: { currentUserId: authenticatedUser ? authenticatedUser.id : null, }, @@ -55,11 +55,11 @@ describe('blockedUsers', () => { describe('authenticated and given a blocked user', () => { beforeEach(async () => { - currentUser = await instance.create('User', { + currentUser = await neode.create('User', { name: 'Current User', id: 'u1', }) - blockedUser = await instance.create('User', { + blockedUser = await neode.create('User', { name: 'Blocked User', id: 'u2', }) @@ -113,7 +113,7 @@ describe('block', () => { describe('authenticated', () => { beforeEach(async () => { - currentUser = await instance.create('User', { + currentUser = await neode.create('User', { name: 'Current User', id: 'u1', }) @@ -138,7 +138,7 @@ describe('block', () => { describe('given a to-be-blocked user', () => { beforeEach(async () => { - blockedUser = await instance.create('User', { + blockedUser = await neode.create('User', { name: 'Blocked User', id: 'u2', }) @@ -181,11 +181,11 @@ describe('block', () => { let postQuery beforeEach(async () => { - const post1 = await instance.create('Post', { + const post1 = await neode.create('Post', { id: 'p12', title: 'A post written by the current user', }) - const post2 = await instance.create('Post', { + const post2 = await neode.create('Post', { id: 'p23', title: 'A post written by the blocked user', }) @@ -323,7 +323,7 @@ describe('unblock', () => { describe('authenticated', () => { beforeEach(async () => { - currentUser = await instance.create('User', { + currentUser = await neode.create('User', { name: 'Current User', id: 'u1', }) @@ -348,7 +348,7 @@ describe('unblock', () => { describe('given another user', () => { beforeEach(async () => { - blockedUser = await instance.create('User', { + blockedUser = await neode.create('User', { name: 'Blocked User', id: 'u2', }) diff --git a/backend/src/seed/factories/index.js b/backend/src/seed/factories/index.js index 441fe47d5..10db5cc03 100644 --- a/backend/src/seed/factories/index.js +++ b/backend/src/seed/factories/index.js @@ -1,4 +1,4 @@ -import { getDriver, neode } from '../../bootstrap/neo4j' +import { getDriver, getNeode } from '../../bootstrap/neo4j' import createBadge from './badges.js' import createUser from './users.js' import createPost from './posts.js' @@ -39,7 +39,7 @@ export const cleanDatabase = async (options = {}) => { } export default function Factory(options = {}) { - const { neo4jDriver = getDriver(), neodeInstance = neode() } = options + const { neo4jDriver = getDriver(), neodeInstance = getNeode() } = options const result = { neo4jDriver, diff --git a/backend/src/seed/seed-db.js b/backend/src/seed/seed-db.js index 2e10b0472..475a7b54f 100644 --- a/backend/src/seed/seed-db.js +++ b/backend/src/seed/seed-db.js @@ -3,7 +3,7 @@ import sample from 'lodash/sample' import { createTestClient } from 'apollo-server-testing' import createServer from '../server' import Factory from './factories' -import { neode as getNeode, getDriver } from '../bootstrap/neo4j' +import { getNeode, getDriver } from '../bootstrap/neo4j' import { gql } from '../helpers/jest' const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl'] diff --git a/backend/src/server.js b/backend/src/server.js index 053a3e4b3..91b9a13aa 100644 --- a/backend/src/server.js +++ b/backend/src/server.js @@ -3,7 +3,7 @@ import helmet from 'helmet' import { ApolloServer } from 'apollo-server-express' import CONFIG, { requiredConfigs } from './config' import middleware from './middleware' -import { neode as getNeode, getDriver } from './bootstrap/neo4j' +import { getNeode, getDriver } from './bootstrap/neo4j' import decode from './jwt/decode' import schema from './schema' import webfinger from './activitypub/routes/webfinger' diff --git a/backend/yarn.lock b/backend/yarn.lock index cba2455d1..56796f040 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -33,10 +33,10 @@ resolved "https://registry.yarnpkg.com/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.24.tgz#3ce939cb127fb8aaa3ffc1e90dff9b8af9f2e3dc" integrity sha512-8GqG48m1XqyXh4mIZrtB5xOhUwSsh1WsrrsaZQOEYYql3YN9DEu9OOSg0ILzXHZo/h2Q74777YE4YzlArQzQEQ== -"@babel/cli@~7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.7.4.tgz#38804334c8db40209f88c69a5c90998e60cca18b" - integrity sha512-O7mmzaWdm+VabWQmxuM8hqNrWGGihN83KfhPUzp2lAW4kzIMwBxujXkZbD4fMwKMYY9FXTbDvXsJqU+5XHXi4A== +"@babel/cli@~7.7.5": + version "7.7.5" + resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.7.5.tgz#25702cc65418efc06989af3727897b9f4c8690b6" + integrity sha512-y2YrMGXM3NUyu1Myg0pxg+Lx6g8XhEyvLHYNRwTBV6fDek3H7Io6b7N/LXscLs4HWn4HxMdy7f2rM1rTMp2mFg== dependencies: commander "^4.0.1" convert-source-map "^1.1.0" @@ -184,6 +184,18 @@ "@babel/types" "^7.7.4" lodash "^4.17.13" +"@babel/helper-module-transforms@^7.7.5": + version "7.7.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.7.5.tgz#d044da7ffd91ec967db25cd6748f704b6b244835" + integrity sha512-A7pSxyJf1gN5qXVcidwLWydjftUN878VkalhXX5iQDuGyiGK3sOrrKKHF4/A4fwHtnsotv/NipwAeLzY4KQPvw== + dependencies: + "@babel/helper-module-imports" "^7.7.4" + "@babel/helper-simple-access" "^7.7.4" + "@babel/helper-split-export-declaration" "^7.7.4" + "@babel/template" "^7.7.4" + "@babel/types" "^7.7.4" + lodash "^4.17.13" + "@babel/helper-optimise-call-expression@^7.7.4": version "7.7.4" resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.7.4.tgz#034af31370d2995242aa4df402c3b7794b2dcdf2" @@ -502,21 +514,21 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-modules-amd@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.7.4.tgz#276b3845ca2b228f2995e453adc2e6f54d72fb71" - integrity sha512-/542/5LNA18YDtg1F+QHvvUSlxdvjZoD/aldQwkq+E3WCkbEjNSN9zdrOXaSlfg3IfGi22ijzecklF/A7kVZFQ== +"@babel/plugin-transform-modules-amd@^7.7.5": + version "7.7.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.7.5.tgz#39e0fb717224b59475b306402bb8eedab01e729c" + integrity sha512-CT57FG4A2ZUNU1v+HdvDSDrjNWBrtCmSH6YbbgN3Lrf0Di/q/lWRxZrE72p3+HCCz9UjfZOEBdphgC0nzOS6DQ== dependencies: - "@babel/helper-module-transforms" "^7.7.4" + "@babel/helper-module-transforms" "^7.7.5" "@babel/helper-plugin-utils" "^7.0.0" babel-plugin-dynamic-import-node "^2.3.0" -"@babel/plugin-transform-modules-commonjs@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.7.4.tgz#bee4386e550446343dd52a571eda47851ff857a3" - integrity sha512-k8iVS7Jhc367IcNF53KCwIXtKAH7czev866ThsTgy8CwlXjnKZna2VHwChglzLleYrcHz1eQEIJlGRQxB53nqA== +"@babel/plugin-transform-modules-commonjs@^7.7.5": + version "7.7.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.7.5.tgz#1d27f5eb0bcf7543e774950e5b2fa782e637b345" + integrity sha512-9Cq4zTFExwFhQI6MT1aFxgqhIsMWQWDVwOgLzl7PTWJHsNaqFvklAU+Oz6AQLAS0dJKTwZSOCo20INwktxpi3Q== dependencies: - "@babel/helper-module-transforms" "^7.7.4" + "@babel/helper-module-transforms" "^7.7.5" "@babel/helper-plugin-utils" "^7.0.0" "@babel/helper-simple-access" "^7.7.4" babel-plugin-dynamic-import-node "^2.3.0" @@ -576,10 +588,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-regenerator@^7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.7.4.tgz#d18eac0312a70152d7d914cbed2dc3999601cfc0" - integrity sha512-e7MWl5UJvmPEwFJTwkBlPmqixCtr9yAASBqff4ggXTNicZiwbF8Eefzm6NVgfiBp7JdAGItecnctKTgH44q2Jw== +"@babel/plugin-transform-regenerator@^7.7.5": + version "7.7.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.7.5.tgz#3a8757ee1a2780f390e89f246065ecf59c26fce9" + integrity sha512-/8I8tPvX2FkuEyWbjRCt4qTAgZK0DVy8QRguhA524UH48RfGJy94On2ri+dCuwOpcerPRl9O4ebQkRcVzIaGBw== dependencies: regenerator-transform "^0.14.0" @@ -635,10 +647,10 @@ "@babel/helper-create-regexp-features-plugin" "^7.7.4" "@babel/helper-plugin-utils" "^7.0.0" -"@babel/preset-env@~7.7.4": - version "7.7.4" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.7.4.tgz#ccaf309ae8d1ee2409c85a4e2b5e280ceee830f8" - integrity sha512-Dg+ciGJjwvC1NIe/DGblMbcGq1HOtKbw8RLl4nIjlfcILKEOkWT/vRqPpumswABEBVudii6dnVwrBtzD7ibm4g== +"@babel/preset-env@~7.7.6": + version "7.7.6" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.7.6.tgz#39ac600427bbb94eec6b27953f1dfa1d64d457b2" + integrity sha512-k5hO17iF/Q7tR9Jv8PdNBZWYW6RofxhnxKjBMc0nG4JTaWvOTiPoO/RLFwAKcA4FpmuBFm6jkoqaRJLGi0zdaQ== dependencies: "@babel/helper-module-imports" "^7.7.4" "@babel/helper-plugin-utils" "^7.0.0" @@ -668,8 +680,8 @@ "@babel/plugin-transform-function-name" "^7.7.4" "@babel/plugin-transform-literals" "^7.7.4" "@babel/plugin-transform-member-expression-literals" "^7.7.4" - "@babel/plugin-transform-modules-amd" "^7.7.4" - "@babel/plugin-transform-modules-commonjs" "^7.7.4" + "@babel/plugin-transform-modules-amd" "^7.7.5" + "@babel/plugin-transform-modules-commonjs" "^7.7.5" "@babel/plugin-transform-modules-systemjs" "^7.7.4" "@babel/plugin-transform-modules-umd" "^7.7.4" "@babel/plugin-transform-named-capturing-groups-regex" "^7.7.4" @@ -677,7 +689,7 @@ "@babel/plugin-transform-object-super" "^7.7.4" "@babel/plugin-transform-parameters" "^7.7.4" "@babel/plugin-transform-property-literals" "^7.7.4" - "@babel/plugin-transform-regenerator" "^7.7.4" + "@babel/plugin-transform-regenerator" "^7.7.5" "@babel/plugin-transform-reserved-words" "^7.7.4" "@babel/plugin-transform-shorthand-properties" "^7.7.4" "@babel/plugin-transform-spread" "^7.7.4" @@ -687,7 +699,7 @@ "@babel/plugin-transform-unicode-regex" "^7.7.4" "@babel/types" "^7.7.4" browserslist "^4.6.0" - core-js-compat "^3.1.1" + core-js-compat "^3.4.7" invariant "^2.2.2" js-levenshtein "^1.1.3" semver "^5.5.0" @@ -1101,56 +1113,56 @@ resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= -"@sentry/apm@5.10.1": - version "5.10.1" - resolved "https://registry.yarnpkg.com/@sentry/apm/-/apm-5.10.1.tgz#2ec20cef0f87f9f638ff78dd5092e1e9d36c4b7d" - integrity sha512-VSFK8giRG5/lN0YSaOw8+Cru/8MVevmoHZ5JC9iDIt0H6sGTUjOBKIqTZ0eq2Y99Vn0N9dkxjeT0rOIvsrg0gA== +"@sentry/apm@5.10.2": + version "5.10.2" + resolved "https://registry.yarnpkg.com/@sentry/apm/-/apm-5.10.2.tgz#41a401b3964b68514439f8a595b12c6fd05ab21a" + integrity sha512-rPeAFsD/6ontvs7bsuHh+XAg1ohWo04ms08SNWqEvLRQJx7WfiWnjziyC0S3dXIYZDGdhruSsqQJPJN8r6Aj5g== dependencies: - "@sentry/hub" "5.10.1" - "@sentry/minimal" "5.10.1" + "@sentry/hub" "5.10.2" + "@sentry/minimal" "5.10.2" "@sentry/types" "5.10.0" - "@sentry/utils" "5.10.1" + "@sentry/utils" "5.10.2" tslib "^1.9.3" -"@sentry/core@5.10.1": - version "5.10.1" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.10.1.tgz#356551f111d4df38e60852607cc8cde0ed8ccc76" - integrity sha512-MbiasA/cuMB0+9zVBGi5YLWRj7CdFQJOM29Vp8rm3xMaQDH0KHarpny1gOgMiLu/O/r8itjiZwKu+9pxOWGbeA== +"@sentry/core@5.10.2": + version "5.10.2" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.10.2.tgz#1cb64489e6f8363c3249415b49d3f1289814825f" + integrity sha512-sKVeFH3v8K8xw2vM5MKMnnyAAwih+JSE3pbNL0CcCCA+/SwX+3jeAo2BhgXev2SAR/TjWW+wmeC9TdIW7KyYbg== dependencies: - "@sentry/hub" "5.10.1" - "@sentry/minimal" "5.10.1" + "@sentry/hub" "5.10.2" + "@sentry/minimal" "5.10.2" "@sentry/types" "5.10.0" - "@sentry/utils" "5.10.1" + "@sentry/utils" "5.10.2" tslib "^1.9.3" -"@sentry/hub@5.10.1": - version "5.10.1" - resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.10.1.tgz#3be4a0705cd0cd074be0aab0dc418ecb72885989" - integrity sha512-g+P+0cj6vKdf6Ct4S47MxHwSMIjtIadOwBhb4Lqwij5YPtQ4LpVr10peKbE+FMMvCNQSvQnJEhTDko+AE7AoYw== +"@sentry/hub@5.10.2": + version "5.10.2" + resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.10.2.tgz#25d9f36b8f7c5cb65cf486737fa61dc9bf69b7e3" + integrity sha512-hSlZIiu3hcR/I5yEhlpN9C0nip+U7hiRzRzUQaBiHO4YG4TC58NqnOPR89D/ekiuHIXzFpjW9OQmqtAMRoSUYA== dependencies: "@sentry/types" "5.10.0" - "@sentry/utils" "5.10.1" + "@sentry/utils" "5.10.2" tslib "^1.9.3" -"@sentry/minimal@5.10.1": - version "5.10.1" - resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.10.1.tgz#37104f81ef3b333c0f9e77ac94bfed348070dea3" - integrity sha512-oKrLvKaah0xGVIYbS1I7dVbo73aWssfiT2ypl9DYt8MAFiwfiiXz68FlG4z9dPZ2jSz9Jm2SAYHFaYLvU26TBQ== +"@sentry/minimal@5.10.2": + version "5.10.2" + resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.10.2.tgz#267c2f3aa6877a0fe7a86971942e83f3ee616580" + integrity sha512-GalixiM9sckYfompH5HHTp9XT2BcjawBkcl1DMEKUBEi37+kUq0bivOBmnN1G/I4/wWOUdnAI/kagDWaWpbZPg== dependencies: - "@sentry/hub" "5.10.1" + "@sentry/hub" "5.10.2" "@sentry/types" "5.10.0" tslib "^1.9.3" -"@sentry/node@^5.10.1": - version "5.10.1" - resolved "https://registry.yarnpkg.com/@sentry/node/-/node-5.10.1.tgz#cafbf3b0918c98fb9f99803ffe50056e32194bef" - integrity sha512-kard7OXQDvYqmQD93bOkYhznqrbsiFNZ6+dIi13eo/kc2Au+v1Th1mGvr9JDRE/X07z6vJMYMiorKd351G3p/A== +"@sentry/node@^5.10.2": + version "5.10.2" + resolved "https://registry.yarnpkg.com/@sentry/node/-/node-5.10.2.tgz#1f5d6deefb2c1549ddb542c10952cccf5f9a4ac2" + integrity sha512-1ib1hAhVtmfXOThpcCfR4S6wFopd6lHqgOMrAUPo9saHy8zseZPRC7iTWGoSPy2RMwjrURAk54VvFnLe7G+PdQ== dependencies: - "@sentry/apm" "5.10.1" - "@sentry/core" "5.10.1" - "@sentry/hub" "5.10.1" + "@sentry/apm" "5.10.2" + "@sentry/core" "5.10.2" + "@sentry/hub" "5.10.2" "@sentry/types" "5.10.0" - "@sentry/utils" "5.10.1" + "@sentry/utils" "5.10.2" cookie "^0.3.1" https-proxy-agent "^3.0.0" lru_map "^0.3.3" @@ -1161,10 +1173,10 @@ resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.10.0.tgz#4f0ba31b6e4d5371112c38279f11f66c73b43746" integrity sha512-TW20GzkCWsP6uAxR2JIpIkiitCKyIOfkyDsKBeLqYj4SaZjfvBPnzgNCcYR0L0UsP1/Es6oHooZfIGSkp6GGxQ== -"@sentry/utils@5.10.1": - version "5.10.1" - resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.10.1.tgz#eeb3ede85a9b5b1cd1aad7e3157052bee0d42551" - integrity sha512-zdv03sINfJ8QXSHP49845qhkbdNUrX20AagUY+Arq2zxmM4XxnRVA7dtWDkyy55bTt0ziRuSikBxR3266t8mDg== +"@sentry/utils@5.10.2": + version "5.10.2" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.10.2.tgz#261f575079d30aaf604e59f5f4de0aa21db22252" + integrity sha512-UcbbaFpYrGSV448lQ16Cr+W/MPuKUflQQUdrMCt5vgaf5+M7kpozlcji4GGGZUCXIA7oRP93ABoXj55s1OM9zw== dependencies: "@sentry/types" "5.10.0" tslib "^1.9.3" @@ -1918,6 +1930,15 @@ array-unique@^0.3.2: resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= +array.prototype.flat@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.2.tgz#8f3c71d245ba349b6b64b4078f76f5576f1fd723" + integrity sha512-VXjh7lAL4KXKF2hY4FnEW9eRW6IhdvFW1sN/JwLbmECbCgACCnBHNyP3lFiYuttr0jxRN9Bsc5+G27dMseSWqQ== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.15.0" + function-bind "^1.1.1" + arrify@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa" @@ -2233,14 +2254,14 @@ browser-resolve@^1.11.3: dependencies: resolve "1.1.7" -browserslist@^4.6.0, browserslist@^4.6.6: - version "4.6.6" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.6.6.tgz#6e4bf467cde520bc9dbdf3747dafa03531cec453" - integrity sha512-D2Nk3W9JL9Fp/gIcWei8LrERCS+eXu9AM5cfXA8WEZ84lFks+ARnZ0q/R69m2SV3Wjma83QDDPxsNKXUwdIsyA== +browserslist@^4.6.0, browserslist@^4.8.2: + version "4.8.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.8.2.tgz#b45720ad5fbc8713b7253c20766f701c9a694289" + integrity sha512-+M4oeaTplPm/f1pXDw84YohEv7B1i/2Aisei8s4s6k3QsoSHa7i5sz8u/cGQkkatCPxMASKxPualR4wwYgVboA== dependencies: - caniuse-lite "^1.0.30000984" - electron-to-chromium "^1.3.191" - node-releases "^1.1.25" + caniuse-lite "^1.0.30001015" + electron-to-chromium "^1.3.322" + node-releases "^1.1.42" bser@^2.0.0: version "2.1.0" @@ -2319,10 +2340,10 @@ camelize@1.0.0: resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b" integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs= -caniuse-lite@^1.0.30000984: - version "1.0.30000989" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz#b9193e293ccf7e4426c5245134b8f2a56c0ac4b9" - integrity sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw== +caniuse-lite@^1.0.30001015: + version "1.0.30001015" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001015.tgz#15a7ddf66aba786a71d99626bc8f2b91c6f0f5f0" + integrity sha512-/xL2AbW/XWHNu1gnIrO8UitBGoFthcsDgU9VLK1/dpsoxbaD5LscHozKze05R6WLsBvLhqv78dAPozMFQBYLbQ== capture-exit@^2.0.0: version "2.0.0" @@ -2683,12 +2704,12 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= -core-js-compat@^3.1.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.2.1.tgz#0cbdbc2e386e8e00d3b85dc81c848effec5b8150" - integrity sha512-MwPZle5CF9dEaMYdDeWm73ao/IflDH+FjeJCWEADcEgFSE9TLimFKwJsfmkwzI8eC0Aj0mgvMDjeQjrElkz4/A== +core-js-compat@^3.4.7: + version "3.4.8" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.4.8.tgz#f72e6a4ed76437ea710928f44615f926a81607d5" + integrity sha512-l3WTmnXHV2Sfu5VuD7EHE2w7y+K68+kULKt5RJg8ZJk3YhHF1qLD4O8v8AmNq+8vbOwnPFFDvds25/AoEvMqlQ== dependencies: - browserslist "^4.6.6" + browserslist "^4.8.2" semver "^6.3.0" core-js@^2.4.0, core-js@^2.6.5: @@ -2874,7 +2895,7 @@ date-fns@2.8.1: resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.8.1.tgz#2109362ccb6c87c3ca011e9e31f702bc09e4123b" integrity sha512-EL/C8IHvYRwAHYgFRse4MGAPSqlJVlOrhVYZ75iQBKrnv+ZedmYsgwH3t+BCDuZDXpoo07+q9j4qgSSOa7irJg== -debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: +debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== @@ -3156,10 +3177,10 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -electron-to-chromium@^1.3.191: - version "1.3.237" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.237.tgz#39c5d1da59d6fd16ff705b97e772bb3b5dfda7e4" - integrity sha512-SPAFjDr/7iiVK2kgTluwxela6eaWjjFkS9rO/iYpB/KGXgccUom5YC7OIf19c8m8GGptWxLU0Em8xM64A/N7Fg== +electron-to-chromium@^1.3.322: + version "1.3.322" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.322.tgz#a6f7e1c79025c2b05838e8e344f6e89eb83213a8" + integrity sha512-Tc8JQEfGQ1MzfSzI/bTlSr7btJv/FFO7Yh6tanqVmIWOuNCu6/D1MilIEgLtmWqIrsv+o4IjpLAhgMBr/ncNAA== emoji-regex@^7.0.1: version "7.0.3" @@ -3219,6 +3240,22 @@ es-abstract@^1.12.0, es-abstract@^1.4.3, es-abstract@^1.5.1, es-abstract@^1.7.0: is-regex "^1.0.4" object-keys "^1.0.12" +es-abstract@^1.15.0: + version "1.16.3" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.16.3.tgz#52490d978f96ff9f89ec15b5cf244304a5bca161" + integrity sha512-WtY7Fx5LiOnSYgF5eg/1T+GONaGmpvpPdCpSnYij+U2gDTL0UPfWrhDw7b2IYb+9NQJsYpCA0wOQvZfsd6YwRw== + dependencies: + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + is-callable "^1.1.4" + is-regex "^1.0.4" + object-inspect "^1.7.0" + object-keys "^1.1.1" + string.prototype.trimleft "^2.1.0" + string.prototype.trimright "^2.1.0" + es-to-primitive@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" @@ -3228,6 +3265,15 @@ es-to-primitive@^1.2.0: is-date-object "^1.0.1" is-symbol "^1.0.2" +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + es5-ext@^0.10.35, es5-ext@^0.10.50, es5-ext@~0.10.14, es5-ext@~0.10.46: version "0.10.50" resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.50.tgz#6d0e23a0abdb27018e5ac4fd09b412bc5517a778" @@ -3313,12 +3359,12 @@ eslint-import-resolver-node@^0.3.2: debug "^2.6.9" resolve "^1.5.0" -eslint-module-utils@^2.4.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.4.1.tgz#7b4675875bf96b0dbf1b21977456e5bb1f5e018c" - integrity sha512-H6DOj+ejw7Tesdgbfs4jeS4YMFrT8uI8xwd1gtQqXssaR0EQ26L+2O/w6wkYFy2MymON0fTwHmXBvvfLNZVZEw== +eslint-module-utils@^2.4.1: + version "2.5.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.5.0.tgz#cdf0b40d623032274ccd2abd7e64c4e524d6e19c" + integrity sha512-kCo8pZaNz2dsAW7nCUjuVoI11EBXXpIzfNxmaoLhXoRDOnqXLC4iSGVRdZPhOitfbdEfMEfKOiENaK6wDPZEGw== dependencies: - debug "^2.6.8" + debug "^2.6.9" pkg-dir "^2.0.0" eslint-plugin-es@^2.0.0: @@ -3329,22 +3375,23 @@ eslint-plugin-es@^2.0.0: eslint-utils "^1.4.2" regexpp "^3.0.0" -eslint-plugin-import@~2.18.2: - version "2.18.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.18.2.tgz#02f1180b90b077b33d447a17a2326ceb400aceb6" - integrity sha512-5ohpsHAiUBRNaBWAF08izwUGlbrJoJJ+W9/TBwsGoR1MnlgfwMIKrFeSjWbt6moabiXW9xNvtFz+97KHRfI4HQ== +eslint-plugin-import@~2.19.1: + version "2.19.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.19.1.tgz#5654e10b7839d064dd0d46cd1b88ec2133a11448" + integrity sha512-x68131aKoCZlCae7rDXKSAQmbT5DQuManyXo2sK6fJJ0aK5CWAkv6A6HJZGgqC8IhjQxYPgo6/IY4Oz8AFsbBw== dependencies: array-includes "^3.0.3" + array.prototype.flat "^1.2.1" contains-path "^0.1.0" debug "^2.6.9" doctrine "1.5.0" eslint-import-resolver-node "^0.3.2" - eslint-module-utils "^2.4.0" + eslint-module-utils "^2.4.1" has "^1.0.3" minimatch "^3.0.4" object.values "^1.1.0" read-pkg-up "^2.0.0" - resolve "^1.11.0" + resolve "^1.12.0" eslint-plugin-jest@~23.1.1: version "23.1.1" @@ -4205,6 +4252,11 @@ has-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q= +has-symbols@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" + integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== + has-unicode@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" @@ -6109,10 +6161,10 @@ neo4j-driver@^1.7.3, neo4j-driver@^1.7.5, neo4j-driver@~1.7.6: text-encoding-utf-8 "^1.0.2" uri-js "^4.2.2" -neo4j-graphql-js@^2.10.0: - version "2.10.0" - resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-2.10.0.tgz#4298793756d839dedb98bc3e50a2bd40a311874d" - integrity sha512-jRdIyw+DHg9gfB6pWKb1ZHMR9rXIl7qf51efjUHIRHRbVR3RCcw1cKyONkq4LE8v2bHc7QDrKwJs+GQ1SRxDug== +neo4j-graphql-js@^2.10.1: + version "2.10.1" + resolved "https://registry.yarnpkg.com/neo4j-graphql-js/-/neo4j-graphql-js-2.10.1.tgz#e470d067db681bac8f4daa755f697000110aca4b" + integrity sha512-D6Gimu39lkg+3pXKWR3qEY6yMXOv/JOdKSizsYSAE73lj9CubJAYx4hdtmNXJ0Tyy+C9LxcPZwWZEzg0P9niEw== dependencies: "@babel/runtime" "^7.5.5" "@babel/runtime-corejs2" "^7.5.5" @@ -6204,12 +6256,12 @@ node-pre-gyp@^0.12.0: semver "^5.3.0" tar "^4" -node-releases@^1.1.25: - version "1.1.28" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.28.tgz#503c3c70d0e4732b84e7aaa2925fbdde10482d4a" - integrity sha512-AQw4emh6iSXnCpDiFe0phYcThiccmkNWMZnFZ+lDJjAP8J0m2fVd59duvUUyuTirQOhIAajTFkzG6FHCLBO59g== +node-releases@^1.1.42: + version "1.1.42" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.42.tgz#a999f6a62f8746981f6da90627a8d2fc090bbad7" + integrity sha512-OQ/ESmUqGawI2PRX+XIRao44qWYBBfN54ImQYdWVTQqUckuejOg76ysSqDBK8NG3zwySRVnX36JwDQ6x+9GxzA== dependencies: - semver "^5.3.0" + semver "^6.3.0" nodemailer-html-to-text@^3.1.0: version "3.1.0" @@ -6218,15 +6270,15 @@ nodemailer-html-to-text@^3.1.0: dependencies: html-to-text "^5.1.1" -nodemailer@^6.4.1: - version "6.4.1" - resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.4.1.tgz#f70b40355b7b08f1f80344b353970a4f8f664370" - integrity sha512-mSQAzMim8XIC1DemK9TifDTIgASfoJEllG5aC1mEtZeZ+FQyrSOdGBRth6JRA1ERzHQCET3QHVSd9Kc6mh356g== +nodemailer@^6.4.2: + version "6.4.2" + resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.4.2.tgz#7147550e32cdc37453380ab78d2074533966090a" + integrity sha512-g0n4nH1ONGvqYo1v72uSWvF/MRNnnq1LzmSzXb/6EPF3LFb51akOhgG3K2+aETAsJx90/Q5eFNTntu4vBCwyQQ== -nodemon@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.1.tgz#cec436f8153ad5d3e6c27c304849a06cabea71cc" - integrity sha512-UC6FVhNLXjbbV4UzaXA3wUdbEkUZzLGgMGzmxvWAex5nzib/jhcSHVFlQODdbuUHq8SnnZ4/EABBAbC3RplvPg== +nodemon@~2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.2.tgz#9c7efeaaf9b8259295a97e5d4585ba8f0cbe50b0" + integrity sha512-GWhYPMfde2+M0FsHnggIHXTqPDHXia32HRhh6H0d75Mt9FKUoCBvumNHr7LdrpPBTKxsWmIEOjoN+P4IU6Hcaw== dependencies: chokidar "^3.2.2" debug "^3.2.6" @@ -6382,7 +6434,12 @@ object-hash@^2.0.0: resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.0.0.tgz#7c4cc341eb8b53367312a7c546142f00c9e0ea20" integrity sha512-I7zGBH0rDKwVGeGZpZoFaDhIwvJa3l1CZE+8VchylXbInNiCj7sxxea9P5dTM4ftKR5//nrqxrdeGSTWL2VpBA== -object-keys@^1.0.11, object-keys@^1.0.12: +object-inspect@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" + integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== + +object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== @@ -7259,7 +7316,7 @@ resolve@1.1.7: resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= -resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.0, resolve@^1.12.0, resolve@^1.3.2, resolve@^1.3.3, resolve@^1.5.0: +resolve@^1.10.0, resolve@^1.10.1, resolve@^1.12.0, resolve@^1.3.2, resolve@^1.3.3, resolve@^1.5.0: version "1.12.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.12.0.tgz#3fc644a35c84a48554609ff26ec52b66fa577df6" integrity sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w== @@ -7788,6 +7845,22 @@ string.prototype.padend@^3.0.0: es-abstract "^1.4.3" function-bind "^1.0.2" +string.prototype.trimleft@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz#6cc47f0d7eb8d62b0f3701611715a3954591d634" + integrity sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw== + dependencies: + define-properties "^1.1.3" + function-bind "^1.1.1" + +string.prototype.trimright@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz#669d164be9df9b6f7559fa8e89945b168a5a6c58" + integrity sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg== + dependencies: + define-properties "^1.1.3" + function-bind "^1.1.1" + string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" diff --git a/cypress.env.template.json b/cypress.env.template.json deleted file mode 100644 index 8eda47154..000000000 --- a/cypress.env.template.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "BACKEND_HOST": "http://localhost:4000", - "NEO4J_URI": "bolt://localhost:7687", - "NEO4J_USERNAME": "neo4j", - "NEO4J_PASSWORD": "letmein" -} diff --git a/cypress/README.md b/cypress/README.md index 2adcff925..662d0b51c 100644 --- a/cypress/README.md +++ b/cypress/README.md @@ -16,12 +16,7 @@ First, you have to tell cypress how to connect to your local neo4j database among other things. You can copy our template configuration and change the new file according to your needs. -Make sure you are at the root level of the project. Then: -```bash -# in the top level folder Human-Connection/ -$ cp cypress.env.template.json cypress.env.json -``` -To start the services that are required for cypress testing, run this: +To start the services that are required for cypress testing, run: ```bash # in the top level folder Human-Connection/ diff --git a/cypress/integration/common/post.js b/cypress/integration/common/post.js index 814159a34..a680986f4 100644 --- a/cypress/integration/common/post.js +++ b/cypress/integration/common/post.js @@ -3,6 +3,14 @@ import { When, Then } from "cypress-cucumber-preprocessor/steps"; const narratorAvatar = "https://s3.amazonaws.com/uifaces/faces/twitter/nerrsoft/128.jpg"; +When("I type in a comment with {int} characters", size => { + var c=""; + for (var i = 0; i < size; i++) { + c += "c" + } + cy.get(".editor .ProseMirror").type(c); +}); + Then("I click on the {string} button", text => { cy.get("button") .contains(text) @@ -23,6 +31,16 @@ Then("I should see my comment", () => { .should("contain", "today at"); }); +Then("I should see the entirety of my comment", () => { + cy.get("div.comment") + .should("not.contain", "show more") +}); + +Then("I should see an abreviated version of my comment", () => { + cy.get("div.comment") + .should("contain", "show more") +}); + Then("the editor should be cleared", () => { cy.get(".ProseMirror p").should("have.class", "is-empty"); }); diff --git a/cypress/integration/common/report.js b/cypress/integration/common/report.js index 9f62a2818..25f4c6e35 100644 --- a/cypress/integration/common/report.js +++ b/cypress/integration/common/report.js @@ -1,5 +1,6 @@ import { Given, When, Then } from 'cypress-cucumber-preprocessor/steps' import { VERSION } from '../../constants/terms-and-conditions-version.js' +import { gql } from '../../../backend/src/helpers/jest' /* global cy */ @@ -128,7 +129,7 @@ Given('somebody reported the following posts:', table => { cy.factory() .create('User', submitter) .authenticateAs(submitter) - .mutate(`mutation($resourceId: ID!, $reasonCategory: ReasonCategory!, $reasonDescription: String!) { + .mutate(gql`mutation($resourceId: ID!, $reasonCategory: ReasonCategory!, $reasonDescription: String!) { fileReport(resourceId: $resourceId, reasonCategory: $reasonCategory, reasonDescription: $reasonDescription) { id } diff --git a/cypress/integration/post/Comment.feature b/cypress/integration/post/Comment.feature index e7e462824..50284d6f5 100644 --- a/cypress/integration/post/Comment.feature +++ b/cypress/integration/post/Comment.feature @@ -20,3 +20,19 @@ Feature: Post Comment Then my comment should be successfully created And I should see my comment And the editor should be cleared + + Scenario: View medium length comments + Given I visit "post/bWBjpkTKZp/101-essays" + And I type in a comment with 305 characters + And I click on the "Comment" button + Then my comment should be successfully created + And I should see the entirety of my comment + And the editor should be cleared + + Scenario: View long comments + Given I visit "post/bWBjpkTKZp/101-essays" + And I type in a comment with 1205 characters + And I click on the "Comment" button + Then my comment should be successfully created + And I should see an abreviated version of my comment + And the editor should be cleared diff --git a/cypress/support/commands.js b/cypress/support/commands.js index f8bc76d50..f52b38faf 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -18,8 +18,8 @@ import helpers from "./helpers"; import users from "../fixtures/users.json"; import { GraphQLClient, request } from 'graphql-request' import { gql } from '../../backend/src/helpers/jest' +import config from '../../backend/src/config' -const backendHost = Cypress.env('BACKEND_HOST') const switchLang = name => { cy.get(".locale-menu").click(); cy.contains(".locale-menu-popover a", name).click(); @@ -31,7 +31,7 @@ const authenticatedHeaders = async (variables) => { login(email: $email, password: $password) } ` - const response = await request(backendHost, mutation, variables) + const response = await request(config.GRAPHQL_URI, mutation, variables) return { authorization: `Bearer ${response.login}` } } @@ -100,8 +100,7 @@ Cypress.Commands.add( 'authenticateAs', async ({email, password}) => { const headers = await authenticatedHeaders({ email, password }) - console.log(headers) - return new GraphQLClient(backendHost, { headers }) + return new GraphQLClient(config.GRAPHQL_URI, { headers }) } ) diff --git a/cypress/support/factories.js b/cypress/support/factories.js index da67debd5..234584e09 100644 --- a/cypress/support/factories.js +++ b/cypress/support/factories.js @@ -1,16 +1,10 @@ import Factory from '../../backend/src/seed/factories' -import { getDriver, neode as getNeode } from '../../backend/src/bootstrap/neo4j' -import setupNeode from '../../backend/src/bootstrap/neode' +import { getDriver, getNeode } from '../../backend/src/bootstrap/neo4j' import neode from 'neode' -const backendHost = Cypress.env('SEED_SERVER_HOST') -const neo4jConfigs = { - uri: Cypress.env('NEO4J_URI'), - username: Cypress.env('NEO4J_USERNAME'), - password: Cypress.env('NEO4J_PASSWORD') -} -const neo4jDriver = getDriver(neo4jConfigs) -const factoryOptions = { seedServerHost: backendHost, neo4jDriver, neodeInstance: setupNeode(neo4jConfigs)} +const neo4jDriver = getDriver() +const neodeInstance = getNeode() +const factoryOptions = { neo4jDriver, neodeInstance } const factory = Factory(factoryOptions) beforeEach(async () => { @@ -18,7 +12,7 @@ beforeEach(async () => { }) Cypress.Commands.add('neode', () => { - return setupNeode(neo4jConfigs) + return neodeInstance }) Cypress.Commands.add( 'first', diff --git a/package.json b/package.json index d20232f20..8d8c53f71 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "human-connection", - "version": "0.1.11", + "version": "0.1.12", "description": "Fullstack and API tests with cypress and cucumber for Human Connection", "author": "Human Connection gGmbh", "license": "MIT", @@ -21,8 +21,8 @@ "version": "auto-changelog -p" }, "devDependencies": { - "@babel/core": "^7.7.2", - "@babel/preset-env": "^7.7.4", + "@babel/core": "^7.7.5", + "@babel/preset-env": "^7.7.6", "@babel/register": "^7.7.4", "auto-changelog": "^1.16.2", "bcryptjs": "^2.4.3", @@ -31,7 +31,7 @@ "cucumber": "^6.0.5", "cypress": "^3.7.0", "cypress-cucumber-preprocessor": "^1.18.0", - "cypress-file-upload": "^3.5.0", + "cypress-file-upload": "^3.5.1", "cypress-plugin-retries": "^1.5.0", "date-fns": "^2.8.1", "dotenv": "^8.2.0", diff --git a/scripts/docker_push.sh b/scripts/docker_push.sh index 58f593a16..b342278b9 100755 --- a/scripts/docker_push.sh +++ b/scripts/docker_push.sh @@ -1,11 +1,10 @@ #!/usr/bin/env bash ROOT_DIR=$(dirname "$0")/.. -DOCKER_CLI_EXPERIMENTAL=enabled # BUILD_COMMIT=${TRAVIS_COMMIT:-$(git rev-parse HEAD)} IFS='.' read -r major minor patch < $ROOT_DIR/VERSION apps=(nitro-web nitro-backend neo4j maintenance) -tags=(latest $major $major.$minor $major.$minor.$patch) +tags=($major $major.$minor $major.$minor.$patch) # These three docker images have already been built by now: # docker build --build-arg BUILD_COMMIT=$BUILD_COMMIT --target production -t humanconnection/nitro-backend:latest $ROOT_DIR/backend @@ -17,13 +16,17 @@ echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin for app in "${apps[@]}" do + SOURCE="humanconnection/${app}:latest" + echo "docker push $SOURCE" + docker push $SOURCE + for tag in "${tags[@]}" do - SOURCE="humanconnection/${app}:latest" TARGET="humanconnection/${app}:${tag}" - if docker manifest inspect $TARGET &> /dev/null; then - echo "Docker image ${TARGET} already present, skipping ..." + if DOCKER_CLI_EXPERIMENTAL=enabled docker manifest inspect $TARGET >/dev/null; then + echo "docker image ${TARGET} already present, skipping ..." else + echo -e "docker tag $SOURCE $TARGET\ndocker push $TARGET" docker tag $SOURCE $TARGET docker push $TARGET fi diff --git a/webapp/README.md b/webapp/README.md index 185557fc7..897bb56ca 100644 --- a/webapp/README.md +++ b/webapp/README.md @@ -6,14 +6,15 @@ ```bash # install all dependencies +$ cd webapp/ $ yarn install ``` Copy: ```text +# in webapp/ cp .env.template .env -cp cypress.env.template.json cypress.env.json ``` Configure the files according to your needs and your local setup. diff --git a/webapp/components/MasonryGrid/MasonryGridItem.spec.js b/webapp/components/MasonryGrid/MasonryGridItem.spec.js index d37be8d58..66b0607fd 100644 --- a/webapp/components/MasonryGrid/MasonryGridItem.spec.js +++ b/webapp/components/MasonryGrid/MasonryGridItem.spec.js @@ -1,4 +1,4 @@ -import { config, mount } from '@vue/test-utils' +import { config, shallowMount } from '@vue/test-utils' import MasonryGridItem from './MasonryGridItem' const localVue = global.localVue @@ -8,41 +8,24 @@ config.stubs['ds-grid-item'] = '' describe('MasonryGridItem', () => { let wrapper - describe('given an imageAspectRatio', () => { - it('sets the initial rowSpan to 13 when the ratio is higher than 1.3', () => { - const propsData = { imageAspectRatio: 2 } - wrapper = mount(MasonryGridItem, { localVue, propsData }) - - expect(wrapper.vm.rowSpan).toBe(13) - }) - - it('sets the initial rowSpan to 15 when the ratio is between 1.3 and 1', () => { - const propsData = { imageAspectRatio: 1.1 } - wrapper = mount(MasonryGridItem, { localVue, propsData }) - - expect(wrapper.vm.rowSpan).toBe(15) - }) - - it('sets the initial rowSpan to 18 when the ratio is between 1 and 0.7', () => { - const propsData = { imageAspectRatio: 0.7 } - wrapper = mount(MasonryGridItem, { localVue, propsData }) - - expect(wrapper.vm.rowSpan).toBe(18) - }) - - it('sets the initial rowSpan to 25 when the ratio is lower than 0.7', () => { - const propsData = { imageAspectRatio: 0.3 } - wrapper = mount(MasonryGridItem, { localVue, propsData }) - - expect(wrapper.vm.rowSpan).toBe(25) - }) + beforeEach(() => { + wrapper = shallowMount(MasonryGridItem, { localVue }) + wrapper.vm.$parent.$emit = jest.fn() }) - describe('given no aspect ratio', () => { - it('sets the initial rowSpan to 8 when not given an imageAspectRatio', () => { - wrapper = mount(MasonryGridItem, { localVue }) + it('emits "calculating-item-height" when starting calculation', async () => { + wrapper.vm.calculateItemHeight() + await wrapper.vm.$nextTick() - expect(wrapper.vm.rowSpan).toBe(8) - }) + const firstCallArgument = wrapper.vm.$parent.$emit.mock.calls[0][0] + expect(firstCallArgument).toBe('calculating-item-height') + }) + + it('emits "finished-calculating-item-height" after the calculation', async () => { + wrapper.vm.calculateItemHeight() + await wrapper.vm.$nextTick() + + const secondCallArgument = wrapper.vm.$parent.$emit.mock.calls[1][0] + expect(secondCallArgument).toBe('finished-calculating-item-height') }) }) diff --git a/webapp/components/MasonryGrid/MasonryGridItem.vue b/webapp/components/MasonryGrid/MasonryGridItem.vue index 91fb8a1d8..937da8f1f 100644 --- a/webapp/components/MasonryGrid/MasonryGridItem.vue +++ b/webapp/components/MasonryGrid/MasonryGridItem.vue @@ -5,17 +5,6 @@ diff --git a/webapp/components/PostCard/PostCard.vue b/webapp/components/PostCard/PostCard.vue index 79ba9e8f0..d5afe90e1 100644 --- a/webapp/components/PostCard/PostCard.vue +++ b/webapp/components/PostCard/PostCard.vue @@ -141,19 +141,10 @@ export default { this.$emit('unpinPost', post) }, }, - mounted() { - const width = this.$el.offsetWidth - const height = Math.min(width / this.post.imageAspectRatio, 2000) - const imageElement = this.$el.querySelector('.ds-card-image') - - if (imageElement) { - imageElement.style.height = `${height}px` - } - }, } -