Rename blacklist/whitelist to mute/unmute

- Follow @roschaefer suggestion in issue
- This can be reverted if we decide otherwise
This commit is contained in:
mattwr18 2020-01-08 18:04:26 +01:00
parent cd7f0e2783
commit ba3e9e1025
29 changed files with 274 additions and 274 deletions

View File

@ -99,7 +99,7 @@ export default shield(
Badge: allow, Badge: allow,
PostsEmotionsCountByEmotion: allow, PostsEmotionsCountByEmotion: allow,
PostsEmotionsByCurrentUser: isAuthenticated, PostsEmotionsByCurrentUser: isAuthenticated,
blacklistedUsers: isAuthenticated, mutedUsers: isAuthenticated,
notifications: isAuthenticated, notifications: isAuthenticated,
Donations: isAuthenticated, Donations: isAuthenticated,
}, },
@ -135,8 +135,8 @@ export default shield(
resetPassword: allow, resetPassword: allow,
AddPostEmotions: isAuthenticated, AddPostEmotions: isAuthenticated,
RemovePostEmotions: isAuthenticated, RemovePostEmotions: isAuthenticated,
blacklistUserContent: isAuthenticated, muteUser: isAuthenticated,
whitelistUserContent: isAuthenticated, unmuteUser: isAuthenticated,
markAsRead: isAuthenticated, markAsRead: isAuthenticated,
AddEmailAddress: isAuthenticated, AddEmailAddress: isAuthenticated,
VerifyEmailAddress: isAuthenticated, VerifyEmailAddress: isAuthenticated,

View File

@ -78,9 +78,9 @@ module.exports = {
target: 'User', target: 'User',
direction: 'out', direction: 'out',
}, },
blacklisted: { muted: {
type: 'relationship', type: 'relationship',
relationship: 'BLACKLISTED', relationship: 'MUTED',
target: 'User', target: 'User',
direction: 'out', direction: 'out',
}, },

View File

