diff --git a/.travis.yml b/.travis.yml index 19ba3ff9d..d3391ae4c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,6 @@ addons: - libgconf-2-4 snaps: - docker - - chromium install: - yarn global add wait-on diff --git a/CHANGELOG.md b/CHANGELOG.md index 8decb1329..a67694579 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,106 @@ 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.2.2](https://github.com/Human-Connection/Human-Connection/compare/v0.2.1...v0.2.2) + +> 20 January 2020 + +- build(deps): bump metascraper-title from 5.10.3 to 5.10.5 in /backend [`#2835`](https://github.com/Human-Connection/Human-Connection/pull/2835) +- build(deps): bump metascraper-publisher in /backend [`#2836`](https://github.com/Human-Connection/Human-Connection/pull/2836) +- build(deps): bump metascraper-audio from 5.10.3 to 5.10.5 in /backend [`#2840`](https://github.com/Human-Connection/Human-Connection/pull/2840) +- build(deps): bump metascraper-author from 5.10.3 to 5.10.5 in /backend [`#2838`](https://github.com/Human-Connection/Human-Connection/pull/2838) +- build(deps): bump metascraper-url from 5.10.3 to 5.10.5 in /backend [`#2832`](https://github.com/Human-Connection/Human-Connection/pull/2832) +- build(deps): bump metascraper-lang from 5.10.3 to 5.10.5 in /backend [`#2831`](https://github.com/Human-Connection/Human-Connection/pull/2831) +- refactor(modules): Various import fixes [`#2802`](https://github.com/Human-Connection/Human-Connection/pull/2802) +- build(deps): bump metascraper-description from 5.10.3 to 5.10.5 in /backend [`#2839`](https://github.com/Human-Connection/Human-Connection/pull/2839) +- build(deps-dev): bump @storybook/addon-notes from 5.3.5 to 5.3.6 in /webapp [`#2834`](https://github.com/Human-Connection/Human-Connection/pull/2834) +- build(deps): bump metascraper-youtube from 5.10.3 to 5.10.5 in /backend [`#2833`](https://github.com/Human-Connection/Human-Connection/pull/2833) +- build(deps): bump metascraper from 5.10.3 to 5.10.5 in /backend [`#2830`](https://github.com/Human-Connection/Human-Connection/pull/2830) +- build(deps): bump metascraper-soundcloud from 5.10.3 to 5.10.5 in /backend [`#2829`](https://github.com/Human-Connection/Human-Connection/pull/2829) +- fix(translations): Remove duplicate and mistranslated item from code of conduct [`#2725`](https://github.com/Human-Connection/Human-Connection/pull/2725) +- build(deps-dev): bump @storybook/addon-a11y from 5.3.3 to 5.3.6 in /webapp [`#2820`](https://github.com/Human-Connection/Human-Connection/pull/2820) +- build(deps): bump metascraper from 5.10.2 to 5.10.3 in /backend [`#2808`](https://github.com/Human-Connection/Human-Connection/pull/2808) +- build(deps-dev): bump @storybook/vue from 5.3.3 to 5.3.6 in /webapp [`#2819`](https://github.com/Human-Connection/Human-Connection/pull/2819) +- build(deps): bump faker from `9fd8d7d` to `3b2fa4a` in /backend [`#2803`](https://github.com/Human-Connection/Human-Connection/pull/2803) +- build(deps-dev): bump faker from `9fd8d7d` to `3b2fa4a` [`#2804`](https://github.com/Human-Connection/Human-Connection/pull/2804) +- build(deps-dev): bump @storybook/addon-a11y in /webapp [`#2809`](https://github.com/Human-Connection/Human-Connection/pull/2809) +- build(deps): bump uuid from 3.3.3 to 3.4.0 in /backend [`#2810`](https://github.com/Human-Connection/Human-Connection/pull/2810) +- build(deps): bump metascraper-image from 5.9.5 to 5.10.3 in /backend [`#2811`](https://github.com/Human-Connection/Human-Connection/pull/2811) +- build(deps-dev): bump node-sass from 4.13.0 to 4.13.1 in /webapp [`#2812`](https://github.com/Human-Connection/Human-Connection/pull/2812) +- build(deps): bump metascraper-audio from 5.9.5 to 5.10.3 in /backend [`#2813`](https://github.com/Human-Connection/Human-Connection/pull/2813) +- build(deps): bump metascraper-soundcloud in /backend [`#2815`](https://github.com/Human-Connection/Human-Connection/pull/2815) +- build(deps-dev): bump @storybook/addon-notes in /webapp [`#2816`](https://github.com/Human-Connection/Human-Connection/pull/2816) +- build(deps-dev): bump @storybook/addon-actions from 5.3.3 to 5.3.5 in /webapp [`#2807`](https://github.com/Human-Connection/Human-Connection/pull/2807) +- build(deps): bump metascraper-description from 5.9.5 to 5.10.3 in /backend [`#2806`](https://github.com/Human-Connection/Human-Connection/pull/2806) +- build(deps): bump mustache from 3.2.1 to 4.0.0 in /backend [`#2805`](https://github.com/Human-Connection/Human-Connection/pull/2805) +- 🍰 feat(webapp): Display deployed version in footer [`#2728`](https://github.com/Human-Connection/Human-Connection/pull/2728) +- fix: cypress breaks locally in login step [`#2776`](https://github.com/Human-Connection/Human-Connection/pull/2776) +- build(deps-dev): bump @vue/test-utils from 1.0.0-beta.29 to 1.0.0-beta.30 in /webapp [`#2378`](https://github.com/Human-Connection/Human-Connection/pull/2378) +- build(deps): bump metascraper-youtube from 5.9.5 to 5.10.3 in /backend [`#2794`](https://github.com/Human-Connection/Human-Connection/pull/2794) +- build(deps): bump metascraper-video from 5.9.5 to 5.10.3 in /backend [`#2795`](https://github.com/Human-Connection/Human-Connection/pull/2795) +- build(deps): bump metascraper-logo from 5.9.5 to 5.10.3 in /backend [`#2796`](https://github.com/Human-Connection/Human-Connection/pull/2796) +- refactor(styleguide): improve emotion buttons and header responsiveness [`#2582`](https://github.com/Human-Connection/Human-Connection/pull/2582) +- build(deps): bump metascraper-url from 5.9.5 to 5.10.3 in /backend [`#2793`](https://github.com/Human-Connection/Human-Connection/pull/2793) +- build(deps): bump metascraper-author from 5.9.5 to 5.10.3 in /backend [`#2789`](https://github.com/Human-Connection/Human-Connection/pull/2789) +- build(deps): bump metascraper-lang from 5.9.5 to 5.10.3 in /backend [`#2790`](https://github.com/Human-Connection/Human-Connection/pull/2790) +- build(deps): bump metascraper-publisher from 5.9.5 to 5.10.3 in /backend [`#2792`](https://github.com/Human-Connection/Human-Connection/pull/2792) +- build(deps): bump metascraper-title from 5.9.5 to 5.10.3 in /backend [`#2791`](https://github.com/Human-Connection/Human-Connection/pull/2791) +- build(deps): bump @sentry/node from 5.11.0 to 5.11.1 in /backend [`#2788`](https://github.com/Human-Connection/Human-Connection/pull/2788) +- build(deps): bump metascraper-date from 5.9.5 to 5.10.3 in /backend [`#2787`](https://github.com/Human-Connection/Human-Connection/pull/2787) +- build(deps-dev): bump @babel/node from 7.8.0 to 7.8.3 in /backend [`#2754`](https://github.com/Human-Connection/Human-Connection/pull/2754) +- refactor(styleguide): migrate and redesign buttons [`#2562`](https://github.com/Human-Connection/Human-Connection/pull/2562) +- build(deps-dev): bump @babel/core from 7.8.0 to 7.8.3 in /backend [`#2760`](https://github.com/Human-Connection/Human-Connection/pull/2760) +- build(deps-dev): bump @storybook/addon-actions from 5.3.2 to 5.3.3 in /webapp [`#2782`](https://github.com/Human-Connection/Human-Connection/pull/2782) +- build(deps-dev): bump sass-loader from 8.0.0 to 8.0.2 in /webapp [`#2781`](https://github.com/Human-Connection/Human-Connection/pull/2781) +- build(deps-dev): bump @babel/plugin-syntax-dynamic-import from 7.8.0 to 7.8.3 in /webapp [`#2780`](https://github.com/Human-Connection/Human-Connection/pull/2780) +- build(deps-dev): bump @storybook/addon-a11y from 5.3.2 to 5.3.3 in /webapp [`#2779`](https://github.com/Human-Connection/Human-Connection/pull/2779) +- build(deps): bump metascraper from 5.9.5 to 5.10.2 in /backend [`#2778`](https://github.com/Human-Connection/Human-Connection/pull/2778) +- build(deps-dev): bump @babel/preset-env from 7.7.7 to 7.8.3 in /webapp [`#2767`](https://github.com/Human-Connection/Human-Connection/pull/2767) +- build(deps-dev): bump @babel/plugin-proposal-throw-expressions from 7.8.0 to 7.8.3 in /backend [`#2757`](https://github.com/Human-Connection/Human-Connection/pull/2757) +- build(deps-dev): bump @storybook/vue from 5.3.1 to 5.3.3 in /webapp [`#2772`](https://github.com/Human-Connection/Human-Connection/pull/2772) +- build(deps-dev): bump @babel/preset-env from 7.8.2 to 7.8.3 [`#2758`](https://github.com/Human-Connection/Human-Connection/pull/2758) +- build(deps-dev): bump eslint-plugin-import from 2.19.1 to 2.20.0 in /webapp [`#2748`](https://github.com/Human-Connection/Human-Connection/pull/2748) +- build(deps-dev): bump @storybook/addon-notes from 5.3.1 to 5.3.3 in /webapp [`#2771`](https://github.com/Human-Connection/Human-Connection/pull/2771) +- build(deps-dev): bump @babel/core from 7.7.7 to 7.8.3 in /webapp [`#2769`](https://github.com/Human-Connection/Human-Connection/pull/2769) +- build(deps-dev): bump @babel/register from 7.8.0 to 7.8.3 [`#2764`](https://github.com/Human-Connection/Human-Connection/pull/2764) +- build(deps-dev): bump @babel/preset-env from 7.8.2 to 7.8.3 in /backend [`#2755`](https://github.com/Human-Connection/Human-Connection/pull/2755) +- build(deps-dev): bump eslint-plugin-jest from 23.3.0 to 23.6.0 in /webapp [`#2768`](https://github.com/Human-Connection/Human-Connection/pull/2768) +- build(deps-dev): bump @babel/cli from 7.8.0 to 7.8.3 in /backend [`#2763`](https://github.com/Human-Connection/Human-Connection/pull/2763) +- build(deps-dev): bump cypress-cucumber-preprocessor from 1.19.0 to 2.0.1 [`#2761`](https://github.com/Human-Connection/Human-Connection/pull/2761) +- build(deps-dev): bump @storybook/addon-a11y from 5.2.8 to 5.3.2 in /webapp [`#2759`](https://github.com/Human-Connection/Human-Connection/pull/2759) +- build(deps-dev): bump @babel/core from 7.8.0 to 7.8.3 [`#2756`](https://github.com/Human-Connection/Human-Connection/pull/2756) +- build(deps-dev): bump @babel/register from 7.8.0 to 7.8.3 in /backend [`#2753`](https://github.com/Human-Connection/Human-Connection/pull/2753) +- build(deps): [security] bump serialize-javascript from 2.1.0 to 2.1.2 in /webapp [`#2752`](https://github.com/Human-Connection/Human-Connection/pull/2752) +- build(deps-dev): bump @babel/core from 7.7.7 to 7.8.0 in /backend [`#2743`](https://github.com/Human-Connection/Human-Connection/pull/2743) +- build(deps-dev): bump @storybook/addon-actions from 5.2.8 to 5.3.2 in /webapp [`#2751`](https://github.com/Human-Connection/Human-Connection/pull/2751) +- build(deps-dev): bump @babel/register from 7.7.7 to 7.8.0 in /backend [`#2735`](https://github.com/Human-Connection/Human-Connection/pull/2735) +- build(deps-dev): bump @babel/plugin-syntax-dynamic-import from 7.7.4 to 7.8.0 in /webapp [`#2746`](https://github.com/Human-Connection/Human-Connection/pull/2746) +- build(deps-dev): bump @babel/preset-env from 7.7.7 to 7.8.2 in /backend [`#2739`](https://github.com/Human-Connection/Human-Connection/pull/2739) +- build(deps-dev): bump @babel/cli from 7.7.7 to 7.8.0 in /backend [`#2744`](https://github.com/Human-Connection/Human-Connection/pull/2744) +- Issues marked as bounty never become stale [`#2726`](https://github.com/Human-Connection/Human-Connection/pull/2726) +- build(deps-dev): bump css-loader from 3.4.1 to 3.4.2 in /webapp [`#2747`](https://github.com/Human-Connection/Human-Connection/pull/2747) +- build(deps-dev): bump @storybook/addon-notes from 5.2.8 to 5.3.1 in /webapp [`#2742`](https://github.com/Human-Connection/Human-Connection/pull/2742) +- build(deps-dev): bump @babel/plugin-proposal-throw-expressions from 7.7.4 to 7.8.0 in /backend [`#2741`](https://github.com/Human-Connection/Human-Connection/pull/2741) +- build(deps-dev): bump eslint-plugin-import from 2.19.1 to 2.20.0 in /backend [`#2737`](https://github.com/Human-Connection/Human-Connection/pull/2737) +- build(deps-dev): bump @babel/preset-env from 7.7.7 to 7.8.2 [`#2732`](https://github.com/Human-Connection/Human-Connection/pull/2732) +- build(deps): bump @nuxtjs/axios from 5.9.2 to 5.9.3 in /webapp [`#2740`](https://github.com/Human-Connection/Human-Connection/pull/2740) +- build(deps-dev): bump @storybook/vue from 5.2.8 to 5.3.1 in /webapp [`#2738`](https://github.com/Human-Connection/Human-Connection/pull/2738) +- build(deps-dev): bump cypress from 3.8.1 to 3.8.2 [`#2734`](https://github.com/Human-Connection/Human-Connection/pull/2734) +- build(deps-dev): bump @babel/node from 7.7.7 to 7.8.0 in /backend [`#2733`](https://github.com/Human-Connection/Human-Connection/pull/2733) +- build(deps-dev): bump eslint-plugin-jest from 23.3.0 to 23.6.0 in /backend [`#2731`](https://github.com/Human-Connection/Human-Connection/pull/2731) +- build(deps-dev): bump @babel/core from 7.7.7 to 7.8.0 [`#2730`](https://github.com/Human-Connection/Human-Connection/pull/2730) +- build(deps-dev): bump @babel/register from 7.7.7 to 7.8.0 [`#2729`](https://github.com/Human-Connection/Human-Connection/pull/2729) +- build(deps): bump nuxt from 2.10.2 to 2.11.0 in /webapp [`#2552`](https://github.com/Human-Connection/Human-Connection/pull/2552) +- Update yarn.lock after dependabot update [`#2724`](https://github.com/Human-Connection/Human-Connection/pull/2724) +- build(deps): bump @nuxtjs/axios from 5.8.0 to 5.9.2 in /webapp [`#2657`](https://github.com/Human-Connection/Human-Connection/pull/2657) +- Update to version 0.2.1 [`#2722`](https://github.com/Human-Connection/Human-Connection/pull/2722) +- refactor(modules): Various import fixes [`#2773`](https://github.com/Human-Connection/Human-Connection/issues/2773) [`#2774`](https://github.com/Human-Connection/Human-Connection/issues/2774) +- feat(webapp): Display deployed version in footer [`#1831`](https://github.com/Human-Connection/Human-Connection/issues/1831) +- fix #2229 [`#2229`](https://github.com/Human-Connection/Human-Connection/issues/2229) +- build(deps-dev): bump @storybook/addon-actions in /webapp [`d0124bf`](https://github.com/Human-Connection/Human-Connection/commit/d0124bf2b4b4a641c9af76d6d2f7b5aa075ade90) +- refactor and use base-button in SearchableInput [`fcbe612`](https://github.com/Human-Connection/Human-Connection/commit/fcbe6125f35c0dd23e2ba1ae63f539f5ef5990ea) +- Update `vue-test-utils` and follow updated docs [`8c29ad9`](https://github.com/Human-Connection/Human-Connection/commit/8c29ad947b72fbaa173d070221cdf35b7ab6aaa5) + #### [v0.2.1](https://github.com/Human-Connection/Human-Connection/compare/v0.2.0...v0.2.1) > 10 January 2020 @@ -107,16 +207,16 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). - build(deps): bump metascraper-publisher from 5.8.7 to 5.8.12 in /backend [`#2592`](https://github.com/Human-Connection/Human-Connection/pull/2592) - build(deps-dev): bump @babel/preset-env from 7.7.6 to 7.7.7 in /backend [`#2568`](https://github.com/Human-Connection/Human-Connection/pull/2568) - Fix imageAspectRatio set to null UpdatePost [`#2588`](https://github.com/Human-Connection/Human-Connection/pull/2588) -- Update to version 0.2.0 [`#2584`](https://github.com/Human-Connection/Human-Connection/pull/2584) - fixes #2659 [`#2659`](https://github.com/Human-Connection/Human-Connection/issues/2659) - build(deps-dev): bump storybook-design-token in /webapp [`88d39c4`](https://github.com/Human-Connection/Human-Connection/commit/88d39c4a427cb86527b06201f3f5e96d53ac09a0) +- manage button states and color schemes with mixin [`1b9249c`](https://github.com/Human-Connection/Human-Connection/commit/1b9249c685e34eb2e94b31ee0ec22421c6aa6a73) - Specs for Searches [`bc3aa51`](https://github.com/Human-Connection/Human-Connection/commit/bc3aa519d0e7a6e0242ecd37d611fd1a3df385d0) -- build(deps): bump apollo-server-express in /backend [`84df7b5`](https://github.com/Human-Connection/Human-Connection/commit/84df7b5a0a4845ab44d19946d877aef79691d38e) #### [v0.2.0](https://github.com/Human-Connection/Human-Connection/compare/v0.1.13...v0.2.0) > 19 December 2019 +- Update to version 0.2.0 [`#2584`](https://github.com/Human-Connection/Human-Connection/pull/2584) - build(deps): bump metascraper-image from 5.8.10 to 5.8.12 in /backend [`#2556`](https://github.com/Human-Connection/Human-Connection/pull/2556) - build(deps-dev): bump @babel/core from 7.7.5 to 7.7.7 [`#2569`](https://github.com/Human-Connection/Human-Connection/pull/2569) - build(deps-dev): bump @babel/cli from 7.7.5 to 7.7.7 in /backend [`#2576`](https://github.com/Human-Connection/Human-Connection/pull/2576) @@ -203,7 +303,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). - Fix search by adding result id [`ebc5cf3`](https://github.com/Human-Connection/Human-Connection/commit/ebc5cf392d92acf3a9e22c8967d02ea2cf6fd7fb) - Write test/refactor tests/resolvers/middleware [`d375ebe`](https://github.com/Human-Connection/Human-Connection/commit/d375ebe7d90e3251b17f59ffba8fb1470923ebe8) -#### [v0.1.12](https://github.com/Human-Connection/Human-Connection/compare/v0.1.10...v0.1.12) +#### [v0.1.12](https://github.com/Human-Connection/Human-Connection/compare/v0.1.11...v0.1.12) > 10 December 2019 @@ -313,6 +413,16 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). - 2329 normalize emails in login form [`#2330`](https://github.com/Human-Connection/Human-Connection/pull/2330) - Lokalise: Translations update [`#2327`](https://github.com/Human-Connection/Human-Connection/pull/2327) - Changed translation must change test :( [`#2310`](https://github.com/Human-Connection/Human-Connection/pull/2310) +- 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) +- Lokalise: update of webapp/locales/ru.json [`3e52ee0`](https://github.com/Human-Connection/Human-Connection/commit/3e52ee090c88c357b796895370d126f8bb5529f0) +- Lokalise: update of webapp/locales/de.json [`d2b3396`](https://github.com/Human-Connection/Human-Connection/commit/d2b3396e9b44bac0e767ee970e083d1847426b26) +- Lokalise: update of webapp/locales/pt.json [`bcd9f0e`](https://github.com/Human-Connection/Human-Connection/commit/bcd9f0ec93cfab2661589d72a3b3f38455ec4d51) + +#### [v0.1.11](https://github.com/Human-Connection/Human-Connection/compare/v0.1.10...v0.1.11) + +> 22 November 2019 + - build(deps-dev): bump apollo-server-testing from 2.9.9 to 2.9.12 in /backend [`#2318`](https://github.com/Human-Connection/Human-Connection/pull/2318) - build(deps-dev): bump fuse.js from 3.4.5 to 3.4.6 in /webapp [`#2314`](https://github.com/Human-Connection/Human-Connection/pull/2314) - build(deps-dev): bump eslint-config-prettier from 6.6.0 to 6.7.0 in /webapp [`#2302`](https://github.com/Human-Connection/Human-Connection/pull/2302) @@ -362,13 +472,11 @@ 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) -- Move components to components/features [`2357028`](https://github.com/Human-Connection/Human-Connection/commit/235702867d97b44dac37f8059f9194e23ba7f47d) -- Basic Search Is Working For Users And Posts [`72e4d0a`](https://github.com/Human-Connection/Human-Connection/commit/72e4d0abbcb9abab07f3fd12876453eb1de5da4c) -- Add missing unit tests/refactor code [`b364065`](https://github.com/Human-Connection/Human-Connection/commit/b3640659bb608cc34edc6f2aca350f07dd2b9ce6) +- 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) +- set up global localVue [`77f4810`](https://github.com/Human-Connection/Human-Connection/commit/77f4810ddc963386bc68d3e8a5e078ef4cf270b2) #### [v0.1.10](https://github.com/Human-Connection/Human-Connection/compare/v0.1.9...v0.1.10) @@ -428,8 +536,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) -- 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) +- 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) #### [v0.1.9](https://github.com/Human-Connection/Human-Connection/compare/v0.1.8...v0.1.9) @@ -497,9 +605,9 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). - 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) -#### [v0.1.8](https://github.com/Human-Connection/Human-Connection/compare/0.1.7...v0.1.8) +#### [v0.1.8](https://github.com/Human-Connection/Human-Connection/compare/v0.1.7...v0.1.8) -> 25 October 2019 +> 24 October 2019 - add FAQ _blank-href in Footer [`#2028`](https://github.com/Human-Connection/Human-Connection/pull/2028) - fix: Don't attempt to save locale if not authenticated [`#2025`](https://github.com/Human-Connection/Human-Connection/pull/2025) @@ -515,11 +623,11 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). - build(deps-dev): bump @storybook/addon-a11y from 5.2.4 to 5.2.5 in /webapp [`#1989`](https://github.com/Human-Connection/Human-Connection/pull/1989) - build(deps-dev): bump @vue/cli-shared-utils from 4.0.4 to 4.0.5 in /webapp [`#2002`](https://github.com/Human-Connection/Human-Connection/pull/2002) - 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) - Finish redesign of moderators report list [`15d28aa`](https://github.com/Human-Connection/Human-Connection/commit/15d28aa8ef84788aa640aac67838380bfacf63b7) +- build(deps-dev): bump @storybook/addon-actions in /webapp [`7e95d37`](https://github.com/Human-Connection/Human-Connection/commit/7e95d376a311a5ede6351d577d30e25aea9cb65d) -#### [0.1.7](https://github.com/Human-Connection/Human-Connection/compare/0.1.6...0.1.7) +#### [v0.1.7](https://github.com/Human-Connection/Human-Connection/compare/v0.1.6...v0.1.7) > 23 October 2019 @@ -535,7 +643,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). - build(deps-dev): bump @vue/cli-shared-utils in /webapp [`a5d993c`](https://github.com/Human-Connection/Human-Connection/commit/a5d993c761b2f92c3f44b6f83592ea4c1d822606) - Fix block user workflow [`44e5437`](https://github.com/Human-Connection/Human-Connection/commit/44e54372c4148fafae1095d172d1a52a87b3b1b2) -#### [0.1.6](https://github.com/Human-Connection/Human-Connection/compare/0.1.5...0.1.6) +#### [v0.1.6](https://github.com/Human-Connection/Human-Connection/compare/v0.1.5...v0.1.6) > 22 October 2019 @@ -569,7 +677,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). - Refactor tests for querying reported resources [`4e42017`](https://github.com/Human-Connection/Human-Connection/commit/4e42017afaa97fa87ec726a5bbd1605cca911375) - Return pinnedAt date from pinPost resolver/clean up [`be0c804`](https://github.com/Human-Connection/Human-Connection/commit/be0c8044e87e211f2578df151d9d2d11795a135f) -#### [0.1.5](https://github.com/Human-Connection/Human-Connection/compare/0.1.4...0.1.5) +#### [v0.1.5](https://github.com/Human-Connection/Human-Connection/compare/v0.1.4...v0.1.5) > 17 October 2019 @@ -627,7 +735,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). - Start adding missing portuguese translation [`33eb000`](https://github.com/Human-Connection/Human-Connection/commit/33eb000ee33e5aa513083450f0a00abd7240efb0) - refactor: restructure translations and components [`bb5d581`](https://github.com/Human-Connection/Human-Connection/commit/bb5d581906b5e6e723966c3dc687c7f309356841) -#### [0.1.4](https://github.com/Human-Connection/Human-Connection/compare/0.1.3...0.1.4) +#### [v0.1.4](https://github.com/Human-Connection/Human-Connection/compare/v0.1.3...v0.1.4) > 10 October 2019 @@ -665,7 +773,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). - Fix lint, update tests [`bced698`](https://github.com/Human-Connection/Human-Connection/commit/bced6983ea1f51736e989eab6a41166723a6a6ca) - add test embeds and links [`7cc139e`](https://github.com/Human-Connection/Human-Connection/commit/7cc139e879ac7ea912e82ea7eff14f7b67eddb4a) -#### [0.1.3](https://github.com/Human-Connection/Human-Connection/compare/0.1.2...0.1.3) +#### [v0.1.3](https://github.com/Human-Connection/Human-Connection/compare/v0.1.2...v0.1.3) > 4 October 2019 @@ -685,7 +793,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). - Set hasMore to false when returned Posts are equal to pageSize [`6f1c5e3`](https://github.com/Human-Connection/Human-Connection/commit/6f1c5e3efa3b77e72172592a0b5e4ea52158e642) - refactor: use named slot for additional text [`3912b21`](https://github.com/Human-Connection/Human-Connection/commit/3912b21ea2f24e2e25682060b7166d1511442e6e) -#### [0.1.2](https://github.com/Human-Connection/Human-Connection/compare/0.1.1...0.1.2) +#### [v0.1.2](https://github.com/Human-Connection/Human-Connection/compare/v0.1.1...v0.1.2) > 2 October 2019 @@ -744,7 +852,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). - build(deps): bump @nuxtjs/apollo in /webapp [`4648080`](https://github.com/Human-Connection/Human-Connection/commit/4648080a74fa6df60d6bb9b34d1db5030a9d4124) - Write and refactor backend test which are supposed to fail at first [`6ad9dc2`](https://github.com/Human-Connection/Human-Connection/commit/6ad9dc27e937eb263914846c073172906aa661e1) -#### [0.1.1](https://github.com/Human-Connection/Human-Connection/compare/0.1.0...0.1.1) +#### [v0.1.1](https://github.com/Human-Connection/Human-Connection/compare/v0.1.0...v0.1.1) > 27 September 2019 @@ -818,7 +926,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). - Run with tag 0.1.0 [`c634ad2`](https://github.com/Human-Connection/Human-Connection/commit/c634ad264bd99dd1a87a86f870d7877aa751dc38) - zwischenspeichern [`e4c7c11`](https://github.com/Human-Connection/Human-Connection/commit/e4c7c1125da6f8fa259241b4d3838b1e7b1e24a2) -#### 0.1.0 +#### v0.1.0 > 18 September 2019 @@ -1956,5 +2064,5 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). - Merge pull request #93 from Gerald1614/500_error_on_login [`#49`](https://github.com/Human-Connection/Human-Connection/issues/49) - Update schema.graphql [`#7`](https://github.com/Human-Connection/Human-Connection/issues/7) - Refactore the import and hashtags to all unicode characters [`0bc4c55`](https://github.com/Human-Connection/Human-Connection/commit/0bc4c558ae8f01d6d975b8ee1ea7f0f42b056d91) -- Change strategy, only build docker image [`d6b7374`](https://github.com/Human-Connection/Human-Connection/commit/d6b7374ddbf497bdb5cbc935b88ae085c38b3237) -- Copy package.json from webapp/ [`f3a9996`](https://github.com/Human-Connection/Human-Connection/commit/f3a9996962e5dd8b2e365a032c1a5766fe666103) +- Remove package-lock.json [`25bd96e`](https://github.com/Human-Connection/Human-Connection/commit/25bd96eedf6be5b7ea6e94c8433d044e13d62e70) +- Remove Styleguide [`53ea934`](https://github.com/Human-Connection/Human-Connection/commit/53ea93492dcc7f861743cd50a4ddf7728c9d659b) diff --git a/backend/package.json b/backend/package.json index e07f8387e..a6504cc3d 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "human-connection-backend", - "version": "0.2.1", + "version": "0.2.2", "description": "GraphQL Backend for Human Connection", "main": "src/index.js", "scripts": { @@ -32,7 +32,7 @@ ] }, "dependencies": { - "@hapi/joi": "^17.0.2", + "@hapi/joi": "^17.1.0", "@sentry/node": "^5.11.1", "apollo-cache-inmemory": "~1.6.5", "apollo-client": "~2.6.8", @@ -63,20 +63,20 @@ "lodash": "~4.17.14", "merge-graphql-schemas": "^1.7.6", "metascraper": "^5.10.5", - "metascraper-audio": "^5.10.3", - "metascraper-author": "^5.10.3", + "metascraper-audio": "^5.10.5", + "metascraper-author": "^5.10.5", "metascraper-clearbit-logo": "^5.3.0", - "metascraper-date": "^5.10.3", + "metascraper-date": "^5.10.5", "metascraper-description": "^5.10.5", - "metascraper-image": "^5.10.3", - "metascraper-lang": "^5.10.3", + "metascraper-image": "^5.10.5", + "metascraper-lang": "^5.10.5", "metascraper-lang-detector": "^4.10.2", - "metascraper-logo": "^5.10.3", - "metascraper-publisher": "^5.10.3", + "metascraper-logo": "^5.10.5", + "metascraper-publisher": "^5.10.5", "metascraper-soundcloud": "^5.10.5", - "metascraper-title": "^5.10.3", - "metascraper-url": "^5.10.3", - "metascraper-video": "^5.10.3", + "metascraper-title": "^5.10.5", + "metascraper-url": "^5.10.5", + "metascraper-video": "^5.10.5", "metascraper-youtube": "^5.10.5", "minimatch": "^3.0.4", "mustache": "^4.0.0", @@ -88,12 +88,12 @@ "nodemailer-html-to-text": "^3.1.0", "npm-run-all": "~4.1.5", "request": "~2.88.0", - "sanitize-html": "~1.20.1", + "sanitize-html": "~1.21.1", "slug": "~2.1.0", "trunc-html": "~1.1.2", "uuid": "~3.4.0", "validator": "^12.1.0", - "wait-on": "~3.3.0", + "wait-on": "~4.0.0", "xregexp": "^4.2.4" }, "devDependencies": { diff --git a/backend/src/middleware/permissionsMiddleware.js b/backend/src/middleware/permissionsMiddleware.js index a4c41871f..faeeb8594 100644 --- a/backend/src/middleware/permissionsMiddleware.js +++ b/backend/src/middleware/permissionsMiddleware.js @@ -101,7 +101,7 @@ export default shield( Badge: allow, PostsEmotionsCountByEmotion: allow, PostsEmotionsByCurrentUser: isAuthenticated, - blockedUsers: isAuthenticated, + mutedUsers: isAuthenticated, notifications: isAuthenticated, Donations: isAuthenticated, }, @@ -137,8 +137,8 @@ export default shield( resetPassword: allow, AddPostEmotions: isAuthenticated, RemovePostEmotions: isAuthenticated, - block: isAuthenticated, - unblock: isAuthenticated, + muteUser: isAuthenticated, + unmuteUser: isAuthenticated, markAsRead: isAuthenticated, AddEmailAddress: isAuthenticated, VerifyEmailAddress: isAuthenticated, diff --git a/backend/src/models/User.js b/backend/src/models/User.js index fc352dccc..8dbfffb7a 100644 --- a/backend/src/models/User.js +++ b/backend/src/models/User.js @@ -78,6 +78,12 @@ export default { target: 'User', direction: 'out', }, + muted: { + type: 'relationship', + relationship: 'MUTED', + target: 'User', + direction: 'out', + }, notifications: { type: 'relationship', relationship: 'NOTIFIED', diff --git a/backend/src/schema/resolvers/helpers/filterForBlockedUsers.js b/backend/src/schema/resolvers/helpers/filterForBlockedUsers.js deleted file mode 100644 index b646038f0..000000000 --- a/backend/src/schema/resolvers/helpers/filterForBlockedUsers.js +++ /dev/null @@ -1,25 +0,0 @@ -import { getBlockedUsers, getBlockedByUsers } from '../users.js' -import { mergeWith, isArray } from 'lodash' - -export const filterForBlockedUsers = async (params, context) => { - if (!context.user) return params - const [blockedUsers, blockedByUsers] = await Promise.all([ - getBlockedUsers(context), - getBlockedByUsers(context), - ]) - const blockedUsersIds = [...blockedByUsers.map(b => b.id), ...blockedUsers.map(b => b.id)] - if (!blockedUsersIds.length) return params - - params.filter = mergeWith( - params.filter, - { - author_not: { id_in: blockedUsersIds }, - }, - (objValue, srcValue) => { - if (isArray(objValue)) { - return objValue.concat(srcValue) - } - }, - ) - return params -} diff --git a/backend/src/schema/resolvers/helpers/filterForMutedUsers.js b/backend/src/schema/resolvers/helpers/filterForMutedUsers.js new file mode 100644 index 000000000..78f461c28 --- /dev/null +++ b/backend/src/schema/resolvers/helpers/filterForMutedUsers.js @@ -0,0 +1,22 @@ +import { getMutedUsers } from '../users.js' +import { mergeWith, isArray } from 'lodash' + +export const filterForMutedUsers = async (params, context) => { + if (!context.user) return params + const [mutedUsers] = await Promise.all([getMutedUsers(context)]) + const mutedUsersIds = [...mutedUsers.map(user => user.id)] + if (!mutedUsersIds.length) return params + + params.filter = mergeWith( + params.filter, + { + author_not: { id_in: mutedUsersIds }, + }, + (objValue, srcValue) => { + if (isArray(objValue)) { + return objValue.concat(srcValue) + } + }, + ) + return params +} diff --git a/backend/src/schema/resolvers/posts.js b/backend/src/schema/resolvers/posts.js index 4a857a63c..af8165997 100644 --- a/backend/src/schema/resolvers/posts.js +++ b/backend/src/schema/resolvers/posts.js @@ -1,10 +1,10 @@ import uuid from 'uuid/v4' import { neo4jgraphql } from 'neo4j-graphql-js' import { isEmpty } from 'lodash' -import fileUpload from './fileUpload' import { UserInputError } from 'apollo-server' +import fileUpload from './fileUpload' import Resolver from './helpers/Resolver' -import { filterForBlockedUsers } from './helpers/filterForBlockedUsers' +import { filterForMutedUsers } from './helpers/filterForMutedUsers' const maintainPinnedPosts = params => { const pinnedPostFilter = { pinned: true } @@ -19,16 +19,16 @@ const maintainPinnedPosts = params => { export default { Query: { Post: async (object, params, context, resolveInfo) => { - params = await filterForBlockedUsers(params, context) + params = await filterForMutedUsers(params, context) params = await maintainPinnedPosts(params) return neo4jgraphql(object, params, context, resolveInfo) }, findPosts: async (object, params, context, resolveInfo) => { - params = await filterForBlockedUsers(params, context) + params = await filterForMutedUsers(params, context) return neo4jgraphql(object, params, context, resolveInfo) }, profilePagePosts: async (object, params, context, resolveInfo) => { - params = await filterForBlockedUsers(params, context) + params = await filterForMutedUsers(params, context) return neo4jgraphql(object, params, context, resolveInfo) }, PostsEmotionsCountByEmotion: async (object, params, context, resolveInfo) => { diff --git a/backend/src/schema/resolvers/users.js b/backend/src/schema/resolvers/users.js index 0b3f13631..a680f5e41 100644 --- a/backend/src/schema/resolvers/users.js +++ b/backend/src/schema/resolvers/users.js @@ -8,42 +8,26 @@ import createOrUpdateLocations from './users/location' const neode = getNeode() -export const getBlockedUsers = async context => { +export const getMutedUsers = async context => { const { neode } = context const userModel = neode.model('User') - let blockedUsers = neode + let mutedUsers = neode .query() .match('user', userModel) .where('user.id', context.user.id) - .relationship(userModel.relationships().get('blocked')) - .to('blocked', userModel) - .return('blocked') - blockedUsers = await blockedUsers.execute() - blockedUsers = blockedUsers.records.map(r => r.get('blocked').properties) - return blockedUsers -} - -export const getBlockedByUsers = async context => { - if (context.user.role === 'moderator' || context.user.role === 'admin') return [] - const { neode } = context - const userModel = neode.model('User') - let blockedByUsers = neode - .query() - .match('user', userModel) - .relationship(userModel.relationships().get('blocked')) - .to('blocked', userModel) - .where('blocked.id', context.user.id) - .return('user') - blockedByUsers = await blockedByUsers.execute() - blockedByUsers = blockedByUsers.records.map(r => r.get('user').properties) - return blockedByUsers + .relationship(userModel.relationships().get('muted')) + .to('muted', userModel) + .return('muted') + mutedUsers = await mutedUsers.execute() + mutedUsers = mutedUsers.records.map(r => r.get('muted').properties) + return mutedUsers } export default { Query: { - blockedUsers: async (object, args, context, resolveInfo) => { + mutedUsers: async (object, args, context, resolveInfo) => { try { - return getBlockedUsers(context) + return getMutedUsers(context) } catch (e) { throw new UserInputError(e.message) } @@ -72,6 +56,36 @@ export default { }, }, Mutation: { + muteUser: async (_parent, params, context, _resolveInfo) => { + const { user: currentUser } = context + if (currentUser.id === params.id) return null + await neode.cypher( + ` + MATCH(u:User {id: $currentUser.id})-[previousRelationship:FOLLOWS]->(b:User {id: $params.id}) + DELETE previousRelationship + `, + { currentUser, params }, + ) + const [user, mutedUser] = await Promise.all([ + neode.find('User', currentUser.id), + neode.find('User', params.id), + ]) + await user.relateTo(mutedUser, 'muted') + return mutedUser.toJson() + }, + unmuteUser: async (_parent, params, context, _resolveInfo) => { + const { user: currentUser } = context + if (currentUser.id === params.id) return null + await neode.cypher( + ` + MATCH(u:User {id: $currentUser.id})-[previousRelationship:MUTED]->(b:User {id: $params.id}) + DELETE previousRelationship + `, + { currentUser, params }, + ) + const unmutedUser = await neode.find('User', params.id) + return unmutedUser.toJson() + }, block: async (object, args, context, resolveInfo) => { const { user: currentUser } = context if (currentUser.id === args.id) return null @@ -217,6 +231,8 @@ export default { 'MATCH (this)<-[:FOLLOWS]-(u:User {id: $cypherParams.currentUserId}) RETURN COUNT(u) >= 1', isBlocked: 'MATCH (this)<-[:BLOCKED]-(u:User {id: $cypherParams.currentUserId}) RETURN COUNT(u) >= 1', + isMuted: + 'MATCH (this)<-[:MUTED]-(u:User {id: $cypherParams.currentUserId}) RETURN COUNT(u) >= 1', }, count: { contributionsCount: diff --git a/backend/src/schema/resolvers/users/blockedUsers.spec.js b/backend/src/schema/resolvers/users/mutedUsers.spec.js similarity index 58% rename from backend/src/schema/resolvers/users/blockedUsers.spec.js rename to backend/src/schema/resolvers/users/mutedUsers.spec.js index 11bcb823d..3dab70278 100644 --- a/backend/src/schema/resolvers/users/blockedUsers.spec.js +++ b/backend/src/schema/resolvers/users/mutedUsers.spec.js @@ -9,7 +9,7 @@ const factory = Factory() const neode = getNeode() let currentUser -let blockedUser +let mutedUser let authenticatedUser let server @@ -33,15 +33,15 @@ afterEach(async () => { await factory.cleanDatabase() }) -describe('blockedUsers', () => { - let blockedUserQuery +describe('mutedUsers', () => { + let mutedUserQuery beforeEach(() => { - blockedUserQuery = gql` + mutedUserQuery = gql` query { - blockedUsers { + mutedUsers { id name - isBlocked + isMuted } } ` @@ -49,34 +49,34 @@ describe('blockedUsers', () => { it('throws permission error', async () => { const { query } = createTestClient(server) - const result = await query({ query: blockedUserQuery }) + const result = await query({ query: mutedUserQuery }) expect(result.errors[0]).toHaveProperty('message', 'Not Authorised!') }) - describe('authenticated and given a blocked user', () => { + describe('authenticated and given a muted user', () => { beforeEach(async () => { currentUser = await neode.create('User', { name: 'Current User', id: 'u1', }) - blockedUser = await neode.create('User', { - name: 'Blocked User', + mutedUser = await neode.create('User', { + name: 'Muted User', id: 'u2', }) - await currentUser.relateTo(blockedUser, 'blocked') + await currentUser.relateTo(mutedUser, 'muted') authenticatedUser = await currentUser.toJson() }) - it('returns a list of blocked users', async () => { + it('returns a list of muted users', async () => { const { query } = createTestClient(server) - await expect(query({ query: blockedUserQuery })).resolves.toEqual( + await expect(query({ query: mutedUserQuery })).resolves.toEqual( expect.objectContaining({ data: { - blockedUsers: [ + mutedUsers: [ { - name: 'Blocked User', + name: 'Muted User', id: 'u2', - isBlocked: true, + isMuted: true, }, ], }, @@ -86,28 +86,28 @@ describe('blockedUsers', () => { }) }) -describe('block', () => { - let blockAction +describe('muteUser', () => { + let muteAction beforeEach(() => { currentUser = undefined - blockAction = variables => { + muteAction = variables => { const { mutate } = createTestClient(server) - const blockMutation = gql` + const muteUserMutation = gql` mutation($id: ID!) { - block(id: $id) { + muteUser(id: $id) { id name - isBlocked + isMuted } } ` - return mutate({ mutation: blockMutation, variables }) + return mutate({ mutation: muteUserMutation, variables }) } }) it('throws permission error', async () => { - const result = await blockAction({ id: 'u2' }) + const result = await muteAction({ id: 'u2' }) expect(result.errors[0]).toHaveProperty('message', 'Not Authorised!') }) @@ -120,45 +120,47 @@ describe('block', () => { authenticatedUser = await currentUser.toJson() }) - describe('block yourself', () => { + describe('mute yourself', () => { it('returns null', async () => { - await expect(blockAction({ id: 'u1' })).resolves.toEqual( - expect.objectContaining({ data: { block: null } }), + await expect(muteAction({ id: 'u1' })).resolves.toEqual( + expect.objectContaining({ data: { muteUser: null } }), ) }) }) - describe('block not existing user', () => { + describe('mute not existing user', () => { it('returns null', async () => { - await expect(blockAction({ id: 'u2' })).resolves.toEqual( - expect.objectContaining({ data: { block: null } }), + await expect(muteAction({ id: 'u2' })).resolves.toEqual( + expect.objectContaining({ data: { muteUser: null } }), ) }) }) - describe('given a to-be-blocked user', () => { + describe('given a to-be-muted user', () => { beforeEach(async () => { - blockedUser = await neode.create('User', { - name: 'Blocked User', + mutedUser = await neode.create('User', { + name: 'Muted User', id: 'u2', }) }) - it('blocks a user', async () => { - await expect(blockAction({ id: 'u2' })).resolves.toEqual( + it('mutes a user', async () => { + await expect(muteAction({ id: 'u2' })).resolves.toEqual( expect.objectContaining({ - data: { block: { id: 'u2', name: 'Blocked User', isBlocked: true } }, + data: { + muteUser: { id: 'u2', name: 'Muted User', isMuted: true }, + }, }), ) }) it('unfollows the user', async () => { - await currentUser.relateTo(blockedUser, 'following') + await currentUser.relateTo(mutedUser, 'following') const queryUser = gql` query { User(id: "u2") { id - isBlocked + isMuted followedByCurrentUser } } @@ -166,18 +168,18 @@ describe('block', () => { const { query } = createTestClient(server) await expect(query({ query: queryUser })).resolves.toEqual( expect.objectContaining({ - data: { User: [{ id: 'u2', isBlocked: false, followedByCurrentUser: true }] }, + data: { User: [{ id: 'u2', isMuted: false, followedByCurrentUser: true }] }, }), ) - await blockAction({ id: 'u2' }) + await muteAction({ id: 'u2' }) await expect(query({ query: queryUser })).resolves.toEqual( expect.objectContaining({ - data: { User: [{ id: 'u2', isBlocked: true, followedByCurrentUser: false }] }, + data: { User: [{ id: 'u2', isMuted: true, followedByCurrentUser: false }] }, }), ) }) - describe('given both the current user and the to-be-blocked user write a post', () => { + describe('given both the current user and the to-be-muted user write a post', () => { let postQuery beforeEach(async () => { @@ -187,11 +189,11 @@ describe('block', () => { }) const post2 = await neode.create('Post', { id: 'p23', - title: 'A post written by the blocked user', + title: 'A post written by the muted user', }) await Promise.all([ post1.relateTo(currentUser, 'author'), - post2.relateTo(blockedUser, 'author'), + post2.relateTo(mutedUser, 'author'), ]) postQuery = gql` query { @@ -223,9 +225,9 @@ describe('block', () => { }, { id: 'p23', - title: 'A post written by the blocked user', + title: 'A post written by the muted user', author: { - name: 'Blocked User', + name: 'Muted User', id: 'u2', }, }, @@ -238,12 +240,12 @@ describe('block', () => { describe('from the perspective of the current user', () => { it('both posts are in the newsfeed', bothPostsAreInTheNewsfeed) - describe('but if the current user blocks the other user', () => { + describe('but if the current user mutes the other user', () => { beforeEach(async () => { - await currentUser.relateTo(blockedUser, 'blocked') + await currentUser.relateTo(mutedUser, 'muted') }) - it("the blocked user's post won't show up in the newsfeed of the current user", async () => { + it("the muted user's post won't show up in the newsfeed of the current user", async () => { const { query } = createTestClient(server) await expect(query({ query: postQuery })).resolves.toEqual( expect.objectContaining({ @@ -262,29 +264,34 @@ describe('block', () => { }) }) - describe('from the perspective of the blocked user', () => { + describe('from the perspective of the muted user', () => { beforeEach(async () => { - authenticatedUser = await blockedUser.toJson() + authenticatedUser = await mutedUser.toJson() }) it('both posts are in the newsfeed', bothPostsAreInTheNewsfeed) - describe('but if the current user blocks the other user', () => { + describe('but if the current user mutes the other user', () => { beforeEach(async () => { - await currentUser.relateTo(blockedUser, 'blocked') + await currentUser.relateTo(mutedUser, 'muted') }) - it("the current user's post won't show up in the newsfeed of the blocked user", async () => { + it("the current user's post will show up in the newsfeed of the muted user", async () => { const { query } = createTestClient(server) await expect(query({ query: postQuery })).resolves.toEqual( expect.objectContaining({ data: { - Post: [ + Post: expect.arrayContaining([ { id: 'p23', - title: 'A post written by the blocked user', - author: { name: 'Blocked User', id: 'u2' }, + title: 'A post written by the muted user', + author: { name: 'Muted User', id: 'u2' }, }, - ], + { + id: 'p12', + title: 'A post written by the current user', + author: { name: 'Current User', id: 'u1' }, + }, + ]), }, }), ) @@ -296,28 +303,28 @@ describe('block', () => { }) }) -describe('unblock', () => { - let unblockAction +describe('unmuteUser', () => { + let unmuteAction beforeEach(() => { currentUser = undefined - unblockAction = variables => { + unmuteAction = variables => { const { mutate } = createTestClient(server) - const unblockMutation = gql` + const unmuteUserMutation = gql` mutation($id: ID!) { - unblock(id: $id) { + unmuteUser(id: $id) { id name - isBlocked + isMuted } } ` - return mutate({ mutation: unblockMutation, variables }) + return mutate({ mutation: unmuteUserMutation, variables }) } }) it('throws permission error', async () => { - const result = await unblockAction({ id: 'u2' }) + const result = await unmuteAction({ id: 'u2' }) expect(result.errors[0]).toHaveProperty('message', 'Not Authorised!') }) @@ -330,59 +337,69 @@ describe('unblock', () => { authenticatedUser = await currentUser.toJson() }) - describe('unblock yourself', () => { + describe('unmute yourself', () => { it('returns null', async () => { - await expect(unblockAction({ id: 'u1' })).resolves.toEqual( - expect.objectContaining({ data: { unblock: null } }), + await expect(unmuteAction({ id: 'u1' })).resolves.toEqual( + expect.objectContaining({ data: { unmuteUser: null } }), ) }) }) - describe('unblock not-existing user', () => { + describe('unmute not-existing user', () => { it('returns null', async () => { - await expect(unblockAction({ id: 'lksjdflksfdj' })).resolves.toEqual( - expect.objectContaining({ data: { unblock: null } }), + await expect(unmuteAction({ id: 'lksjdflksfdj' })).resolves.toEqual( + expect.objectContaining({ data: { unmuteUser: null } }), ) }) }) describe('given another user', () => { beforeEach(async () => { - blockedUser = await neode.create('User', { - name: 'Blocked User', + mutedUser = await neode.create('User', { + name: 'Muted User', id: 'u2', }) }) - describe('unblocking a not yet blocked user', () => { + describe('unmuting a not yet muted user', () => { it('does not hurt', async () => { - await expect(unblockAction({ id: 'u2' })).resolves.toEqual( + await expect(unmuteAction({ id: 'u2' })).resolves.toEqual( expect.objectContaining({ - data: { unblock: { id: 'u2', name: 'Blocked User', isBlocked: false } }, + data: { + unmuteUser: { id: 'u2', name: 'Muted User', isMuted: false }, + }, }), ) }) }) - describe('given a blocked user', () => { + describe('given a muted user', () => { beforeEach(async () => { - await currentUser.relateTo(blockedUser, 'blocked') + await currentUser.relateTo(mutedUser, 'muted') }) - it('unblocks a user', async () => { - await expect(unblockAction({ id: 'u2' })).resolves.toEqual( + it('unmutes a user', async () => { + await expect(unmuteAction({ id: 'u2' })).resolves.toEqual( expect.objectContaining({ - data: { unblock: { id: 'u2', name: 'Blocked User', isBlocked: false } }, + data: { + unmuteUser: { id: 'u2', name: 'Muted User', isMuted: false }, + }, }), ) }) - describe('unblocking twice', () => { + describe('unmuting twice', () => { it('has no effect', async () => { - await unblockAction({ id: 'u2' }) - await expect(unblockAction({ id: 'u2' })).resolves.toEqual( + await unmuteAction({ id: 'u2' }) + await expect(unmuteAction({ id: 'u2' })).resolves.toEqual( expect.objectContaining({ - data: { unblock: { id: 'u2', name: 'Blocked User', isBlocked: false } }, + data: { + unmuteUser: { + id: 'u2', + name: 'Muted User', + isMuted: false, + }, + }, }), ) }) diff --git a/backend/src/schema/types/type/User.gql b/backend/src/schema/types/type/User.gql index 6c07e1cc2..4eb04a638 100644 --- a/backend/src/schema/types/type/User.gql +++ b/backend/src/schema/types/type/User.gql @@ -75,6 +75,13 @@ type User { """ ) + isMuted: Boolean! @cypher( + statement: """ + MATCH (this)<-[:MUTED]-(user:User { id: $cypherParams.currentUserId}) + RETURN COUNT(user) >= 1 + """ + ) + # contributions: [WrittenPost]! # contributions2(first: Int = 10, offset: Int = 0): [WrittenPost2]! # @cypher( @@ -160,6 +167,7 @@ type Query { filter: _UserFilter ): [User] + mutedUsers: [User] blockedUsers: [User] isLoggedIn: Boolean! currentUser: User @@ -197,7 +205,8 @@ type Mutation { DeleteUser(id: ID!, resource: [Deletable]): User - + muteUser(id: ID!): User + unmuteUser(id: ID!): User block(id: ID!): User unblock(id: ID!): User } diff --git a/backend/src/seed/factories/posts.js b/backend/src/seed/factories/posts.js index d1a46d71b..55f4f95fb 100644 --- a/backend/src/seed/factories/posts.js +++ b/backend/src/seed/factories/posts.js @@ -36,7 +36,6 @@ export default function create() { if (categoryIds) categories = await Promise.all(categoryIds.map(id => neodeInstance.find('Category', id))) categories = categories || (await Promise.all([factoryInstance.create('Category')])) - const { tagIds = [] } = args delete args.tags const tags = await Promise.all( diff --git a/backend/src/seed/seed-db.js b/backend/src/seed/seed-db.js index 4178169bb..d4ce431be 100644 --- a/backend/src/seed/seed-db.js +++ b/backend/src/seed/seed-db.js @@ -226,6 +226,10 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl'] dewey.relateTo(huey, 'following'), louie.relateTo(jennyRostock, 'following'), + huey.relateTo(dagobert, 'muted'), + dewey.relateTo(dagobert, 'muted'), + louie.relateTo(dagobert, 'muted'), + dagobert.relateTo(huey, 'blocked'), dagobert.relateTo(dewey, 'blocked'), dagobert.relateTo(louie, 'blocked'), diff --git a/backend/yarn.lock b/backend/yarn.lock index 57bc2e878..5749c5639 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -850,6 +850,11 @@ resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.2.tgz#1c794cd6dbf2354d1eb1ef10e0303f573e1c7222" integrity sha512-O4QDrx+JoGKZc6aN64L04vqa7e41tIiLU+OvKdcYaEMP97UttL0f9GIi9/0A4WAMx0uBd6SidDIhktZhgOcN8Q== +"@hapi/address@^2.1.2": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5" + integrity sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ== + "@hapi/address@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@hapi/address/-/address-4.0.0.tgz#36affb4509b5a6adc628bcc394450f2a7d51d111" @@ -862,6 +867,11 @@ resolved "https://registry.yarnpkg.com/@hapi/bourne/-/bourne-1.3.2.tgz#0a7095adea067243ce3283e1b56b8a8f453b242a" integrity sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA== +"@hapi/formula@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@hapi/formula/-/formula-1.2.0.tgz#994649c7fea1a90b91a0a1e6d983523f680e10cd" + integrity sha512-UFbtbGPjstz0eWHb+ga/GM3Z9EzqKXFWIbSOFURU0A/Gku0Bky4bCk9/h//K2Xr3IrCfjFNhMm4jyZ5dbCewGA== + "@hapi/formula@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@hapi/formula/-/formula-2.0.0.tgz#edade0619ed58c8e4f164f233cda70211e787128" @@ -872,12 +882,17 @@ resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.2.4.tgz#684a14f4ca35d46f44abc87dfc696e5e4fe8a020" integrity sha512-Ze5SDNt325yZvNO7s5C4fXDscjJ6dcqLFXJQ/M7dZRQCewuDj2iDUuBi6jLQt+APbW9RjjVEvLr35FXuOEqjow== +"@hapi/hoek@^8.2.4", "@hapi/hoek@^8.3.0": + version "8.5.0" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.5.0.tgz#2f9ce301c8898e1c3248b0a8564696b24d1a9a5a" + integrity sha512-7XYT10CZfPsH7j9F1Jmg1+d0ezOux2oM2GfArAzLwWe4mE2Dr3hVjsAL6+TFY49RRJlCdJDMw3nJsLFroTc8Kw== + "@hapi/hoek@^9.0.0": version "9.0.0" resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.0.0.tgz#ba83436edfac1d1ffd0e94797d43419c20ad49b8" integrity sha512-XxD4A5YMIH70ddjG7BJBUz7RWVQAwIP/36Eoyh0DsaWp92OAeXkrbtSEaYkynBPTsN9Uv2mZq9QWZYILl2Svrw== -"@hapi/joi@^15.0.3", "@hapi/joi@^15.1.0": +"@hapi/joi@^15.1.0": version "15.1.1" resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-15.1.1.tgz#c675b8a71296f02833f8d6d243b34c57b8ce19d7" integrity sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ== @@ -887,10 +902,21 @@ "@hapi/hoek" "8.x.x" "@hapi/topo" "3.x.x" -"@hapi/joi@^17.0.2": - version "17.0.2" - resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-17.0.2.tgz#613d47f629eb3e4ae17c8065092bce46b87771a6" - integrity sha512-84icw1yV3vbRzUidqFli1Gqr8diigOhTuKzlu3gqBXBm4Lukqe5apjyeJJhGO4rO/J3NiRjy1vXQ5bmhc5+fUA== +"@hapi/joi@^16.1.8": + version "16.1.8" + resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-16.1.8.tgz#84c1f126269489871ad4e2decc786e0adef06839" + integrity sha512-wAsVvTPe+FwSrsAurNt5vkg3zo+TblvC5Bb1zMVK6SJzZqw9UrJnexxR+76cpePmtUZKHAPxcQ2Bf7oVHyahhg== + dependencies: + "@hapi/address" "^2.1.2" + "@hapi/formula" "^1.2.0" + "@hapi/hoek" "^8.2.4" + "@hapi/pinpoint" "^1.0.2" + "@hapi/topo" "^3.1.3" + +"@hapi/joi@^17.1.0": + version "17.1.0" + resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-17.1.0.tgz#cc4000b6c928a6a39b9bef092151b6bdee10ce55" + integrity sha512-ob67RcPlwRWxBzLCnWvcwx5qbwf88I3ykD7gcJLWOTRfLLgosK7r6aeChz4thA3XRvuBfI0KB1tPVl2EQFlPXw== dependencies: "@hapi/address" "^4.0.0" "@hapi/formula" "^2.0.0" @@ -898,6 +924,11 @@ "@hapi/pinpoint" "^2.0.0" "@hapi/topo" "^5.0.0" +"@hapi/pinpoint@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@hapi/pinpoint/-/pinpoint-1.0.2.tgz#025b7a36dbbf4d35bf1acd071c26b20ef41e0d13" + integrity sha512-dtXC/WkZBfC5vxscazuiJ6iq4j9oNx1SHknmIr8hofarpKUZKmlUVYVIhNVzIEgK5Wrc4GMHL5lZtt1uS2flmQ== + "@hapi/pinpoint@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@hapi/pinpoint/-/pinpoint-2.0.0.tgz#805b40d4dbec04fc116a73089494e00f073de8df" @@ -910,6 +941,13 @@ dependencies: "@hapi/hoek" "8.x.x" +"@hapi/topo@^3.1.3": + version "3.1.6" + resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-3.1.6.tgz#68d935fa3eae7fdd5ab0d7f953f3205d8b2bfc29" + integrity sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ== + dependencies: + "@hapi/hoek" "^8.3.0" + "@hapi/topo@^5.0.0": version "5.0.0" resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.0.0.tgz#c19af8577fa393a06e9c77b60995af959be721e7" @@ -5962,19 +6000,19 @@ merge2@^1.3.0: resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.3.0.tgz#5b366ee83b2f1582c48f87e47cf1a9352103ca81" integrity sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw== -metascraper-audio@^5.10.3: - version "5.10.3" - resolved "https://registry.yarnpkg.com/metascraper-audio/-/metascraper-audio-5.10.3.tgz#ce0c3a895f8d45c488c5b5916038f6479c8b0f31" - integrity sha512-L4ft5y36MJPZt8Odzbpzm5/iazNaDPHy6EkQtzDYwr7yoOJTrUE+RMkiYRz81HBl/ThRh0Ez4RuTNVNQfNsQZA== +metascraper-audio@^5.10.5: + version "5.10.5" + resolved "https://registry.yarnpkg.com/metascraper-audio/-/metascraper-audio-5.10.5.tgz#7f292bfb66516753672a52dec083fabdc05edfbd" + integrity sha512-S3Wrzfgf0zpl8rjYN1NBMEz0FCcpbtTV/+QxktLqSeJv/kzLfUWrYQadOMv9++EQpIc8umBgVwHeZ6+1TCBVgA== dependencies: - "@metascraper/helpers" "^5.10.3" + "@metascraper/helpers" "^5.10.5" -metascraper-author@^5.10.3: - version "5.10.3" - resolved "https://registry.yarnpkg.com/metascraper-author/-/metascraper-author-5.10.3.tgz#b867875e6b08925c0cf5f9d4c841ba3165382841" - integrity sha512-kJmQf6IER9rUVLrLVIp7JiO8QjbOMp209rea4t/5pUjYmSAL6pj9JiU2XVnTe0lZroxoqgV3DdZLJUUUrB1s2w== +metascraper-author@^5.10.5: + version "5.10.5" + resolved "https://registry.yarnpkg.com/metascraper-author/-/metascraper-author-5.10.5.tgz#f863dfc577ea4069f984c74608a46f22c67fd082" + integrity sha512-5fN5LS0RwbfUE5W4Tw9+Vn598+P3zAvkXBkVAaWxy92Uoy4gQyIptjTIs1at9GIOOr2eLgN9pD2qxIso6SU/hw== dependencies: - "@metascraper/helpers" "^5.10.3" + "@metascraper/helpers" "^5.10.5" lodash "~4.17.15" metascraper-clearbit-logo@^5.3.0: @@ -5984,12 +6022,12 @@ metascraper-clearbit-logo@^5.3.0: dependencies: got "~9.6.0" -metascraper-date@^5.10.3: - version "5.10.3" - resolved "https://registry.yarnpkg.com/metascraper-date/-/metascraper-date-5.10.3.tgz#bd2636c32caf89cb8e46219bba5792f140bd624f" - integrity sha512-H4LZgJbfaTlkn56ZvO6C0XtERmIcJoZPhZKxyu6yTTxUYhGKho0M430TZZoGU5sTVTRlDEOtVICMKu+0yz+eog== +metascraper-date@^5.10.5: + version "5.10.5" + resolved "https://registry.yarnpkg.com/metascraper-date/-/metascraper-date-5.10.5.tgz#07be5149b9a0502e872080f1d474b2fff34c8361" + integrity sha512-BPujzdQ61XYjpPWZLwDmz5ZuQ4Sd4sB9+WKHN7j0gaHfmiWbm7QAKQm8YIjyNwuFysOYBYPI772cEePN6zdn7Q== dependencies: - "@metascraper/helpers" "^5.10.3" + "@metascraper/helpers" "^5.10.5" metascraper-description@^5.10.5: version "5.10.5" @@ -5998,12 +6036,12 @@ metascraper-description@^5.10.5: dependencies: "@metascraper/helpers" "^5.10.5" -metascraper-image@^5.10.3: - version "5.10.3" - resolved "https://registry.yarnpkg.com/metascraper-image/-/metascraper-image-5.10.3.tgz#853eb464c3b717f8fe4ac8bf31c4b2bc39b83216" - integrity sha512-22/WPf9A+jUc/Unvpfursi6FAfo/s71Pq/N9jiTNxBgOjfrUWjrzzw8qUKBxTc7Dwz1mERfDn2B0f/tKdsBAFA== +metascraper-image@^5.10.5: + version "5.10.5" + resolved "https://registry.yarnpkg.com/metascraper-image/-/metascraper-image-5.10.5.tgz#3c4b897abacab78b7794d472fade1e195a4e7031" + integrity sha512-1YTNu3NaOGwRs0XmlQnmatEepYggwA5HyVxE05IxzNZ9oZdb26A0bwxbXSxSNNRerhcMNdePReHlqjVAk/W1TA== dependencies: - "@metascraper/helpers" "^5.10.3" + "@metascraper/helpers" "^5.10.5" metascraper-lang-detector@^4.10.2: version "4.10.2" @@ -6014,26 +6052,26 @@ metascraper-lang-detector@^4.10.2: franc "~4.0.0" iso-639-3 "~1.1.0" -metascraper-lang@^5.10.3: - version "5.10.3" - resolved "https://registry.yarnpkg.com/metascraper-lang/-/metascraper-lang-5.10.3.tgz#497f90559b6070e155d1c76f91e48275c823af9a" - integrity sha512-3AdLZ+WiK+byaQSLGmkfanJSQalHvhXqyn/kaaCXraztDx5gsoNs8QskRlM9kxxKID5obbYSqMn9Eb9RLFki+g== +metascraper-lang@^5.10.5: + version "5.10.5" + resolved "https://registry.yarnpkg.com/metascraper-lang/-/metascraper-lang-5.10.5.tgz#8d62f8a398863b8bf785f730319f0cf0a5bff3ba" + integrity sha512-DzpZSkze6p/MDIrK4g+jl/lbgTIBW8FdERCD8LnmzFLtSYDr/U3e9SB+d7wLlrWSPm0JBKkVajwzkQGx6GKqGQ== dependencies: - "@metascraper/helpers" "^5.10.3" + "@metascraper/helpers" "^5.10.5" -metascraper-logo@^5.10.3: - version "5.10.3" - resolved "https://registry.yarnpkg.com/metascraper-logo/-/metascraper-logo-5.10.3.tgz#22847c9ba65d8ae8e8af05d838f1da0953215300" - integrity sha512-8bliBXhe638D5A1gFh3q07rxYMCD6WOgywKFKPLcgOb0YybOU0MlrHkInXaGLMGCinULw3cXCn67b/+11mbmHA== +metascraper-logo@^5.10.5: + version "5.10.5" + resolved "https://registry.yarnpkg.com/metascraper-logo/-/metascraper-logo-5.10.5.tgz#5bbd3981391b0984bf85e67644a94ad65b04868b" + integrity sha512-ygKvX+EIuU6eCqigW+nGFPkXri1EyHeSpu6P37Sg6jXfgo+eZL8B2ophKtG4lOnc5yZjMFKdv+PaADGhXUsUWg== dependencies: - "@metascraper/helpers" "^5.10.3" + "@metascraper/helpers" "^5.10.5" -metascraper-publisher@^5.10.3: - version "5.10.3" - resolved "https://registry.yarnpkg.com/metascraper-publisher/-/metascraper-publisher-5.10.3.tgz#caf9dabdae2c118db2125aa34c321e527e88279b" - integrity sha512-l2W6YKqybvvhmqEOIvLmb9hTycH5JeIQ8O3d1q21hT3IwMW3BCmy4TyiSoPS+6vWlss0VYdQ8rzmESWdniGRWA== +metascraper-publisher@^5.10.5: + version "5.10.5" + resolved "https://registry.yarnpkg.com/metascraper-publisher/-/metascraper-publisher-5.10.5.tgz#8797e419886f084adefcb7b8a642552b2a65ea38" + integrity sha512-YTY5UlkVa/htrm8t+O8qCrl2l24PffXkwvGStYJB2vA984WsR0XfhDuDqHqUZiQoSYBx/Za9wi74k6LWPnL4yA== dependencies: - "@metascraper/helpers" "^5.10.3" + "@metascraper/helpers" "^5.10.5" metascraper-soundcloud@^5.10.5: version "5.10.5" @@ -6043,27 +6081,27 @@ metascraper-soundcloud@^5.10.5: "@metascraper/helpers" "^5.10.5" tldts "~5.6.3" -metascraper-title@^5.10.3: - version "5.10.3" - resolved "https://registry.yarnpkg.com/metascraper-title/-/metascraper-title-5.10.3.tgz#549e35616f3fbc3ecae5fff8f5adc677f0e43a2d" - integrity sha512-HrYrZ/jOarFFvxUjuefBT9q4KDUqZnkvDhQM7WQ/8qE1Eht5WsijBxqWsDvONxIW/VhELhXendvt6MU9t+y2yA== +metascraper-title@^5.10.5: + version "5.10.5" + resolved "https://registry.yarnpkg.com/metascraper-title/-/metascraper-title-5.10.5.tgz#719164bfc2d934ddad4fa3bae86eba750729a0bd" + integrity sha512-ukiLgQ4CNto1eA9edKB1QN0qFczJRZItBsTpmns6AEezQfDYs4M/LZyjnMCTVmZXYABliU53Ut+Yhf5g9uvX+w== dependencies: - "@metascraper/helpers" "^5.10.3" + "@metascraper/helpers" "^5.10.5" lodash "~4.17.15" -metascraper-url@^5.10.3: - version "5.10.3" - resolved "https://registry.yarnpkg.com/metascraper-url/-/metascraper-url-5.10.3.tgz#95be7d8d27fae9b9e945dd0121669cd726b23618" - integrity sha512-38K6yodNfQRnrACXTZ76rE17WalwdW0ov1wjpPO0FP8LKJ/3I/GcBW8LOgwdMeyzlBBuF7UzPYPlLQzp1RZpMQ== +metascraper-url@^5.10.5: + version "5.10.5" + resolved "https://registry.yarnpkg.com/metascraper-url/-/metascraper-url-5.10.5.tgz#b4a9951143e19f39e3bf62d93e060ece9bdba6d4" + integrity sha512-fdPPDk1/hq8vRTxwnLtUV55FpclJfhfBLxYLekTSRGqQbqSlXLNpncj2LjrvRUc0yw0oT2fEsTYzb56OQmh2Aw== dependencies: - "@metascraper/helpers" "^5.10.3" + "@metascraper/helpers" "^5.10.5" -metascraper-video@^5.10.3: - version "5.10.3" - resolved "https://registry.yarnpkg.com/metascraper-video/-/metascraper-video-5.10.3.tgz#deb0510b247aff0c9f1777a9d790f0aa55fa2890" - integrity sha512-xXGtPWX1RYSEOkLDvIzD20+o4hrSYycN31briMwQkjL7ZcuSfGgILDOCXSnT+WcpEbRNNxAOmODvAxU5qGnqjQ== +metascraper-video@^5.10.5: + version "5.10.5" + resolved "https://registry.yarnpkg.com/metascraper-video/-/metascraper-video-5.10.5.tgz#56e5d286a83dcd90c76308c59890b272fc1c9bb9" + integrity sha512-wqTyROU5TbvNhmyhhO9G2Dko0Hiho8dzfVIUh4rF760Kf3J3O9FEXo9NTgKJJGB7Gg0sNaWZt7fvWsmWIzY7UA== dependencies: - "@metascraper/helpers" "^5.10.3" + "@metascraper/helpers" "^5.10.5" lodash "~4.17.15" metascraper-youtube@^5.10.5: @@ -7405,19 +7443,19 @@ repeat-string@^1.5.2, repeat-string@^1.6.1: resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= -request-promise-core@1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.2.tgz#339f6aababcafdb31c799ff158700336301d3346" - integrity sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag== +request-promise-core@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.3.tgz#e9a3c081b51380dfea677336061fea879a829ee9" + integrity sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ== dependencies: - lodash "^4.17.11" + lodash "^4.17.15" -request-promise-native@^1.0.5: - version "1.0.7" - resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.7.tgz#a49868a624bdea5069f1251d0a836e0d89aa2c59" - integrity sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w== +request-promise-native@^1.0.5, request-promise-native@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.8.tgz#a455b960b826e44e2bf8999af64dff2bfe58cb36" + integrity sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ== dependencies: - request-promise-core "1.1.2" + request-promise-core "1.1.3" stealthy-require "^1.1.1" tough-cookie "^2.3.3" @@ -7562,22 +7600,10 @@ run-parallel@^1.1.9: resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.9.tgz#c9dd3a7cf9f4b2c4b6244e173a6ed866e61dd679" integrity sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q== -rx@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" - integrity sha1-pfE/957zt0D+MKqAP7CfmIBdR4I= - -rxjs@^6.4.0: - version "6.5.2" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.2.tgz#2e35ce815cd46d84d02a209fb4e5921e051dbec7" - integrity sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg== - dependencies: - tslib "^1.9.0" - -rxjs@^6.5.2: - version "6.5.3" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.3.tgz#510e26317f4db91a7eb1de77d9dd9ba0a4899a3a" - integrity sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA== +rxjs@^6.4.0, rxjs@^6.5.2, rxjs@^6.5.4: + version "6.5.4" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.4.tgz#e0777fe0d184cec7872df147f303572d414e211c" + integrity sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q== dependencies: tslib "^1.9.0" @@ -7618,10 +7644,10 @@ sane@^4.0.3: minimist "^1.1.1" walker "~1.0.5" -sanitize-html@~1.20.1: - version "1.20.1" - resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-1.20.1.tgz#f6effdf55dd398807171215a62bfc21811bacf85" - integrity sha512-txnH8TQjaQvg2Q0HY06G6CDJLVYCpbnxrdO0WN8gjCKaU5J0KbyGYhZxx5QJg3WLZ1lB7XU9kDkfrCXUozqptA== +sanitize-html@~1.21.1: + version "1.21.1" + resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-1.21.1.tgz#1647d15c0c672901aa41eac1b86d0c38146d30ce" + integrity sha512-W6enXSVphVaVbmVbzVngBthR5f5sMmhq3EfPfBlzBzp2WnX8Rnk7NGpP7KmHUc0Y3MVk9tv/+CbpdHchX9ai7g== dependencies: chalk "^2.4.1" htmlparser2 "^3.10.0" @@ -8754,16 +8780,17 @@ w3c-hr-time@^1.0.1: dependencies: browser-process-hrtime "^0.1.2" -wait-on@~3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-3.3.0.tgz#9940981d047a72a9544a97b8b5fca45b2170a082" - integrity sha512-97dEuUapx4+Y12aknWZn7D25kkjMk16PbWoYzpSdA8bYpVfS6hpl2a2pOWZ3c+Tyt3/i4/pglyZctG3J4V1hWQ== +wait-on@~4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-4.0.0.tgz#4d7e4485ca759968897fd3b0cc50720c0b4ca959" + integrity sha512-QrW3J8LzS5ADPfD9Rx5S6KJck66xkqyiFKQs9jmUTkIhiEOmkzU7WRZc+MjsnmkrgjitS2xQ4bb13hnlQnKBUQ== dependencies: - "@hapi/joi" "^15.0.3" - core-js "^2.6.5" + "@hapi/joi" "^16.1.8" + lodash "^4.17.15" minimist "^1.2.0" request "^2.88.0" - rx "^4.1.0" + request-promise-native "^1.0.8" + rxjs "^6.5.4" walker@^1.0.7, walker@~1.0.5: version "1.0.7" diff --git a/cypress/integration/common/report.js b/cypress/integration/common/report.js index 2e11c1d0d..1ba3e2e83 100644 --- a/cypress/integration/common/report.js +++ b/cypress/integration/common/report.js @@ -7,7 +7,7 @@ import { gql } from '../../../backend/src/helpers/jest' let lastReportTitle let davidIrvingPostTitle = 'The Truth about the Holocaust' let davidIrvingPostSlug = 'the-truth-about-the-holocaust' -let annoyingUserWhoBlockedModeratorTitle = 'Fake news' +let annoyingUserWhoMutedModeratorTitle = 'Fake news' const savePostTitle = $post => { return $post @@ -147,9 +147,9 @@ Then('I see all the reported posts including the one from above', () => { }) }) -Then('I see all the reported posts including from the user who blocked me', () => { +Then('I see all the reported posts including from the user who muted me', () => { cy.get('table tbody').within(() => { - cy.contains('tr', annoyingUserWhoBlockedModeratorTitle) + cy.contains('tr', annoyingUserWhoMutedModeratorTitle) }) }) @@ -159,9 +159,9 @@ Then('each list item links to the post page', () => { }) Then('I can visit the post page', () => { - cy.contains(annoyingUserWhoBlockedModeratorTitle).click() + cy.contains(annoyingUserWhoMutedModeratorTitle).click() cy.location('pathname').should('contain', '/post') - .get('h3').should('contain', annoyingUserWhoBlockedModeratorTitle) + .get('h3').should('contain', annoyingUserWhoMutedModeratorTitle) }) When("they have a post someone has reported", () => { diff --git a/cypress/integration/common/steps.js b/cypress/integration/common/steps.js index 9e0cc799b..53b5f7c3d 100644 --- a/cypress/integration/common/steps.js +++ b/cypress/integration/common/steps.js @@ -29,10 +29,20 @@ const narratorParams = { ...termsAndConditionsAgreedVersion, }; +const annoyingParams = { + email: "spammy-spammer@example.org", + password: "1234", + ...termsAndConditionsAgreedVersion +}; + Given("I am logged in", () => { cy.login(loginCredentials); }); +Given("I am logged in as the muted user", () => { + cy.login({ email: annoyingParams.email, password: '1234' }); +}); + Given("we have a selection of categories", () => { cy.createCategories("cat0", "just-for-fun"); }); @@ -227,7 +237,6 @@ Given("I previously created a post", () => { lastPost.authorId = narratorParams.id lastPost.title = "previously created post"; lastPost.content = "with some content"; - lastPost.categoryIds = ["cat0"]; cy.factory() .create("Post", lastPost); }); @@ -407,11 +416,6 @@ Then("there are no notifications in the top menu", () => { }); Given("there is an annoying user called {string}", name => { - const annoyingParams = { - email: "spammy-spammer@example.org", - password: "1234", - ...termsAndConditionsAgreedVersion - }; cy.factory().create("User", { ...annoyingParams, id: "annoying-user", @@ -420,17 +424,17 @@ Given("there is an annoying user called {string}", name => { }); }); -Given("there is an annoying user who has blocked me", () => { +Given("there is an annoying user who has muted me", () => { cy.neode() .first("User", { role: 'moderator' }) - .then(blocked => { + .then(mutedUser => { cy.neode() .first("User", { id: 'annoying-user' }) - .relateTo(blocked, "blocked"); + .relateTo(mutedUser, "muted"); }); }); @@ -514,17 +518,17 @@ Given("I wrote a post {string}", title => { }); }); -When("I block the user {string}", name => { +When("I mute the user {string}", name => { cy.neode() .first("User", { name }) - .then(blocked => { + .then(mutedUser => { cy.neode() .first("User", { name: narratorParams.name }) - .relateTo(blocked, "blocked"); + .relateTo(mutedUser, "muted"); }); }); diff --git a/cypress/integration/moderation/ReportContent.feature b/cypress/integration/moderation/ReportContent.feature index 4eceb4bdf..c87d41230 100644 --- a/cypress/integration/moderation/ReportContent.feature +++ b/cypress/integration/moderation/ReportContent.feature @@ -11,7 +11,7 @@ Feature: Report and Moderate Given we have the following user accounts: | id | name | | u67 | David Irving | - | annoying-user | I'm gonna block Moderators and Admins HA HA HA | + | annoying-user | I'm gonna mute Moderators and Admins HA HA HA | Given we have the following posts in our database: | authorId | id | title | content | @@ -58,16 +58,16 @@ Feature: Report and Moderate Then I see all the reported posts including the one from above And each list item links to the post page - Scenario: Review reported posts of a user who's blocked a moderator + Scenario: Review reported posts of a user who's muted a moderator Given somebody reported the following posts: | submitterEmail | resourceId | reasonCategory | reasonDescription | | p2.submitter@example.org | p2 | other | Offensive content | And my user account has the role "moderator" - And there is an annoying user who has blocked me + And there is an annoying user who has muted me And I am logged in When I click on the avatar menu in the top right corner And I click on "Moderation" - Then I see all the reported posts including from the user who blocked me + Then I see all the reported posts including from the user who muted me And I can visit the post page Scenario: Normal user can't see the moderation page diff --git a/cypress/integration/user_profile/blocked-users/Content.feature b/cypress/integration/user_profile/blocked-users/Content.feature deleted file mode 100644 index edc0d63b9..000000000 --- a/cypress/integration/user_profile/blocked-users/Content.feature +++ /dev/null @@ -1,22 +0,0 @@ -Feature: Block a User - As a user - I'd like to have a button to block another user - To prevent him from seeing and interacting with my contributions and also to avoid seeing his/her posts - - Background: - Given I have a user account - And there is an annoying user called "Spammy Spammer" - - Scenario Outline: Blocked users cannot see each others posts - Given "Spammy Spammer" wrote a post "Spam Spam Spam" - And I wrote a post "I hate spammers" - And I block the user "Spammy Spammer" - When I log in with: - | Email | Password | - | | | - Then I see only one post with the title "" - Examples: - | email | password | expected_title | - | peterpan@example.org | 1234 | I hate spammers | - | spammy-spammer@example.org | 1234 | Spam Spam Spam | - diff --git a/cypress/integration/user_profile/blocked-users/Blocking.feature b/cypress/integration/user_profile/mute-users/Mute.feature similarity index 53% rename from cypress/integration/user_profile/blocked-users/Blocking.feature rename to cypress/integration/user_profile/mute-users/Mute.feature index 9b27f82a3..b52faeeaa 100644 --- a/cypress/integration/user_profile/blocked-users/Blocking.feature +++ b/cypress/integration/user_profile/mute-users/Mute.feature @@ -1,6 +1,6 @@ -Feature: Block a User +Feature: Mute a User As a user - I'd like to have a button to block another user + I'd like to have a button to mute another user To prevent him from seeing and interacting with my contributions and also to avoid seeing his/her posts Background: @@ -8,36 +8,46 @@ Feature: Block a User And there is an annoying user called "Spammy Spammer" And I am logged in - Scenario: Block a user + Scenario: Mute a user Given I am on the profile page of the annoying user - When I click on "Block user" from the content menu in the user info box - And I navigate to my "Blocked users" settings page + When I click on "Mute user" from the content menu in the user info box + And I navigate to my "Muted users" settings page Then I can see the following table: | Avatar | Name | | | Spammy Spammer | - Scenario: Block a previously followed user + Scenario: Mute a previously followed user Given I follow the user "Spammy Spammer" And "Spammy Spammer" wrote a post "Spam Spam Spam" When I visit the profile page of the annoying user - And I click on "Block user" from the content menu in the user info box + And I click on "Mute user" from the content menu in the user info box Then the list of posts of this user is empty And nobody is following the user profile anymore - Scenario: Posts of blocked users are filtered from search results + Scenario: Posts of muted users are filtered from search results Given we have the following posts in our database: - | id | title | content | - | im-not-blocked | Post that should be seen | cause I'm not blocked | + | id | title | content | + | im-not-muted | Post that should be seen | cause I'm not muted | Given "Spammy Spammer" wrote a post "Spam Spam Spam" When I search for "Spam" Then I should see the following posts in the select dropdown: | title | | Spam Spam Spam | - When I block the user "Spammy Spammer" + When I mute the user "Spammy Spammer" And I refresh the page And I search for "Spam" Then the search has no results - But I search for "not blocked" + But I search for "not muted" Then I should see the following posts in the select dropdown: | title | | Post that should be seen | + + Scenario: Muted users can still see my posts + Given I previously created a post + And I mute the user "Spammy Spammer" + Given I log out + And I am logged in as the muted user + When I search for "previously created" + Then I should see the following posts in the select dropdown: + | title | + | previously created post | diff --git a/cypress/support/commands.js b/cypress/support/commands.js index 13d33964a..c9a2e213a 100644 --- a/cypress/support/commands.js +++ b/cypress/support/commands.js @@ -60,6 +60,7 @@ Cypress.Commands.add("login", ({ email, password }) => { .as("submitButton") .click(); cy.get(".iziToast-message").should("contain", "You are logged in!"); + cy.location("pathname").should("eq", "/"); }); Cypress.Commands.add("logout", (email, password) => { diff --git a/package.json b/package.json index 0e8930251..b162d2c2d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "human-connection", - "version": "0.2.1", + "version": "0.2.2", "description": "Fullstack and API tests with cypress and cucumber for Human Connection", "author": "Human Connection gGmbh", "license": "MIT", @@ -18,8 +18,8 @@ "cypress:backend": "cd backend && yarn run dev", "cypress:webapp": "cd webapp && yarn run dev", "cypress:setup": "run-p cypress:backend cypress:webapp", - "cypress:run": "cross-env cypress run --browser chromium", - "cypress:open": "cross-env cypress open --browser chromium", + "cypress:run": "cross-env cypress run", + "cypress:open": "cross-env cypress open", "cucumber:setup": "cd backend && yarn run dev", "cucumber": "wait-on tcp:4000 && cucumber-js --require-module @babel/register --exit", "release": "standard-version" diff --git a/webapp/components/ContentMenu/ContentMenu.spec.js b/webapp/components/ContentMenu/ContentMenu.spec.js index 77ca36e35..f079f6240 100644 --- a/webapp/components/ContentMenu/ContentMenu.spec.js +++ b/webapp/components/ContentMenu/ContentMenu.spec.js @@ -407,49 +407,49 @@ describe('ContentMenu.vue', () => { ).toBe('/settings') }) - it('can block other users', () => { + it('can mute other users', () => { const wrapper = openContentMenu({ isOwner: false, resourceType: 'user', resource: { id: 'd23a4265-f5f7-4e17-9f86-85f714b4b9f8', - isBlocked: false, + isMuted: false, }, }) wrapper .findAll('.ds-menu-item') - .filter(item => item.text() === 'settings.blocked-users.block') + .filter(item => item.text() === 'settings.muted-users.mute') .at(0) .trigger('click') - expect(wrapper.emitted('block')).toEqual([ + expect(wrapper.emitted('mute')).toEqual([ [ { id: 'd23a4265-f5f7-4e17-9f86-85f714b4b9f8', - isBlocked: false, + isMuted: false, }, ], ]) }) - it('can unblock blocked users', () => { + it('can unmute muted users', () => { const wrapper = openContentMenu({ isOwner: false, resourceType: 'user', resource: { id: 'd23a4265-f5f7-4e17-9f86-85f714b4b9f8', - isBlocked: true, + isMuted: true, }, }) wrapper .findAll('.ds-menu-item') - .filter(item => item.text() === 'settings.blocked-users.unblock') + .filter(item => item.text() === 'settings.muted-users.unmute') .at(0) .trigger('click') - expect(wrapper.emitted('unblock')).toEqual([ + expect(wrapper.emitted('unmute')).toEqual([ [ { id: 'd23a4265-f5f7-4e17-9f86-85f714b4b9f8', - isBlocked: true, + isMuted: true, }, ], ]) diff --git a/webapp/components/ContentMenu/ContentMenu.vue b/webapp/components/ContentMenu/ContentMenu.vue index b3c73c687..a22bc3267 100644 --- a/webapp/components/ContentMenu/ContentMenu.vue +++ b/webapp/components/ContentMenu/ContentMenu.vue @@ -155,19 +155,19 @@ export default { icon: 'edit', }) } else { - if (this.resource.isBlocked) { + if (this.resource.isMuted) { routes.push({ - label: this.$t(`settings.blocked-users.unblock`), + label: this.$t(`settings.muted-users.unmute`), callback: () => { - this.$emit('unblock', this.resource) + this.$emit('unmute', this.resource) }, icon: 'user-plus', }) } else { routes.push({ - label: this.$t(`settings.blocked-users.block`), + label: this.$t(`settings.muted-users.mute`), callback: () => { - this.$emit('block', this.resource) + this.$emit('mute', this.resource) }, icon: 'user-times', }) diff --git a/webapp/components/UserTeaser/UserTeaser.story.js b/webapp/components/UserTeaser/UserTeaser.story.js index 62b0d37c8..488576bd5 100644 --- a/webapp/components/UserTeaser/UserTeaser.story.js +++ b/webapp/components/UserTeaser/UserTeaser.story.js @@ -48,7 +48,7 @@ export const user = { ], followedByCount: 0, followedByCurrentUser: false, - isBlocked: false, + isMuted: false, followedBy: [], socialMedia: [], } diff --git a/webapp/graphql/User.js b/webapp/graphql/User.js index 4ed832ad3..8962830dc 100644 --- a/webapp/graphql/User.js +++ b/webapp/graphql/User.js @@ -23,7 +23,7 @@ export default i18n => { locationName createdAt followedByCurrentUser - isBlocked + isMuted following(first: 7) { ...user ...userCounts diff --git a/webapp/graphql/settings/BlockedUsers.js b/webapp/graphql/settings/MutedUsers.js similarity index 66% rename from webapp/graphql/settings/BlockedUsers.js rename to webapp/graphql/settings/MutedUsers.js index 8f882f8ad..55ea34769 100644 --- a/webapp/graphql/settings/BlockedUsers.js +++ b/webapp/graphql/settings/MutedUsers.js @@ -1,9 +1,9 @@ import gql from 'graphql-tag' -export const BlockedUsers = () => { +export const mutedUsers = () => { return gql` { - blockedUsers { + mutedUsers { id name slug @@ -16,26 +16,26 @@ export const BlockedUsers = () => { ` } -export const Block = () => { +export const muteUser = () => { return gql` mutation($id: ID!) { - block(id: $id) { + muteUser(id: $id) { id name - isBlocked + isMuted followedByCurrentUser } } ` } -export const Unblock = () => { +export const unmuteUser = () => { return gql` mutation($id: ID!) { - unblock(id: $id) { + unmuteUser(id: $id) { id name - isBlocked + isMuted followedByCurrentUser } } diff --git a/webapp/locales/de.json b/webapp/locales/de.json index 4307a9593..d52a9817c 100644 --- a/webapp/locales/de.json +++ b/webapp/locales/de.json @@ -76,9 +76,6 @@ "download": { "name": "Daten herunterladen" }, - "delete": { - "name": "Konto löschen" - }, "organizations": { "name": "Meine Organisationen" }, @@ -145,26 +142,23 @@ "successAdd": "Social-Media hinzugefügt. Profil aktualisiert!", "successDelete": "Social-Media gelöscht. Profil aktualisiert!" }, - "blocked-users": { - "name": "Blockierte Benutzer", + "muted-users": { + "name": "Stummgeschaltete Benutzer", "explanation": { - "intro": "Wenn ein anderer Benutzer von dir blockiert wurde, dann passiert folgendes:", - "your-perspective": "In deiner Beitragsübersicht tauchen keine Beiträge der blockierten Person mehr auf.", - "their-perspective": "Umgekehrt das gleiche: Die blockierte Person sieht deine Beiträge auch nicht mehr in ihrer Übersicht.", - "search": "Die Beiträge von blockierten Personen verschwinden aus deinen Suchergebnissen.", - "notifications": "Von dir blockierte Personen erhalten keine Benachrichtigungen mehr, wenn sie in deinen Beiträgen erwähnt werden.", - "closing": "Das sollte fürs Erste genügen, damit blockierte Benutzer dich nicht mehr länger belästigen können." + "intro": "Wenn ein anderer Benutzer von dir stummgeschaltet wurde, dann passiert folgendes:", + "your-perspective": "In deiner Beitragsübersicht tauchen keine Beiträge der stummgeschalteten Person mehr auf.", + "search": "Die Beiträge von stummgeschalteten Personen verschwinden aus deinen Suchergebnissen." }, "columns": { "name": "Name", "slug": "Alias", - "unblock": "Entsperren" + "unmute": "Entsperren" }, - "empty": "Bislang hast du niemanden blockiert.", - "how-to": "Du kannst andere Benutzer auf deren Profilseite über das Inhaltsmenü blockieren.", - "block": "Nutzer blockieren", - "unblock": "Nutzer entblocken", - "unblocked": "{name} ist wieder entsperrt" + "empty": "Bislang hast du niemanden stummgeschaltet.", + "how-to": "Du kannst andere Benutzer auf deren Profilseite über das Inhaltsmenü stummschalten.", + "mute": "Stumm schalten", + "unmute": "Stummschaltung aufheben", + "unmuted": "{name} ist nicht mehr stummgeschaltet" }, "privacy": { "name": "Privatsphäre", @@ -217,11 +211,6 @@ "categoryName": "Name", "postCount": "Beiträge" }, - "tags": { - "name": "Schlagworte", - "tagCountUnique": "Benutzer", - "tagCount": "Beiträge" - }, "settings": { "name": "Einstellungen" }, @@ -268,7 +257,7 @@ }, "comment": { "submit": "Kommentiere", - "submitted": "Kommentar Gesendet", + "submitted": "Kommentar gesendet", "updated": "Änderungen gespeichert" }, "edited": "bearbeitet" @@ -444,8 +433,6 @@ } }, "contribution": { - "edit": "Beitrag bearbeiten", - "delete": "Beitrag löschen", "title": "Titel", "newPost": "Erstelle einen neuen Beitrag", "filterFollow": "Beiträge filtern von Usern denen ich folge", @@ -485,13 +472,11 @@ }, "teaserImage": { "cropperConfirm": "Bestätigen" - }, + }, "inappropriatePicture" : "Dieses Bild kann für einige Menschen unangemessen sein.", "inappropriatePictureText" : "Wann soll ein Foto versteckt werden" }, "comment": { - "edit": "Kommentar bearbeiten", - "delete": "Kommentar löschen", "content": { "unavailable-placeholder": "… dieser Kommentar ist nicht mehr verfügbar" }, diff --git a/webapp/locales/en.json b/webapp/locales/en.json index cf4b9e407..79a101b09 100644 --- a/webapp/locales/en.json +++ b/webapp/locales/en.json @@ -312,26 +312,23 @@ "successAdd": "Added social media. Updated user profile!", "successDelete": "Deleted social media. Updated user profile!" }, - "blocked-users": { - "name": "Blocked users", + "muted-users": { + "name": "Muted users", "explanation": { - "intro": "If another user has been blocked by you, this is what happens:", - "your-perspective": "The blocked person's posts will no longer appear in your news feed.", - "their-perspective": "Vice versa: The blocked person will also no longer see your posts in their news feed.", - "search": "Posts of blocked people disappear from your search results.", - "notifications": "Blocked users will no longer receive notifications if they are mentioned in your posts.", - "closing": "This should be sufficient for now so that blocked users can no longer bother you." + "intro": "If another user has been muted by you, this is what happens:", + "your-perspective": "The muted person's posts will no longer appear in your news feed.", + "search": "Posts of muted people disappear from your search results." }, "columns": { "name": "Name", "slug": "Slug", - "unblock": "Unblock" + "unmute": "Unmute" }, - "empty": "So far, you have not blocked anybody.", - "how-to": "You can block other users on their profile page via the content menu.", - "block": "Block user", - "unblock": "Unblock user", - "unblocked": "{name} is unblocked again" + "empty": "So far, you have not muted anybody.", + "how-to": "You can mute other users on their profile page via the content menu.", + "mute": "Mute user", + "unmute": "Unmute user", + "unmuted": "{name} is unmuted again" } }, "admin": { diff --git a/webapp/locales/es.json b/webapp/locales/es.json index 402d95450..f916f849b 100644 --- a/webapp/locales/es.json +++ b/webapp/locales/es.json @@ -145,26 +145,23 @@ "successAdd": "Social-Media agregó. Perfil actualizado!", "successDelete": "Social-Media borrado. Perfil actualizado!" }, - "blocked-users": { + "muted-users": { "name": "Usuarios bloqueados", "explanation": { "intro": "Si otro usuario ha sido bloqueado por usted, esto es lo que sucede:", "your-perspective": "Las contribuciones de la persona bloqueada no aparecerán más en su canal de noticias.", - "their-perspective": "Viceversa: la persona bloqueada tampoco verá más sus contribuciones en sus noticias.", - "search": "Las contribuciones de personas bloqueadas desaparecen de los resultados de búsqueda.", - "notifications": "Los usuarios bloqueados no recibirán más notificaciones si se mencionan en sus contribuciones.", - "closing": "Esto debería ser suficiente por ahora para que los usuarios bloqueados no puedan molestarle más." + "search": "Las contribuciones de personas bloqueadas desaparecen de los resultados de búsqueda." }, "columns": { "name": "Nombre", "slug": "Alias", - "unblock": "Desbloquear" + "unmute": "Desbloquear" }, "empty": "Hasta ahora, no ha bloqueado a nadie.", "how-to": "Puede bloquear a otros usuarios en la página de perfil de aquellos a través del menú de contenido.", - "block": "Bloquear usuario", - "unblock": "Desbloquear usuario", - "unblocked": "{name} está desbloqueado nuevamente" + "mute": "Bloquear usuario", + "unmute": "Desbloquear usuario", + "unmuted": "{name} está desbloqueado nuevamente" }, "privacy": { "name": "Privacidad", diff --git a/webapp/locales/fr.json b/webapp/locales/fr.json index 82027b3dd..92ca5482e 100644 --- a/webapp/locales/fr.json +++ b/webapp/locales/fr.json @@ -145,26 +145,23 @@ "successAdd": "Les médias sociaux ont été ajoutés. Profil mis à jour !", "successDelete": "Médias sociaux supprimé. Profil mis à jour !" }, - "blocked-users": { + "muted-users": { "name": "Utilisateurs bloqués", "explanation": { "intro": "Si vous avez bloqué un autre utilisateur, voici ce qui se passe:", "your-perspective": "Les postes de la personne bloquée n'apparaîtront dans votre fil d'actualités.", - "their-perspective": "Vice versa: la personne bloquée ne verra plus non plus vos postes dans son fil d'actualités.", - "search": "Les postes des personnes bloquées disparaissent de vos résultats de recherche.", - "notifications": "Les utilisateurs bloqués ne recevront plus de notifications s'ils sont mentionnés dans vos postes.", - "closing": "Ceci devrait être suffisant pour le moment afin que les utilisateurs bloqués ne puissent plus vous déranger." + "search": "Les postes des personnes bloquées disparaissent de vos résultats de recherche." }, "columns": { "name": "Nom", "slug": "Slug", - "unblock": "" + "unmute": "" }, "empty": "Jusqu'à présent, vous n'avez bloqué personne.", "how-to": "Vous pouvez bloquer d'autres utilisateurs sur leur page de profil via le menu de contenu.", - "block": "Bloquer l'utilisateur", - "unblock": "Débloquer l'utilisateur", - "unblocked": "{name} est à nouveau débloqué" + "mute": "Bloquer l'utilisateur", + "unmute": "Débloquer l'utilisateur", + "unmuted": "{name} est à nouveau débloqué" }, "privacy": { "name": "", diff --git a/webapp/locales/it.json b/webapp/locales/it.json index 59ee4463b..d07f95086 100644 --- a/webapp/locales/it.json +++ b/webapp/locales/it.json @@ -145,26 +145,23 @@ "successAdd": "Social media aggiunti. \nProfilo utente aggiornato ", "successDelete": "Social media cancellati. Profilo utente aggiornato!" }, - "blocked-users": { - "name": "", + "muted-users": { + "name": null, "explanation": { - "intro": "", - "your-perspective": "", - "their-perspective": "", - "search": "", - "notifications": "", - "closing": "" + "intro": null, + "your-perspective": null, + "search": null }, "columns": { - "name": "", - "slug": "", - "unblock": "" + "name": null, + "slug": null, + "unmute": null }, - "empty": "", - "how-to": "", - "block": "", - "unblock": "", - "unblocked": "" + "empty": null, + "how-to": null, + "mute": null, + "unmute": null, + "unmuted": null }, "privacy": { "name": "", diff --git a/webapp/locales/pt.json b/webapp/locales/pt.json index b1aef0e9e..29fe301c8 100644 --- a/webapp/locales/pt.json +++ b/webapp/locales/pt.json @@ -145,26 +145,23 @@ "successAdd": "Mídias sociais adicionadas. Perfil de usuário atualizado!", "successDelete": "Mídias sociais removidas. Perfil de usuário atualizado!" }, - "blocked-users": { + "muted-users": { "name": "Usuários bloqueados", "explanation": { "intro": "Se outro usuário foi bloqueado por você, isto é o que acontece:", "your-perspective": "As mensagens da pessoa bloqueada não aparecerão mais no seu feed de notícias.", - "their-perspective": "Vice versa: A pessoa bloqueada também não verá mais suas mensagens em seu feed de notícias.", - "search": "Publicações de pessoas bloqueadas desaparecem dos resultados da sua pesquisa.", - "notifications": "Usuários bloqueados não receberão mais notificações se forem mencionados em suas mensagens.", - "closing": "Isso deve ser suficiente por enquanto para que os usuários bloqueados não possam mais incomodá-lo." + "search": "Publicações de pessoas bloqueadas desaparecem dos resultados da sua pesquisa." }, "columns": { "name": "Nome", "slug": "Slug", - "unblock": "Desbloquear" + "unmute": "Desbloquear" }, "empty": "Até agora, você não bloqueou ninguém.", "how-to": "Você pode bloquear outros usuários em suas páginas de perfil através do menu de conteúdo.", - "block": "Bloquear usuário", - "unblock": "Desbloquear usuário", - "unblocked": "{name} está desbloqueado novamente" + "mute": "Bloquear usuário", + "unmute": "Desbloquear usuário", + "unmuted": "{name} está desbloqueado novamente" }, "privacy": { "name": "Privacidade", diff --git a/webapp/locales/ru.json b/webapp/locales/ru.json index 4b24ae67c..64af8f693 100644 --- a/webapp/locales/ru.json +++ b/webapp/locales/ru.json @@ -595,26 +595,23 @@ "placeholder": "Поиск" }, "settings": { - "blocked-users": { - "block": "Блокировать", + "muted-users": { + "mute": "Блокировать", "columns": { "name": "Имя", "slug": "Псевдоним", - "unblock": "Разблокировать" + "unmute": "Разблокировать" }, "empty": "Вы пока никого не блокировали.", "explanation": { - "closing": "На данный момент этого должно быть достаточно, чтобы заблокированные пользователи больше вас не беспокоили.", "intro": "Если блокируете другого пользователя, происходит следующее:", - "notifications": "Заблокированные пользователи больше не будут получать уведомления об упоминаниях в ваших постах.", "search": "Посты заблокированных пользователей не отображаются в результатах поиска.", - "their-perspective": "И наоборот — заблокированный пользователь больше не видит ваши посты в своей ленте.", "your-perspective": "Посты заблокированного пользователя не отображаются в персональной ленте." }, "how-to": "Вы можете блокировать других пользователей на странице их профиля с помощью меню профиля.", "name": "Заблокированные пользователи", - "unblock": "Разблокировать пользователей", - "unblocked": "{name} - снова разблокирован" + "unmute": "Разблокировать пользователей", + "unmuted": "{name} - снова разблокирован" }, "data": { "labelBio": "О себе", diff --git a/webapp/package.json b/webapp/package.json index a0b1637c2..a50816c2d 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -1,6 +1,6 @@ { "name": "human-connection-webapp", - "version": "0.2.1", + "version": "0.2.2", "description": "Human Connection Frontend", "authors": [ "Grzegorz Leoniec (appinteractive)", @@ -84,7 +84,7 @@ "tiptap": "~1.26.6", "tiptap-extensions": "~1.28.6", "trunc-html": "^1.1.2", - "v-tooltip": "~2.0.2", + "v-tooltip": "~2.0.3", "validator": "^12.1.0", "vue-count-to": "~1.0.13", "vue-infinite-loading": "^2.4.4", @@ -99,14 +99,14 @@ "@babel/core": "~7.8.3", "@babel/plugin-syntax-dynamic-import": "^7.8.3", "@babel/preset-env": "~7.8.3", - "@storybook/addon-a11y": "^5.3.6", - "@storybook/addon-actions": "^5.3.5", - "@storybook/addon-notes": "^5.3.6", - "@storybook/vue": "~5.3.6", + "@storybook/addon-a11y": "^5.3.7", + "@storybook/addon-actions": "^5.3.7", + "@storybook/addon-notes": "^5.3.7", + "@storybook/vue": "~5.3.7", "@vue/cli-shared-utils": "~4.1.2", "@vue/eslint-config-prettier": "~6.0.0", - "@vue/server-test-utils": "~1.0.0-beta.30", - "@vue/test-utils": "~1.0.0-beta.30", + "@vue/server-test-utils": "~1.0.0-beta.31", + "@vue/test-utils": "~1.0.0-beta.31", "async-validator": "^3.2.3", "babel-core": "~7.0.0-bridge.0", "babel-eslint": "~10.0.3", diff --git a/webapp/pages/profile/_id/_slug.vue b/webapp/pages/profile/_id/_slug.vue index 0a37dbb38..ce220b66b 100644 --- a/webapp/pages/profile/_id/_slug.vue +++ b/webapp/pages/profile/_id/_slug.vue @@ -22,8 +22,8 @@ :resource="user" :is-owner="myProfile" class="user-content-menu" - @block="block" - @unblock="unblock" + @mute="muteUser" + @unmute="unmuteUser" /> @@ -67,14 +67,14 @@ @@ -284,7 +284,7 @@ import MasonryGrid from '~/components/MasonryGrid/MasonryGrid.vue' import MasonryGridItem from '~/components/MasonryGrid/MasonryGridItem.vue' import { profilePagePosts } from '~/graphql/PostQuery' import UserQuery from '~/graphql/User' -import { Block, Unblock } from '~/graphql/settings/BlockedUsers' +import { muteUser, unmuteUser } from '~/graphql/settings/MutedUsers' import PostMutations from '~/graphql/PostMutations' import UpdateQuery from '~/components/utils/UpdateQuery' @@ -395,17 +395,27 @@ export default { this.posts = [] this.hasMore = true }, - async block(user) { - await this.$apollo.mutate({ mutation: Block(), variables: { id: user.id } }) - this.$apollo.queries.User.refetch() - this.resetPostList() - this.$apollo.queries.profilePagePosts.refetch() + async muteUser(user) { + try { + await this.$apollo.mutate({ mutation: muteUser(), variables: { id: user.id } }) + } catch (error) { + this.$toast.error(error.message) + } finally { + this.$apollo.queries.User.refetch() + this.resetPostList() + this.$apollo.queries.profilePagePosts.refetch() + } }, - async unblock(user) { - await this.$apollo.mutate({ mutation: Unblock(), variables: { id: user.id } }) - this.$apollo.queries.User.refetch() - this.resetPostList() - this.$apollo.queries.profilePagePosts.refetch() + async unmuteUser(user) { + try { + this.$apollo.mutate({ mutation: unmuteUser(), variables: { id: user.id } }) + } catch (error) { + this.$toast.error(error.message) + } finally { + this.$apollo.queries.User.refetch() + this.resetPostList() + this.$apollo.queries.profilePagePosts.refetch() + } }, pinPost(post) { this.$apollo diff --git a/webapp/pages/settings.vue b/webapp/pages/settings.vue index 709499484..5684da024 100644 --- a/webapp/pages/settings.vue +++ b/webapp/pages/settings.vue @@ -40,8 +40,8 @@ export default { path: `/settings/my-social-media`, }, { - name: this.$t('settings.blocked-users.name'), - path: `/settings/blocked-users`, + name: this.$t('settings.muted-users.name'), + path: `/settings/muted-users`, }, { name: this.$t('settings.embeds.name'), diff --git a/webapp/pages/settings/blocked-users.spec.js b/webapp/pages/settings/muted-users.spec.js similarity index 69% rename from webapp/pages/settings/blocked-users.spec.js rename to webapp/pages/settings/muted-users.spec.js index c78de5dc7..7d536e45c 100644 --- a/webapp/pages/settings/blocked-users.spec.js +++ b/webapp/pages/settings/muted-users.spec.js @@ -1,8 +1,8 @@ import { config, mount, createLocalVue } from '@vue/test-utils' -import BlockedUsers from './blocked-users.vue' +import MutedUsers from './muted-users.vue' import Styleguide from '@human-connection/styleguide' import Filters from '~/plugins/vue-filters' -import { Unblock } from '~/graphql/settings/BlockedUsers' +import { unmuteUser } from '~/graphql/settings/MutedUsers' const localVue = createLocalVue() @@ -11,7 +11,7 @@ localVue.use(Filters) config.stubs['nuxt-link'] = '' -describe('blocked-users.vue', () => { +describe('muted-users.vue', () => { let wrapper let mocks @@ -21,7 +21,7 @@ describe('blocked-users.vue', () => { $apollo: { mutate: jest.fn(), queries: { - blockedUsers: { + mutedUsers: { refetch: jest.fn(), }, }, @@ -35,7 +35,7 @@ describe('blocked-users.vue', () => { describe('mount', () => { const Wrapper = () => { - return mount(BlockedUsers, { mocks, localVue }) + return mount(MutedUsers, { mocks, localVue }) } beforeEach(() => { @@ -48,18 +48,18 @@ describe('blocked-users.vue', () => { describe('given a list of blocked users', () => { beforeEach(() => { - const blockedUsers = [{ id: 'u1', name: 'John Doe', slug: 'john-doe', avatar: '' }] - wrapper.setData({ blockedUsers }) + const mutedUsers = [{ id: 'u1', name: 'John Doe', slug: 'john-doe', avatar: '' }] + wrapper.setData({ mutedUsers }) }) - describe('click unblock', () => { + describe('click unmute', () => { beforeEach(() => { wrapper.find('button').trigger('click') }) - it('calls unblock mutation with given user', () => { + it('calls unmute mutation with given user', () => { expect(mocks.$apollo.mutate).toHaveBeenCalledWith({ - mutation: Unblock(), + mutation: unmuteUser(), variables: { id: 'u1' }, }) }) diff --git a/webapp/pages/settings/blocked-users.vue b/webapp/pages/settings/muted-users.vue similarity index 54% rename from webapp/pages/settings/blocked-users.vue rename to webapp/pages/settings/muted-users.vue index 6a82cb8d9..b33c0e571 100644 --- a/webapp/pages/settings/blocked-users.vue +++ b/webapp/pages/settings/muted-users.vue @@ -1,31 +1,22 @@