@ -1,21 +1,21 @@
import uuid from 'uuid/v4' import uuid from 'uuid/v4'
import { neo4jgraphql } from 'neo4j-graphql-js' import { neo4jgraphql } from 'neo4j-graphql-js'
import fileUpload from './fileUpload' import fileUpload from './fileUpload'
import { getBlacklistedUsers } from './users.js' import { getMutedUsers } from './users.js'
import { mergeWith, isArray, isEmpty } from 'lodash' import { mergeWith, isArray, isEmpty } from 'lodash'
import { UserInputError } from 'apollo-server' import { UserInputError } from 'apollo-server'
import Resolver from './helpers/Resolver' import Resolver from './helpers/Resolver'
const filterForBlacklistedUsers = async (params, context) => { const filterForMutedUsers = async (params, context) => {
if (!context.user) return params if (!context.user) return params
const [blacklistedUsers] = await Promise.all([getBlacklistedUsers(context)]) const [mutedUsers] = await Promise.all([getMutedUsers(context)])
const blacklistedUsersIds = [...blacklistedUsers.map(user => user.id)] const mutedUsersIds = [...mutedUsers.map(user => user.id)]
if (!blacklistedUsersIds.length) return params if (!mutedUsersIds.length) return params
params.filter = mergeWith( params.filter = mergeWith(
params.filter, params.filter,
{ {
author_not: { id_in: blacklistedUsersIds }, author_not: { id_in: mutedUsersIds },
}, },
(objValue, srcValue) => { (objValue, srcValue) => {
if (isArray(objValue)) { if (isArray(objValue)) {
@ -39,16 +39,16 @@ const maintainPinnedPosts = params => {
export default { export default {
Query: { Query: {
Post: async (object, params, context, resolveInfo) => { Post: async (object, params, context, resolveInfo) => {
params = await filterForBlacklistedUsers(params, context) params = await filterForMutedUsers(params, context)
params = await maintainPinnedPosts(params) params = await maintainPinnedPosts(params)
return neo4jgraphql(object, params, context, resolveInfo) return neo4jgraphql(object, params, context, resolveInfo)
}, },
findPosts: async (object, params, context, resolveInfo) => { findPosts: async (object, params, context, resolveInfo) => {
params = await filterForBlacklistedUsers(params, context) params = await filterForMutedUsers(params, context)
return neo4jgraphql(object, params, context, resolveInfo) return neo4jgraphql(object, params, context, resolveInfo)
}, },
profilePagePosts: async (object, params, context, resolveInfo) => { profilePagePosts: async (object, params, context, resolveInfo) => {
params = await filterForBlacklistedUsers(params, context) params = await filterForMutedUsers(params, context)
return neo4jgraphql(object, params, context, resolveInfo) return neo4jgraphql(object, params, context, resolveInfo)
}, },
PostsEmotionsCountByEmotion: async (object, params, context, resolveInfo) => { PostsEmotionsCountByEmotion: async (object, params, context, resolveInfo) => {

View File

@ -8,26 +8,26 @@ import createOrUpdateLocations from './users/location'
const neode = getNeode() const neode = getNeode()
export const getBlacklistedUsers = async context => { export const getMutedUsers = async context => {
const { neode } = context const { neode } = context
const userModel = neode.model('User') const userModel = neode.model('User')
let blacklistedUsers = neode let mutedUsers = neode
.query() .query()
.match('user', userModel) .match('user', userModel)
.where('user.id', context.user.id) .where('user.id', context.user.id)
.relationship(userModel.relationships().get('blacklisted')) .relationship(userModel.relationships().get('muted'))
.to('blacklisted', userModel) .to('muted', userModel)
.return('blacklisted') .return('muted')
blacklistedUsers = await blacklistedUsers.execute() mutedUsers = await mutedUsers.execute()
blacklistedUsers = blacklistedUsers.records.map(r => r.get('blacklisted').properties) mutedUsers = mutedUsers.records.map(r => r.get('muted').properties)
return blacklistedUsers return mutedUsers
} }
export default { export default {
Query: { Query: {
blacklistedUsers: async (object, args, context, resolveInfo) => { mutedUsers: async (object, args, context, resolveInfo) => {
try { try {
return getBlacklistedUsers(context) return getMutedUsers(context)
} catch (e) { } catch (e) {
throw new UserInputError(e.message) throw new UserInputError(e.message)
} }
@ -56,7 +56,7 @@ export default {
}, },
}, },
Mutation: { Mutation: {
blacklistUserContent: async (_parent, params, context, _resolveInfo) => { muteUser: async (_parent, params, context, _resolveInfo) => {
const { user: currentUser } = context const { user: currentUser } = context
if (currentUser.id === params.id) return null if (currentUser.id === params.id) return null
await neode.cypher( await neode.cypher(
@ -66,25 +66,25 @@ export default {
`, `,
{ currentUser, params }, { currentUser, params },
) )
const [user, blacklistedUser] = await Promise.all([ const [user, mutedUser] = await Promise.all([
neode.find('User', currentUser.id), neode.find('User', currentUser.id),
neode.find('User', params.id), neode.find('User', params.id),
]) ])
await user.relateTo(blacklistedUser, 'blacklisted') await user.relateTo(mutedUser, 'muted')
return blacklistedUser.toJson() return mutedUser.toJson()
}, },
whitelistUserContent: async (_parent, params, context, _resolveInfo) => { unmuteUser: async (_parent, params, context, _resolveInfo) => {
const { user: currentUser } = context const { user: currentUser } = context
if (currentUser.id === params.id) return null if (currentUser.id === params.id) return null
await neode.cypher( await neode.cypher(
` `
MATCH(u:User {id: $currentUser.id})-[previousRelationship:BLACKLISTED]->(b:User {id: $params.id}) MATCH(u:User {id: $currentUser.id})-[previousRelationship:MUTED]->(b:User {id: $params.id})
DELETE previousRelationship DELETE previousRelationship
`, `,
{ currentUser, params }, { currentUser, params },
) )
const whitelistedUser = await neode.find('User', params.id) const unmutedUser = await neode.find('User', params.id)
return whitelistedUser.toJson() return unmutedUser.toJson()
}, },
block: async (object, args, context, resolveInfo) => { block: async (object, args, context, resolveInfo) => {
const { user: currentUser } = context const { user: currentUser } = context
@ -231,8 +231,8 @@ export default {
'MATCH (this)<-[:FOLLOWS]-(u:User {id: $cypherParams.currentUserId}) RETURN COUNT(u) >= 1', 'MATCH (this)<-[:FOLLOWS]-(u:User {id: $cypherParams.currentUserId}) RETURN COUNT(u) >= 1',
isBlocked: isBlocked:
'MATCH (this)<-[:BLOCKED]-(u:User {id: $cypherParams.currentUserId}) RETURN COUNT(u) >= 1', 'MATCH (this)<-[:BLOCKED]-(u:User {id: $cypherParams.currentUserId}) RETURN COUNT(u) >= 1',
isBlacklisted: isMuted:
'MATCH (this)<-[:BLACKLISTED]-(u:User {id: $cypherParams.currentUserId}) RETURN COUNT(u) >= 1', 'MATCH (this)<-[:MUTED]-(u:User {id: $cypherParams.currentUserId}) RETURN COUNT(u) >= 1',
}, },
count: { count: {
contributionsCount: contributionsCount:

View File

@ -9,7 +9,7 @@ const factory = Factory()
const neode = getNeode() const neode = getNeode()
let currentUser let currentUser
let blacklistedUser let mutedUser
let authenticatedUser let authenticatedUser
let server let server
@ -33,15 +33,15 @@ afterEach(async () => {
await factory.cleanDatabase() await factory.cleanDatabase()
}) })
describe('blacklistedUsers', () => { describe('mutedUsers', () => {
let blacklistedUserQuery let mutedUserQuery
beforeEach(() => { beforeEach(() => {
blacklistedUserQuery = gql` mutedUserQuery = gql`
query { query {
blacklistedUsers { mutedUsers {
id id
name name
isBlacklisted isMuted
} }
} }
` `
@ -49,34 +49,34 @@ describe('blacklistedUsers', () => {
it('throws permission error', async () => { it('throws permission error', async () => {
const { query } = createTestClient(server) const { query } = createTestClient(server)
const result = await query({ query: blacklistedUserQuery }) const result = await query({ query: mutedUserQuery })
expect(result.errors[0]).toHaveProperty('message', 'Not Authorised!') expect(result.errors[0]).toHaveProperty('message', 'Not Authorised!')
}) })
describe('authenticated and given a blacklisted user', () => { describe('authenticated and given a muted user', () => {
beforeEach(async () => { beforeEach(async () => {
currentUser = await neode.create('User', { currentUser = await neode.create('User', {
name: 'Current User', name: 'Current User',
id: 'u1', id: 'u1',
}) })
blacklistedUser = await neode.create('User', { mutedUser = await neode.create('User', {
name: 'Blacklisted User', name: 'Muted User',
id: 'u2', id: 'u2',
}) })
await currentUser.relateTo(blacklistedUser, 'blacklisted') await currentUser.relateTo(mutedUser, 'muted')
authenticatedUser = await currentUser.toJson() authenticatedUser = await currentUser.toJson()
}) })
it('returns a list of blacklisted users', async () => { it('returns a list of muted users', async () => {
const { query } = createTestClient(server) const { query } = createTestClient(server)
await expect(query({ query: blacklistedUserQuery })).resolves.toEqual( await expect(query({ query: mutedUserQuery })).resolves.toEqual(
expect.objectContaining({ expect.objectContaining({
data: { data: {
blacklistedUsers: [ mutedUsers: [
{ {
name: 'Blacklisted User', name: 'Muted User',
id: 'u2', id: 'u2',
isBlacklisted: true, isMuted: true,
}, },
], ],
}, },
@ -86,28 +86,28 @@ describe('blacklistedUsers', () => {
}) })
}) })
describe('blacklistUserContent', () => { describe('muteUser', () => {
let blacklistAction let muteAction
beforeEach(() => { beforeEach(() => {
currentUser = undefined currentUser = undefined
blacklistAction = variables => { muteAction = variables => {
const { mutate } = createTestClient(server) const { mutate } = createTestClient(server)
const blacklistUserContentMutation = gql` const muteUserMutation = gql`
mutation($id: ID!) { mutation($id: ID!) {
blacklistUserContent(id: $id) { muteUser(id: $id) {
id id
name name
isBlacklisted isMuted
} }
} }
` `
return mutate({ mutation: blacklistUserContentMutation, variables }) return mutate({ mutation: muteUserMutation, variables })
} }
}) })
it('throws permission error', async () => { it('throws permission error', async () => {
const result = await blacklistAction({ id: 'u2' }) const result = await muteAction({ id: 'u2' })
expect(result.errors[0]).toHaveProperty('message', 'Not Authorised!') expect(result.errors[0]).toHaveProperty('message', 'Not Authorised!')
}) })
@ -120,47 +120,47 @@ describe('blacklistUserContent', () => {
authenticatedUser = await currentUser.toJson() authenticatedUser = await currentUser.toJson()
}) })
describe('blacklist yourself', () => { describe('mute yourself', () => {
it('returns null', async () => { it('returns null', async () => {
await expect(blacklistAction({ id: 'u1' })).resolves.toEqual( await expect(muteAction({ id: 'u1' })).resolves.toEqual(
expect.objectContaining({ data: { blacklistUserContent: null } }), expect.objectContaining({ data: { muteUser: null } }),
) )
}) })
}) })
describe('blacklist not existing user', () => { describe('mute not existing user', () => {
it('returns null', async () => { it('returns null', async () => {
await expect(blacklistAction({ id: 'u2' })).resolves.toEqual( await expect(muteAction({ id: 'u2' })).resolves.toEqual(
expect.objectContaining({ data: { blacklistUserContent: null } }), expect.objectContaining({ data: { muteUser: null } }),
) )
}) })
}) })
describe('given a to-be-blacklisted user', () => { describe('given a to-be-muted user', () => {
beforeEach(async () => { beforeEach(async () => {
blacklistedUser = await neode.create('User', { mutedUser = await neode.create('User', {
name: 'Blacklisted User', name: 'Muted User',
id: 'u2', id: 'u2',
}) })
}) })
it('blacklists a user', async () => { it('mutes a user', async () => {
await expect(blacklistAction({ id: 'u2' })).resolves.toEqual( await expect(muteAction({ id: 'u2' })).resolves.toEqual(
expect.objectContaining({ expect.objectContaining({
data: { data: {
blacklistUserContent: { id: 'u2', name: 'Blacklisted User', isBlacklisted: true }, muteUser: { id: 'u2', name: 'Muted User', isMuted: true },
}, },
}), }),
) )
}) })
it('unfollows the user', async () => { it('unfollows the user', async () => {
await currentUser.relateTo(blacklistedUser, 'following') await currentUser.relateTo(mutedUser, 'following')
const queryUser = gql` const queryUser = gql`
query { query {
User(id: "u2") { User(id: "u2") {
id id
isBlacklisted isMuted
followedByCurrentUser followedByCurrentUser
} }
} }
@ -168,18 +168,18 @@ describe('blacklistUserContent', () => {
const { query } = createTestClient(server) const { query } = createTestClient(server)
await expect(query({ query: queryUser })).resolves.toEqual( await expect(query({ query: queryUser })).resolves.toEqual(
expect.objectContaining({ expect.objectContaining({
data: { User: [{ id: 'u2', isBlacklisted: false, followedByCurrentUser: true }] }, data: { User: [{ id: 'u2', isMuted: false, followedByCurrentUser: true }] },
}), }),
) )
await blacklistAction({ id: 'u2' }) await muteAction({ id: 'u2' })
await expect(query({ query: queryUser })).resolves.toEqual( await expect(query({ query: queryUser })).resolves.toEqual(
expect.objectContaining({ expect.objectContaining({
data: { User: [{ id: 'u2', isBlacklisted: true, followedByCurrentUser: false }] }, data: { User: [{ id: 'u2', isMuted: true, followedByCurrentUser: false }] },
}), }),
) )
}) })
describe('given both the current user and the to-be-blacklisted user write a post', () => { describe('given both the current user and the to-be-muted user write a post', () => {
let postQuery let postQuery
beforeEach(async () => { beforeEach(async () => {
@ -189,11 +189,11 @@ describe('blacklistUserContent', () => {
}) })
const post2 = await neode.create('Post', { const post2 = await neode.create('Post', {
id: 'p23', id: 'p23',
title: 'A post written by the blacklisted user', title: 'A post written by the muted user',
}) })
await Promise.all([ await Promise.all([
post1.relateTo(currentUser, 'author'), post1.relateTo(currentUser, 'author'),
post2.relateTo(blacklistedUser, 'author'), post2.relateTo(mutedUser, 'author'),
]) ])
postQuery = gql` postQuery = gql`
query { query {
@ -225,9 +225,9 @@ describe('blacklistUserContent', () => {
}, },
{ {
id: 'p23', id: 'p23',
title: 'A post written by the blacklisted user', title: 'A post written by the muted user',
author: { author: {
name: 'Blacklisted User', name: 'Muted User',
id: 'u2', id: 'u2',
}, },
}, },
@ -240,12 +240,12 @@ describe('blacklistUserContent', () => {
describe('from the perspective of the current user', () => { describe('from the perspective of the current user', () => {
it('both posts are in the newsfeed', bothPostsAreInTheNewsfeed) it('both posts are in the newsfeed', bothPostsAreInTheNewsfeed)
describe('but if the current user blacklists the other user', () => { describe('but if the current user mutes the other user', () => {
beforeEach(async () => { beforeEach(async () => {
await currentUser.relateTo(blacklistedUser, 'blacklisted') await currentUser.relateTo(mutedUser, 'muted')
}) })
it("the blacklisted 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) const { query } = createTestClient(server)
await expect(query({ query: postQuery })).resolves.toEqual( await expect(query({ query: postQuery })).resolves.toEqual(
expect.objectContaining({ expect.objectContaining({
@ -264,18 +264,18 @@ describe('blacklistUserContent', () => {
}) })
}) })
describe('from the perspective of the blacklisted user', () => { describe('from the perspective of the muted user', () => {
beforeEach(async () => { beforeEach(async () => {
authenticatedUser = await blacklistedUser.toJson() authenticatedUser = await mutedUser.toJson()
}) })
it('both posts are in the newsfeed', bothPostsAreInTheNewsfeed) it('both posts are in the newsfeed', bothPostsAreInTheNewsfeed)
describe('but if the current user blacklists the other user', () => { describe('but if the current user mutes the other user', () => {
beforeEach(async () => { beforeEach(async () => {
await currentUser.relateTo(blacklistedUser, 'blacklisted') await currentUser.relateTo(mutedUser, 'muted')
}) })
it("the current user's post will show up in the newsfeed of the blacklisted user", async () => { it("the current user's post will show up in the newsfeed of the muted user", async () => {
const { query } = createTestClient(server) const { query } = createTestClient(server)
await expect(query({ query: postQuery })).resolves.toEqual( await expect(query({ query: postQuery })).resolves.toEqual(
expect.objectContaining({ expect.objectContaining({
@ -283,8 +283,8 @@ describe('blacklistUserContent', () => {
Post: expect.arrayContaining([ Post: expect.arrayContaining([
{ {
id: 'p23', id: 'p23',
title: 'A post written by the blacklisted user', title: 'A post written by the muted user',
author: { name: 'Blacklisted User', id: 'u2' }, author: { name: 'Muted User', id: 'u2' },
}, },
{ {
id: 'p12', id: 'p12',
@ -303,28 +303,28 @@ describe('blacklistUserContent', () => {
}) })
}) })
describe('whitelistUserContent', () => { describe('unmuteUser', () => {
let whitelistAction let unmuteAction
beforeEach(() => { beforeEach(() => {
currentUser = undefined currentUser = undefined
whitelistAction = variables => { unmuteAction = variables => {
const { mutate } = createTestClient(server) const { mutate } = createTestClient(server)
const whitelistUserContentMutation = gql` const unmuteUserMutation = gql`
mutation($id: ID!) { mutation($id: ID!) {
whitelistUserContent(id: $id) { unmuteUser(id: $id) {
id id
name name
isBlacklisted isMuted
} }
} }
` `
return mutate({ mutation: whitelistUserContentMutation, variables }) return mutate({ mutation: unmuteUserMutation, variables })
} }
}) })
it('throws permission error', async () => { it('throws permission error', async () => {
const result = await whitelistAction({ id: 'u2' }) const result = await unmuteAction({ id: 'u2' })
expect(result.errors[0]).toHaveProperty('message', 'Not Authorised!') expect(result.errors[0]).toHaveProperty('message', 'Not Authorised!')
}) })
@ -337,67 +337,67 @@ describe('whitelistUserContent', () => {
authenticatedUser = await currentUser.toJson() authenticatedUser = await currentUser.toJson()
}) })
describe('whitelist yourself', () => { describe('unmute yourself', () => {
it('returns null', async () => { it('returns null', async () => {
await expect(whitelistAction({ id: 'u1' })).resolves.toEqual( await expect(unmuteAction({ id: 'u1' })).resolves.toEqual(
expect.objectContaining({ data: { whitelistUserContent: null } }), expect.objectContaining({ data: { unmuteUser: null } }),
) )
}) })
}) })
describe('whitelist not-existing user', () => { describe('unmute not-existing user', () => {
it('returns null', async () => { it('returns null', async () => {
await expect(whitelistAction({ id: 'lksjdflksfdj' })).resolves.toEqual( await expect(unmuteAction({ id: 'lksjdflksfdj' })).resolves.toEqual(
expect.objectContaining({ data: { whitelistUserContent: null } }), expect.objectContaining({ data: { unmuteUser: null } }),
) )
}) })
}) })
describe('given another user', () => { describe('given another user', () => {
beforeEach(async () => { beforeEach(async () => {
blacklistedUser = await neode.create('User', { mutedUser = await neode.create('User', {
name: 'Blacklisted User', name: 'Muted User',
id: 'u2', id: 'u2',
}) })
}) })
describe('whitelisting a not yet blacklisted user', () => { describe('unmuting a not yet muted user', () => {
it('does not hurt', async () => { it('does not hurt', async () => {
await expect(whitelistAction({ id: 'u2' })).resolves.toEqual( await expect(unmuteAction({ id: 'u2' })).resolves.toEqual(
expect.objectContaining({ expect.objectContaining({
data: { data: {
whitelistUserContent: { id: 'u2', name: 'Blacklisted User', isBlacklisted: false }, unmuteUser: { id: 'u2', name: 'Muted User', isMuted: false },
}, },
}), }),
) )
}) })
}) })
describe('given a blacklisted user', () => { describe('given a muted user', () => {
beforeEach(async () => { beforeEach(async () => {
await currentUser.relateTo(blacklistedUser, 'blacklisted') await currentUser.relateTo(mutedUser, 'muted')
}) })
it('whitelists a user', async () => { it('unmutes a user', async () => {
await expect(whitelistAction({ id: 'u2' })).resolves.toEqual( await expect(unmuteAction({ id: 'u2' })).resolves.toEqual(
expect.objectContaining({ expect.objectContaining({
data: { data: {
whitelistUserContent: { id: 'u2', name: 'Blacklisted User', isBlacklisted: false }, unmuteUser: { id: 'u2', name: 'Muted User', isMuted: false },
}, },
}), }),
) )
}) })
describe('whitelisting twice', () => { describe('unmuting twice', () => {
it('has no effect', async () => { it('has no effect', async () => {
await whitelistAction({ id: 'u2' }) await unmuteAction({ id: 'u2' })
await expect(whitelistAction({ id: 'u2' })).resolves.toEqual( await expect(unmuteAction({ id: 'u2' })).resolves.toEqual(
expect.objectContaining({ expect.objectContaining({
data: { data: {
whitelistUserContent: { unmuteUser: {
id: 'u2', id: 'u2',
name: 'Blacklisted User', name: 'Muted User',
isBlacklisted: false, isMuted: false,
}, },
}, },
}), }),

View File

@ -75,9 +75,9 @@ type User {
""" """
) )
isBlacklisted: Boolean! @cypher( isMuted: Boolean! @cypher(
statement: """ statement: """
MATCH (this)<-[: BLACKLISTED]-(u: User { id: $cypherParams.currentUserId}) MATCH (this)<-[: MUTED]-(u: User { id: $cypherParams.currentUserId})
RETURN COUNT(u) >= 1 RETURN COUNT(u) >= 1
""" """
) )
@ -167,7 +167,7 @@ type Query {
filter: _UserFilter filter: _UserFilter
): [User] ): [User]
blacklistedUsers: [User] mutedUsers: [User]
currentUser: User currentUser: User
} }
@ -192,8 +192,8 @@ type Mutation {
DeleteUser(id: ID!, resource: [Deletable]): User DeleteUser(id: ID!, resource: [Deletable]): User
blacklistUserContent(id: ID!): User muteUser(id: ID!): User
whitelistUserContent(id: ID!): User unmuteUser(id: ID!): User
block(id: ID!): User block(id: ID!): User
unblock(id: ID!): User unblock(id: ID!): User
} }

View File

@ -226,9 +226,9 @@ const languages = ['de', 'en', 'es', 'fr', 'it', 'pt', 'pl']
dewey.relateTo(huey, 'following'), dewey.relateTo(huey, 'following'),
louie.relateTo(jennyRostock, 'following'), louie.relateTo(jennyRostock, 'following'),
huey.relateTo(dagobert, 'blacklisted'), huey.relateTo(dagobert, 'muted'),
dewey.relateTo(dagobert, 'blacklisted'), dewey.relateTo(dagobert, 'muted'),
louie.relateTo(dagobert, 'blacklisted'), louie.relateTo(dagobert, 'muted'),
dagobert.relateTo(huey, 'blocked'), dagobert.relateTo(huey, 'blocked'),
dagobert.relateTo(dewey, 'blocked'), dagobert.relateTo(dewey, 'blocked'),

View File

@ -7,7 +7,7 @@ import { gql } from '../../../backend/src/helpers/jest'
let lastReportTitle let lastReportTitle
let davidIrvingPostTitle = 'The Truth about the Holocaust' let davidIrvingPostTitle = 'The Truth about the Holocaust'
let davidIrvingPostSlug = 'the-truth-about-the-holocaust' let davidIrvingPostSlug = 'the-truth-about-the-holocaust'
let annoyingUserWhoBlacklistedModeratorTitle = 'Fake news' let annoyingUserWhoMutedModeratorTitle = 'Fake news'
const savePostTitle = $post => { const savePostTitle = $post => {
return $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 blacklisted me', () => { Then('I see all the reported posts including from the user who muted me', () => {
cy.get('table tbody').within(() => { cy.get('table tbody').within(() => {
cy.contains('tr', annoyingUserWhoBlacklistedModeratorTitle) cy.contains('tr', annoyingUserWhoMutedModeratorTitle)
}) })
}) })
@ -159,9 +159,9 @@ Then('each list item links to the post page', () => {
}) })
Then('I can visit the post page', () => { Then('I can visit the post page', () => {
cy.contains(annoyingUserWhoBlacklistedModeratorTitle).click() cy.contains(annoyingUserWhoMutedModeratorTitle).click()
cy.location('pathname').should('contain', '/post') cy.location('pathname').should('contain', '/post')
.get('h3').should('contain', annoyingUserWhoBlacklistedModeratorTitle) .get('h3').should('contain', annoyingUserWhoMutedModeratorTitle)
}) })
When("they have a post someone has reported", () => { When("they have a post someone has reported", () => {

View File

@ -39,7 +39,7 @@ Given("I am logged in", () => {
cy.login(loginCredentials); cy.login(loginCredentials);
}); });
Given("I am logged in as the blacklisted user", () => { Given("I am logged in as the muted user", () => {
cy.login({ email: annoyingParams.email, password: '1234' }); cy.login({ email: annoyingParams.email, password: '1234' });
}); });
@ -424,17 +424,17 @@ Given("there is an annoying user called {string}", name => {
}); });
}); });
Given("there is an annoying user who has blacklisted me", () => { Given("there is an annoying user who has muted me", () => {
cy.neode() cy.neode()
.first("User", { .first("User", {
role: 'moderator' role: 'moderator'
}) })
.then(blacklisted => { .then(mutedUser => {
cy.neode() cy.neode()
.first("User", { .first("User", {
id: 'annoying-user' id: 'annoying-user'
}) })
.relateTo(blacklisted, "blacklisted"); .relateTo(mutedUser, "muted");
}); });
}); });
@ -518,17 +518,17 @@ Given("I wrote a post {string}", title => {
}); });
}); });
When("I blacklist the user {string}", name => { When("I mute the user {string}", name => {
cy.neode() cy.neode()
.first("User", { .first("User", {
name name
}) })
.then(blacklistedUser => { .then(mutedUser => {
cy.neode() cy.neode()
.first("User", { .first("User", {
name: narratorParams.name name: narratorParams.name
}) })
.relateTo(blacklistedUser, "blacklisted"); .relateTo(mutedUser, "muted");
}); });
}); });

View File

@ -11,7 +11,7 @@ Feature: Report and Moderate
Given we have the following user accounts: Given we have the following user accounts:
| id | name | | id | name |
| u67 | David Irving | | u67 | David Irving |
| annoying-user | I'm gonna blacklist 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: Given we have the following posts in our database:
| authorId | id | title | content | | authorId | id | title | content |
@ -58,16 +58,16 @@ Feature: Report and Moderate
Then I see all the reported posts including the one from above Then I see all the reported posts including the one from above
And each list item links to the post page And each list item links to the post page
Scenario: Review reported posts of a user who's blacklisted a moderator Scenario: Review reported posts of a user who's muted a moderator
Given somebody reported the following posts: Given somebody reported the following posts:
| submitterEmail | resourceId | reasonCategory | reasonDescription | | submitterEmail | resourceId | reasonCategory | reasonDescription |
| p2.submitter@example.org | p2 | other | Offensive content | | p2.submitter@example.org | p2 | other | Offensive content |
And my user account has the role "moderator" And my user account has the role "moderator"
And there is an annoying user who has blacklisted me And there is an annoying user who has muted me
And I am logged in And I am logged in
When I click on the avatar menu in the top right corner When I click on the avatar menu in the top right corner
And I click on "Moderation" And I click on "Moderation"
Then I see all the reported posts including from the user who blacklisted me Then I see all the reported posts including from the user who muted me
And I can visit the post page And I can visit the post page
Scenario: Normal user can't see the moderation page Scenario: Normal user can't see the moderation page

View File

@ -1,4 +1,4 @@
Feature: Blacklist a User Feature: Mute a User
As a user As a user
I'd like to have a button to block another 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 To prevent him from seeing and interacting with my contributions and also to avoid seeing his/her posts
@ -7,10 +7,10 @@ Feature: Blacklist a User
Given I have a user account Given I have a user account
And there is an annoying user called "Spammy Spammer" And there is an annoying user called "Spammy Spammer"
Scenario Outline: Blacklisted users cannot see each others posts Scenario Outline: Muted users cannot see each others posts
Given "Spammy Spammer" wrote a post "Spam Spam Spam" Given "Spammy Spammer" wrote a post "Spam Spam Spam"
And I wrote a post "I hate spammers" And I wrote a post "I hate spammers"
And I I blacklist the user "Spammy Spammer" And I mute the user "Spammy Spammer"
When I log in with: When I log in with:
| Email | Password | | Email | Password |
| <email> | <password> | | <email> | <password> |

View File

@ -1,6 +1,6 @@
Feature: Blacklist a User Feature: Mute a User
As a user As a user
I'd like to have a button to blacklist 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 To prevent him from seeing and interacting with my contributions and also to avoid seeing his/her posts
Background: Background:
@ -8,45 +8,45 @@ Feature: Blacklist a User
And there is an annoying user called "Spammy Spammer" And there is an annoying user called "Spammy Spammer"
And I am logged in And I am logged in
Scenario: Blacklist a user Scenario: Mute a user
Given I am on the profile page of the annoying user Given I am on the profile page of the annoying user
When I click on "Blacklist user" from the content menu in the user info box When I click on "Mute user" from the content menu in the user info box
And I navigate to my "Blacklisted users" settings page And I navigate to my "Muted users" settings page
Then I can see the following table: Then I can see the following table:
| Avatar | Name | | Avatar | Name |
| | Spammy Spammer | | | Spammy Spammer |
Scenario: Blacklist a previously followed user Scenario: Mute a previously followed user
Given I follow the user "Spammy Spammer" Given I follow the user "Spammy Spammer"
And "Spammy Spammer" wrote a post "Spam Spam Spam" And "Spammy Spammer" wrote a post "Spam Spam Spam"
When I visit the profile page of the annoying user When I visit the profile page of the annoying user
And I click on "Blacklist 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 Then the list of posts of this user is empty
And nobody is following the user profile anymore And nobody is following the user profile anymore
Scenario: Posts of blacklisted 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: Given we have the following posts in our database:
| id | title | content | | id | title | content |
| im-not-blacklisted | Post that should be seen | cause I'm not blacklisted | | im-not-muted | Post that should be seen | cause I'm not muted |
Given "Spammy Spammer" wrote a post "Spam Spam Spam" Given "Spammy Spammer" wrote a post "Spam Spam Spam"
When I search for "Spam" When I search for "Spam"
Then I should see the following posts in the select dropdown: Then I should see the following posts in the select dropdown:
| title | | title |
| Spam Spam Spam | | Spam Spam Spam |
When I blacklist the user "Spammy Spammer" When I mute the user "Spammy Spammer"
And I refresh the page And I refresh the page
And I search for "Spam" And I search for "Spam"
Then the search has no results Then the search has no results
But I search for "not blacklisted" But I search for "not muted"
Then I should see the following posts in the select dropdown: Then I should see the following posts in the select dropdown:
| title | | title |
| Post that should be seen | | Post that should be seen |
Scenario: Blacklisted users can still see my posts Scenario: Muted users can still see my posts
Given I previously created a post Given I previously created a post
And I blacklist the user "Spammy Spammer" And I mute the user "Spammy Spammer"
Given I log out Given I log out
And I am logged in as the blacklisted user And I am logged in as the muted user
When I search for "previously created" When I search for "previously created"
Then I should see the following posts in the select dropdown: Then I should see the following posts in the select dropdown:
| title | | title |

View File

@ -14,7 +14,7 @@
"cypress:backend": "cd backend && yarn run dev", "cypress:backend": "cd backend && yarn run dev",
"cypress:webapp": "cd webapp && yarn run dev", "cypress:webapp": "cd webapp && yarn run dev",
"cypress:setup": "run-p cypress:backend cypress:webapp", "cypress:setup": "run-p cypress:backend cypress:webapp",
"cypress:run": "cross-env cypress run --browser chromium", "cypress:run": "cross-env cypress run",
"cypress:open": "cross-env cypress open --browser chromium", "cypress:open": "cross-env cypress open --browser chromium",
"cucumber:setup": "cd backend && yarn run dev", "cucumber:setup": "cd backend && yarn run dev",
"cucumber": "wait-on tcp:4000 && cucumber-js --require-module @babel/register --exit", "cucumber": "wait-on tcp:4000 && cucumber-js --require-module @babel/register --exit",

View File

@ -407,49 +407,49 @@ describe('ContentMenu.vue', () => {
).toBe('/settings') ).toBe('/settings')
}) })
it('can blacklist other users', () => { it('can mute other users', () => {
const wrapper = openContentMenu({ const wrapper = openContentMenu({
isOwner: false, isOwner: false,
resourceType: 'user', resourceType: 'user',
resource: { resource: {
id: 'd23a4265-f5f7-4e17-9f86-85f714b4b9f8', id: 'd23a4265-f5f7-4e17-9f86-85f714b4b9f8',
isBlacklisted: false, isMuted: false,
}, },
}) })
wrapper wrapper
.findAll('.ds-menu-item') .findAll('.ds-menu-item')
.filter(item => item.text() === 'settings.blacklisted-users.blacklist') .filter(item => item.text() === 'settings.muted-users.mute')
.at(0) .at(0)
.trigger('click') .trigger('click')
expect(wrapper.emitted('blacklist')).toEqual([ expect(wrapper.emitted('mute')).toEqual([
[ [
{ {
id: 'd23a4265-f5f7-4e17-9f86-85f714b4b9f8', id: 'd23a4265-f5f7-4e17-9f86-85f714b4b9f8',
isBlacklisted: false, isMuted: false,
}, },
], ],
]) ])
}) })
it('can whitelist blacklisted users', () => { it('can unmute muted users', () => {
const wrapper = openContentMenu({ const wrapper = openContentMenu({
isOwner: false, isOwner: false,
resourceType: 'user', resourceType: 'user',
resource: { resource: {
id: 'd23a4265-f5f7-4e17-9f86-85f714b4b9f8', id: 'd23a4265-f5f7-4e17-9f86-85f714b4b9f8',
isBlacklisted: true, isMuted: true,
}, },
}) })
wrapper wrapper
.findAll('.ds-menu-item') .findAll('.ds-menu-item')
.filter(item => item.text() === 'settings.blacklisted-users.whitelist') .filter(item => item.text() === 'settings.muted-users.unmute')
.at(0) .at(0)
.trigger('click') .trigger('click')
expect(wrapper.emitted('whitelist')).toEqual([ expect(wrapper.emitted('unmute')).toEqual([
[ [
{ {
id: 'd23a4265-f5f7-4e17-9f86-85f714b4b9f8', id: 'd23a4265-f5f7-4e17-9f86-85f714b4b9f8',
isBlacklisted: true, isMuted: true,
}, },
], ],
]) ])

View File

@ -150,19 +150,19 @@ export default {
icon: 'edit', icon: 'edit',
}) })
} else { } else {
if (this.resource.isBlacklisted) { if (this.resource.isMuted) {
routes.push({ routes.push({
label: this.$t(`settings.blacklisted-users.whitelist`), label: this.$t(`settings.muted-users.unmute`),
callback: () => { callback: () => {
this.$emit('whitelist', this.resource) this.$emit('unmute', this.resource)
}, },
icon: 'user-plus', icon: 'user-plus',
}) })
} else { } else {
routes.push({ routes.push({
label: this.$t(`settings.blacklisted-users.blacklist`), label: this.$t(`settings.muted-users.mute`),
callback: () => { callback: () => {
this.$emit('blacklist', this.resource) this.$emit('mute', this.resource)
}, },
icon: 'user-times', icon: 'user-times',
}) })

View File

@ -48,7 +48,7 @@ export const user = {
], ],
followedByCount: 0, followedByCount: 0,
followedByCurrentUser: false, followedByCurrentUser: false,
isBlacklisted: false, isMuted: false,
followedBy: [], followedBy: [],
socialMedia: [], socialMedia: [],
} }

View File

@ -23,7 +23,7 @@ export default i18n => {
locationName locationName
createdAt createdAt
followedByCurrentUser followedByCurrentUser
isBlacklisted isMuted
following(first: 7) { following(first: 7) {
...user ...user
...userCounts ...userCounts

View File

@ -1,9 +1,9 @@
import gql from 'graphql-tag' import gql from 'graphql-tag'
export const blacklistedUsers = () => { export const mutedUsers = () => {
return gql` return gql`
{ {
blacklistedUsers { mutedUsers {
id id
name name
slug slug
@ -16,26 +16,26 @@ export const blacklistedUsers = () => {
` `
} }
export const blacklistUserContent = () => { export const muteUser = () => {
return gql` return gql`
mutation($id: ID!) { mutation($id: ID!) {
blacklistUserContent(id: $id) { muteUser(id: $id) {
id id
name name
isBlacklisted isMuted
followedByCurrentUser followedByCurrentUser
} }
} }
` `
} }
export const whitelistUserContent = () => { export const unmuteUser = () => {
return gql` return gql`
mutation($id: ID!) { mutation($id: ID!) {
whitelistUserContent(id: $id) { unmuteUser(id: $id) {
id id
name name
isBlacklisted isMuted
followedByCurrentUser followedByCurrentUser
} }
} }

View File

@ -145,7 +145,7 @@
"successAdd": "Social-Media hinzugefügt. Profil aktualisiert!", "successAdd": "Social-Media hinzugefügt. Profil aktualisiert!",
"successDelete": "Social-Media gelöscht. Profil aktualisiert!" "successDelete": "Social-Media gelöscht. Profil aktualisiert!"
}, },
"blacklisted-users": { "muted-users": {
"name": "Blockierte Benutzer", "name": "Blockierte Benutzer",
"explanation": { "explanation": {
"intro": "Wenn ein anderer Benutzer von dir blockiert wurde, dann passiert folgendes:", "intro": "Wenn ein anderer Benutzer von dir blockiert wurde, dann passiert folgendes:",
@ -158,12 +158,12 @@
"columns": { "columns": {
"name": "Name", "name": "Name",
"slug": "Alias", "slug": "Alias",
"whitelist": "Entsperren" "unmute": "Entsperren"
}, },
"empty": "Bislang hast du niemanden blockiert.", "empty": "Bislang hast du niemanden blockiert.",
"how-to": "Du kannst andere Benutzer auf deren Profilseite über das Inhaltsmenü blockieren.", "how-to": "Du kannst andere Benutzer auf deren Profilseite über das Inhaltsmenü blockieren.",
"blacklist": "Nutzer blockieren", "mute": "Nutzer blockieren",
"whitelist": "Nutzer entblocken", "unmute": "Nutzer entblocken",
"unblocked": "{name} ist wieder entsperrt" "unblocked": "{name} ist wieder entsperrt"
}, },
"privacy": { "privacy": {

View File

@ -309,26 +309,26 @@
"successAdd": "Added social media. Updated user profile!", "successAdd": "Added social media. Updated user profile!",
"successDelete": "Deleted social media. Updated user profile!" "successDelete": "Deleted social media. Updated user profile!"
}, },
"blacklisted-users": { "muted-users": {
"name": "Blacklisted users", "name": "Muted users",
"explanation": { "explanation": {
"intro": "If another user has been blacklisted by you, this is what happens:", "intro": "If another user has been muted by you, this is what happens:",
"your-perspective": "The blacklisted person's posts will no longer appear in your news feed.", "your-perspective": "The muted person's posts will no longer appear in your news feed.",
"their-perspective": "However: The blacklisted person will still be able to see your posts in their news feed.", "their-perspective": "However: The muted person will still be able to see your posts in their news feed.",
"search": "Posts of blacklisted people disappear from your search results.", "search": "Posts of muted people disappear from your search results.",
"notifications": "Blacklisted users will still receive notifications if they are mentioned in your posts.", "notifications": "Muted users will still receive notifications if they are mentioned in your posts.",
"closing": "This should be sufficient for filtering out content from blacklisted users." "closing": "This should be sufficient for filtering out content from muted users."
}, },
"columns": { "columns": {
"name": "Name", "name": "Name",
"slug": "Slug", "slug": "Slug",
"whitelist": "Whitelist" "unmute": "Unmute"
}, },
"empty": "So far, you have not blacklisted anybody.", "empty": "So far, you have not muted anybody.",
"how-to": "You can blacklist other users on their profile page via the content menu.", "how-to": "You can mute other users on their profile page via the content menu.",
"blacklist": "Blacklist user", "mute": "Mute user",
"whitelist": "Whitelist user", "unmute": "Unmute user",
"whitelisted": "{name} is whitelisted again" "unmuted": "{name} is unmuted again"
} }
}, },
"admin": { "admin": {

View File

@ -145,7 +145,7 @@
"successAdd": "Social-Media agregó. Perfil actualizado!", "successAdd": "Social-Media agregó. Perfil actualizado!",
"successDelete": "Social-Media borrado. Perfil actualizado!" "successDelete": "Social-Media borrado. Perfil actualizado!"
}, },
"blacklisted-users": { "muted-users": {
"name": "Usuarios bloqueados", "name": "Usuarios bloqueados",
"explanation": { "explanation": {
"intro": "Si otro usuario ha sido bloqueado por usted, esto es lo que sucede:", "intro": "Si otro usuario ha sido bloqueado por usted, esto es lo que sucede:",
@ -158,12 +158,12 @@
"columns": { "columns": {
"name": "Nombre", "name": "Nombre",
"slug": "Alias", "slug": "Alias",
"whitelist": "Desbloquear" "unmute": "Desbloquear"
}, },
"empty": "Hasta ahora, no ha bloqueado a nadie.", "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.", "how-to": "Puede bloquear a otros usuarios en la página de perfil de aquellos a través del menú de contenido.",
"blacklist": "Bloquear usuario", "mute": "Bloquear usuario",
"whitelist": "Desbloquear usuario", "unmute": "Desbloquear usuario",
"unblocked": "{name} está desbloqueado nuevamente" "unblocked": "{name} está desbloqueado nuevamente"
}, },
"privacy": { "privacy": {

View File

@ -145,7 +145,7 @@
"successAdd": "Les médias sociaux ont été ajoutés. Profil mis à jour !", "successAdd": "Les médias sociaux ont été ajoutés. Profil mis à jour !",
"successDelete": "Médias sociaux supprimé. Profil mis à jour !" "successDelete": "Médias sociaux supprimé. Profil mis à jour !"
}, },
"blacklisted-users": { "muted-users": {
"name": "Utilisateurs bloqués", "name": "Utilisateurs bloqués",
"explanation": { "explanation": {
"intro": "Si vous avez bloqué un autre utilisateur, voici ce qui se passe:", "intro": "Si vous avez bloqué un autre utilisateur, voici ce qui se passe:",
@ -158,13 +158,13 @@
"columns": { "columns": {
"name": "Nom", "name": "Nom",
"slug": "Slug", "slug": "Slug",
"whitelist": "" "unmute": ""
}, },
"empty": "Jusqu'à présent, vous n'avez bloqué personne.", "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.", "how-to": "Vous pouvez bloquer d'autres utilisateurs sur leur page de profil via le menu de contenu.",
"blacklist": "Bloquer l'utilisateur", "mute": "Bloquer l'utilisateur",
"whitelist": "Débloquer l'utilisateur", "unmute": "Débloquer l'utilisateur",
"unblocked": "{name} est à nouveau débloqué" "unmuted": "{name} est à nouveau débloqué"
}, },
"privacy": { "privacy": {
"name": "", "name": "",

View File

@ -145,7 +145,7 @@
"successAdd": "Social media aggiunti. \nProfilo utente aggiornato ", "successAdd": "Social media aggiunti. \nProfilo utente aggiornato ",
"successDelete": "Social media cancellati. Profilo utente aggiornato!" "successDelete": "Social media cancellati. Profilo utente aggiornato!"
}, },
"blacklisted-users": { "muted-users": {
"name": "", "name": "",
"explanation": { "explanation": {
"intro": "", "intro": "",
@ -158,13 +158,13 @@
"columns": { "columns": {
"name": "", "name": "",
"slug": "", "slug": "",
"whitelist": "" "unmute": ""
}, },
"empty": "", "empty": "",
"how-to": "", "how-to": "",
"blacklist": "", "mute": "",
"whitelist": "", "unmute": "",
"unblocked": "" "unmuted": ""
}, },
"privacy": { "privacy": {
"name": "", "name": "",

View File

@ -145,7 +145,7 @@
"successAdd": "Mídias sociais adicionadas. Perfil de usuário atualizado!", "successAdd": "Mídias sociais adicionadas. Perfil de usuário atualizado!",
"successDelete": "Mídias sociais removidas. Perfil de usuário atualizado!" "successDelete": "Mídias sociais removidas. Perfil de usuário atualizado!"
}, },
"blacklisted-users": { "muted-users": {
"name": "Usuários bloqueados", "name": "Usuários bloqueados",
"explanation": { "explanation": {
"intro": "Se outro usuário foi bloqueado por você, isto é o que acontece:", "intro": "Se outro usuário foi bloqueado por você, isto é o que acontece:",
@ -158,13 +158,13 @@
"columns": { "columns": {
"name": "Nome", "name": "Nome",
"slug": "Slug", "slug": "Slug",
"whitelist": "Desbloquear" "unmute": "Desbloquear"
}, },
"empty": "Até agora, você não bloqueou ninguém.", "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.", "how-to": "Você pode bloquear outros usuários em suas páginas de perfil através do menu de conteúdo.",
"blacklist": "Bloquear usuário", "mute": "Bloquear usuário",
"whitelist": "Desbloquear usuário", "unmute": "Desbloquear usuário",
"unblocked": "{name} está desbloqueado novamente" "unmuted": "{name} está desbloqueado novamente"
}, },
"privacy": { "privacy": {
"name": "Privacidade", "name": "Privacidade",

View File

@ -596,12 +596,12 @@
"placeholder": "Поиск" "placeholder": "Поиск"
}, },
"settings": { "settings": {
"blacklisted-users": { "muted-users": {
"blacklist": "Блокировать", "mute": "Блокировать",
"columns": { "columns": {
"name": "Имя", "name": "Имя",
"slug": "Псевдоним", "slug": "Псевдоним",
"whitelist": "Разблокировать" "unmute": "Разблокировать"
}, },
"empty": "Вы пока никого не блокировали.", "empty": "Вы пока никого не блокировали.",
"explanation": { "explanation": {
@ -614,8 +614,8 @@
}, },
"how-to": "Вы можете блокировать других пользователей на странице их профиля с помощью меню профиля.", "how-to": "Вы можете блокировать других пользователей на странице их профиля с помощью меню профиля.",
"name": "Заблокированные пользователи", "name": "Заблокированные пользователи",
"whitelist": "Разблокировать пользователей", "unmute": "Разблокировать пользователей",
"unblocked": "{name} - снова разблокирован" "unmuted": "{name} - снова разблокирован"
}, },
"data": { "data": {
"labelBio": "О себе", "labelBio": "О себе",

View File

@ -22,8 +22,8 @@
:resource="user" :resource="user"
:is-owner="myProfile" :is-owner="myProfile"
class="user-content-menu" class="user-content-menu"
@blacklist="blacklistUserContent" @mute="muteUser"
@whitelist="whitelistUserContent" @unmute="unmuteUser"
/> />
</client-only> </client-only>
<ds-space margin="small"> <ds-space margin="small">
@ -67,14 +67,14 @@
<ds-space margin="small"> <ds-space margin="small">
<template v-if="!myProfile"> <template v-if="!myProfile">
<hc-follow-button <hc-follow-button
v-if="!user.isBlacklisted" v-if="!user.isMuted"
:follow-id="user.id" :follow-id="user.id"
:is-followed="user.followedByCurrentUser" :is-followed="user.followedByCurrentUser"
@optimistic="optimisticFollow" @optimistic="optimisticFollow"
@update="updateFollow" @update="updateFollow"
/> />
<ds-button v-else fullwidth @click="whitelistUserContent(user)"> <ds-button v-else fullwidth @click="unmuteUser(user)">
{{ $t('settings.blacklisted-users.whitelist') }} {{ $t('settings.muted-users.unmute') }}
</ds-button> </ds-button>
</template> </template>
</ds-space> </ds-space>
@ -285,7 +285,7 @@ import MasonryGrid from '~/components/MasonryGrid/MasonryGrid.vue'
import MasonryGridItem from '~/components/MasonryGrid/MasonryGridItem.vue' import MasonryGridItem from '~/components/MasonryGrid/MasonryGridItem.vue'
import { profilePagePosts } from '~/graphql/PostQuery' import { profilePagePosts } from '~/graphql/PostQuery'
import UserQuery from '~/graphql/User' import UserQuery from '~/graphql/User'
import { blacklistUserContent, whitelistUserContent } from '~/graphql/settings/BlacklistedUsers' import { muteUser, unmuteUser } from '~/graphql/settings/MutedUsers'
import PostMutations from '~/graphql/PostMutations' import PostMutations from '~/graphql/PostMutations'
import UpdateQuery from '~/components/utils/UpdateQuery' import UpdateQuery from '~/components/utils/UpdateQuery'
@ -398,9 +398,9 @@ export default {
this.posts = [] this.posts = []
this.hasMore = true this.hasMore = true
}, },
async blacklistUserContent(user) { async muteUser(user) {
try { try {
await this.$apollo.mutate({ mutation: blacklistUserContent(), variables: { id: user.id } }) await this.$apollo.mutate({ mutation: muteUser(), variables: { id: user.id } })
} catch (error) { } catch (error) {
this.$toast.error(error.message) this.$toast.error(error.message)
} finally { } finally {
@ -409,9 +409,9 @@ export default {
this.$apollo.queries.profilePagePosts.refetch() this.$apollo.queries.profilePagePosts.refetch()
} }
}, },
async whitelistUserContent(user) { async unmuteUser(user) {
try { try {
this.$apollo.mutate({ mutation: whitelistUserContent(), variables: { id: user.id } }) this.$apollo.mutate({ mutation: unmuteUser(), variables: { id: user.id } })
} catch (error) { } catch (error) {
this.$toast.error(error.message) this.$toast.error(error.message)
} finally { } finally {

View File

@ -40,8 +40,8 @@ export default {
path: `/settings/my-social-media`, path: `/settings/my-social-media`,
}, },
{ {
name: this.$t('settings.blacklisted-users.name'), name: this.$t('settings.muted-users.name'),
path: `/settings/blacklisted-users`, path: `/settings/muted-users`,
}, },
{ {
name: this.$t('settings.embeds.name'), name: this.$t('settings.embeds.name'),

View File

@ -1,8 +1,8 @@
import { config, mount, createLocalVue } from '@vue/test-utils' import { config, mount, createLocalVue } from '@vue/test-utils'
import BlacklistedUsers from './blacklisted-users.vue' import MutedUsers from './muted-users.vue'
import Styleguide from '@human-connection/styleguide' import Styleguide from '@human-connection/styleguide'
import Filters from '~/plugins/vue-filters' import Filters from '~/plugins/vue-filters'
import { whitelistUserContent } from '~/graphql/settings/BlacklistedUsers' import { unmuteUser } from '~/graphql/settings/MutedUsers'
const localVue = createLocalVue() const localVue = createLocalVue()
@ -11,7 +11,7 @@ localVue.use(Filters)
config.stubs['nuxt-link'] = '<span><slot /></span>' config.stubs['nuxt-link'] = '<span><slot /></span>'
describe('blacklisted-users.vue', () => { describe('muted-users.vue', () => {
let wrapper let wrapper
let mocks let mocks
@ -21,7 +21,7 @@ describe('blacklisted-users.vue', () => {
$apollo: { $apollo: {
mutate: jest.fn(), mutate: jest.fn(),
queries: { queries: {
blacklistedUsers: { mutedUsers: {
refetch: jest.fn(), refetch: jest.fn(),
}, },
}, },
@ -35,7 +35,7 @@ describe('blacklisted-users.vue', () => {
describe('mount', () => { describe('mount', () => {
const Wrapper = () => { const Wrapper = () => {
return mount(BlacklistedUsers, { mocks, localVue }) return mount(MutedUsers, { mocks, localVue })
} }
beforeEach(() => { beforeEach(() => {
@ -48,18 +48,18 @@ describe('blacklisted-users.vue', () => {
describe('given a list of blocked users', () => { describe('given a list of blocked users', () => {
beforeEach(() => { beforeEach(() => {
const blacklistedUsers = [{ id: 'u1', name: 'John Doe', slug: 'john-doe', avatar: '' }] const mutedUsers = [{ id: 'u1', name: 'John Doe', slug: 'john-doe', avatar: '' }]
wrapper.setData({ blacklistedUsers }) wrapper.setData({ mutedUsers })
}) })
describe('click unblock', () => { describe('click unmute', () => {
beforeEach(() => { beforeEach(() => {
wrapper.find('button').trigger('click') wrapper.find('button').trigger('click')
}) })
it('calls unblock mutation with given user', () => { it('calls unmute mutation with given user', () => {
expect(mocks.$apollo.mutate).toHaveBeenCalledWith({ expect(mocks.$apollo.mutate).toHaveBeenCalledWith({
mutation: whitelistUserContent(), mutation: unmuteUser(),
variables: { id: 'u1' }, variables: { id: 'u1' },
}) })
}) })

View File

@ -1,31 +1,31 @@
<template> <template>
<div> <div>
<ds-space> <ds-space>
<ds-card :header="$t('settings.blacklisted-users.name')"> <ds-card :header="$t('settings.muted-users.name')">
<ds-text> <ds-text>
{{ $t('settings.blacklisted-users.explanation.intro') }} {{ $t('settings.muted-users.explanation.intro') }}
</ds-text> </ds-text>
<ds-list> <ds-list>
<ds-list-item> <ds-list-item>
{{ $t('settings.blacklisted-users.explanation.your-perspective') }} {{ $t('settings.muted-users.explanation.your-perspective') }}
</ds-list-item> </ds-list-item>
<ds-list-item> <ds-list-item>
{{ $t('settings.blacklisted-users.explanation.their-perspective') }} {{ $t('settings.muted-users.explanation.their-perspective') }}
</ds-list-item> </ds-list-item>
<ds-list-item> <ds-list-item>
{{ $t('settings.blacklisted-users.explanation.search') }} {{ $t('settings.muted-users.explanation.search') }}
</ds-list-item> </ds-list-item>
<ds-list-item> <ds-list-item>
{{ $t('settings.blacklisted-users.explanation.notifications') }} {{ $t('settings.muted-users.explanation.notifications') }}
</ds-list-item> </ds-list-item>
</ds-list> </ds-list>
<ds-text> <ds-text>
{{ $t('settings.blacklisted-users.explanation.closing') }} {{ $t('settings.muted-users.explanation.closing') }}
</ds-text> </ds-text>
</ds-card> </ds-card>
</ds-space> </ds-space>
<ds-card v-if="blacklistedUsers && blacklistedUsers.length"> <ds-card v-if="mutedUsers && mutedUsers.length">
<ds-table :data="blacklistedUsers" :fields="fields" condensed> <ds-table :data="mutedUsers" :fields="fields" condensed>
<template slot="avatar" slot-scope="scope"> <template slot="avatar" slot-scope="scope">
<nuxt-link <nuxt-link
:to="{ :to="{
@ -57,8 +57,8 @@
</nuxt-link> </nuxt-link>
</template> </template>
<template slot="whitelistUserContent" slot-scope="scope"> <template slot="unmuteUser" slot-scope="scope">
<ds-button size="small" @click="whitelistUserContent(scope)"> <ds-button size="small" @click="unmuteUser(scope)">
<ds-icon name="user-plus" /> <ds-icon name="user-plus" />
</ds-button> </ds-button>
</template> </template>
@ -67,12 +67,12 @@
<ds-card v-else> <ds-card v-else>
<ds-space> <ds-space>
<ds-placeholder> <ds-placeholder>
{{ $t('settings.blacklisted-users.empty') }} {{ $t('settings.muted-users.empty') }}
</ds-placeholder> </ds-placeholder>
</ds-space> </ds-space>
<ds-space> <ds-space>
<ds-text align="center"> <ds-text align="center">
{{ $t('settings.blacklisted-users.how-to') }} {{ $t('settings.muted-users.how-to') }}
</ds-text> </ds-text>
</ds-space> </ds-space>
</ds-card> </ds-card>
@ -80,7 +80,7 @@
</template> </template>
<script> <script>
import { blacklistedUsers, whitelistUserContent } from '~/graphql/settings/BlacklistedUsers' import { mutedUsers, unmuteUser } from '~/graphql/settings/MutedUsers'
import HcAvatar from '~/components/Avatar/Avatar.vue' import HcAvatar from '~/components/Avatar/Avatar.vue'
export default { export default {
@ -89,31 +89,31 @@ export default {
}, },
data() { data() {
return { return {
blacklistedUsers: [], mutedUsers: [],
} }
}, },
computed: { computed: {
fields() { fields() {
return { return {
avatar: '', avatar: '',
name: this.$t('settings.blacklisted-users.columns.name'), name: this.$t('settings.muted-users.columns.name'),
slug: this.$t('settings.blacklisted-users.columns.slug'), slug: this.$t('settings.muted-users.columns.slug'),
whitelistUserContent: this.$t('settings.blacklisted-users.columns.whitelist'), unmuteUser: this.$t('settings.muted-users.columns.unmute'),
} }
}, },
}, },
apollo: { apollo: {
blacklistedUsers: { query: blacklistedUsers, fetchPolicy: 'cache-and-network' }, mutedUsers: { query: mutedUsers, fetchPolicy: 'cache-and-network' },
}, },
methods: { methods: {
async whitelistUserContent(user) { async unmuteUser(user) {
await this.$apollo.mutate({ await this.$apollo.mutate({
mutation: whitelistUserContent(), mutation: unmuteUser(),
variables: { id: user.row.id }, variables: { id: user.row.id },
}) })
this.$apollo.queries.blacklistedUsers.refetch() this.$apollo.queries.mutedUsers.refetch()
const { name } = user.row const { name } = user.row
this.$toast.success(this.$t('settings.blacklisted-users.unblocked', { name })) this.$toast.success(this.$t('settings.muted-users.unblocked', { name }))
}, },
}, },
} }