Hide a blocked user's content [deploy] (#4678)
* Hide blocked users' content appropriately * Use RESTful create route * Update functionality to block the user * Fix specs for new route * Use const instead of var * Add noopener and noreferrer * Remove caching for blocked user ids * Add new rule for lack of noopener noreferrer * Update snapshot
This commit is contained in:
parent
027dbb027b
commit
85d8f52789
18 changed files with 122 additions and 63 deletions
|
|
@ -199,6 +199,8 @@ function algoliaPaginate(tag){
|
|||
.then(function searchDone(content) {
|
||||
nextPage += 1;
|
||||
insertArticles(content.hits);
|
||||
const checkBlockedContentEvent = new CustomEvent('checkBlockedContent')
|
||||
window.dispatchEvent(checkBlockedContentEvent)
|
||||
if (content.hits.length == 0) {
|
||||
document.getElementById("loading-articles").style.display = "none"
|
||||
done = true;
|
||||
|
|
|
|||
|
|
@ -137,6 +137,8 @@ function algoliaFollowedArticles(){
|
|||
|
||||
if (user && user.followed_tag_names && user.followed_tag_names.length > 0) {
|
||||
insertInitialArticles(user)
|
||||
const checkBlockedContentEvent = new CustomEvent('checkBlockedContent')
|
||||
window.dispatchEvent(checkBlockedContentEvent)
|
||||
var followedUsersArray = [];
|
||||
if (user.followed_user_ids){
|
||||
followedUsersArray = user.followed_user_ids.map(function(id){return 'user_'+id});
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ function buildArticleHTML(article) {
|
|||
timeAgoInWords = timeAgo(article.published_at_int);
|
||||
}
|
||||
|
||||
return '<div class="single-article single-article-small-pic">\
|
||||
return '<div class="single-article single-article-small-pic" data-content-user-id="'+article.user_id+'">\
|
||||
'+videoHTML+'\
|
||||
'+orgHeadline+'\
|
||||
<div class="small-pic">\
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ function buildCommentHTML(comment) {
|
|||
'+detailsStartHTML+'\
|
||||
<div class="comment-hash-marker" id="'+comment.id_code+'"></div>\
|
||||
<div id="comment-node-'+comment.id+'" class="single-comment-node '+depthClass+' comment-deep-'+comment.depth+'" "\
|
||||
data-comment-id="'+comment.id+'" data-comment-author-id="'+comment.user.id+'" data-current-user-comment="'+comment.newly_created+'">\
|
||||
data-comment-id="'+comment.id+'" data-comment-author-id="'+comment.user.id+'" data-current-user-comment="'+comment.newly_created+'" data-content-user-id="'+comment.user.id+'">\
|
||||
<div class="inner-comment '+customClass+'">\
|
||||
<div class="details">\
|
||||
<a href="/'+comment.user.username+'">\
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
const fetchCallback = ({ url, headers = {}, addTokenToBody = false, body }) => {
|
||||
return csrfToken => {
|
||||
if (addTokenToBody) { body.append('authenticity_token', csrfToken) };
|
||||
if (addTokenToBody) {
|
||||
body.append('authenticity_token', csrfToken);
|
||||
}
|
||||
return window.fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
|
|
@ -24,37 +26,41 @@ function sendFetch(switchStatement, body) {
|
|||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body
|
||||
body,
|
||||
});
|
||||
case 'reaction-creation':
|
||||
return fetchCallback({
|
||||
url: '/reactions',
|
||||
addTokenToBody: true,
|
||||
body
|
||||
body,
|
||||
});
|
||||
case 'image-upload':
|
||||
return fetchCallback({
|
||||
url: '/image_uploads',
|
||||
addTokenToBody: true,
|
||||
body
|
||||
body,
|
||||
});
|
||||
case 'follow-creation':
|
||||
return fetchCallback({
|
||||
url: '/follows',
|
||||
addTokenToBody: true,
|
||||
body
|
||||
body,
|
||||
});
|
||||
case 'chat-creation':
|
||||
return fetchCallback({
|
||||
url: '/chat_channels/create_chat',
|
||||
addTokenToBody: true,
|
||||
body
|
||||
body,
|
||||
});
|
||||
case 'block-chat':
|
||||
case 'block-user':
|
||||
return fetchCallback({
|
||||
url: '/chat_channels/block_chat',
|
||||
addTokenToBody: true,
|
||||
body
|
||||
url: '/user_blocks',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
addTokenToBody: false,
|
||||
body,
|
||||
});
|
||||
case 'comment-creation':
|
||||
return fetchCallback({
|
||||
|
|
@ -62,7 +68,7 @@ function sendFetch(switchStatement, body) {
|
|||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body
|
||||
body,
|
||||
});
|
||||
case 'comment-preview':
|
||||
return fetchCallback({
|
||||
|
|
@ -70,7 +76,7 @@ function sendFetch(switchStatement, body) {
|
|||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body
|
||||
body,
|
||||
});
|
||||
default:
|
||||
console.log('A wrong switchStatement was used.'); // eslint-disable-line no-console
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ class AsyncInfoController < ApplicationController
|
|||
followed_organization_ids: @user.cached_following_organizations_ids,
|
||||
followed_podcast_ids: @user.cached_following_podcasts_ids,
|
||||
reading_list_ids: ReadingList.new(@user).cached_ids_of_articles,
|
||||
blocked_user_ids: @user.all_blocking.pluck(:blocked_id),
|
||||
saw_onboarding: @user.saw_onboarding,
|
||||
checked_code_of_conduct: @user.checked_code_of_conduct,
|
||||
checked_terms_and_conditions: @user.checked_terms_and_conditions,
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ module.exports = {
|
|||
},
|
||||
},
|
||||
],
|
||||
'react/jsx-no-target-blank': [2, { enforceDynamicLinks: 'always' }],
|
||||
},
|
||||
globals: {
|
||||
InstantClick: false,
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ exports[`<UserDetails /> for user1 should render and test snapshot 1`] = `
|
|||
>
|
||||
<a
|
||||
href="https://twitter.com/bojacktwitter"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<img
|
||||
|
|
@ -55,6 +56,7 @@ exports[`<UserDetails /> for user1 should render and test snapshot 1`] = `
|
|||
</a>
|
||||
<a
|
||||
href="https://github.com/bojackgithub"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<img
|
||||
|
|
@ -70,6 +72,7 @@ exports[`<UserDetails /> for user1 should render and test snapshot 1`] = `
|
|||
</a>
|
||||
<a
|
||||
href="http://bojackhorseman.com"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<img
|
||||
|
|
@ -254,6 +257,7 @@ exports[`<UserDetails /> for user2 should render and test snapshot 1`] = `
|
|||
>
|
||||
<a
|
||||
href="https://twitter.com/mrpbtwitter"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<img
|
||||
|
|
@ -269,6 +273,7 @@ exports[`<UserDetails /> for user2 should render and test snapshot 1`] = `
|
|||
</a>
|
||||
<a
|
||||
href="https://github.com/mrpbgithub"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<img
|
||||
|
|
@ -284,6 +289,7 @@ exports[`<UserDetails /> for user2 should render and test snapshot 1`] = `
|
|||
</a>
|
||||
<a
|
||||
href="http://mrpeanutbutter.com"
|
||||
rel="noopener noreferrer"
|
||||
target="_blank"
|
||||
>
|
||||
<img
|
||||
|
|
|
|||
|
|
@ -3,12 +3,14 @@ import twitterImage from 'images/twitter-logo.svg';
|
|||
import githubImage from 'images/github-logo.svg';
|
||||
import websiteImage from 'images/external-link-logo.svg';
|
||||
|
||||
function blockChat(activeChannelId) {
|
||||
const formData = new FormData();
|
||||
formData.append('chat_id', activeChannelId);
|
||||
formData.append('controller', 'chat_channels');
|
||||
function blockUser(blockedUserId) {
|
||||
const body = {
|
||||
user_block: {
|
||||
blocked_id: blockedUserId,
|
||||
},
|
||||
};
|
||||
|
||||
getCsrfToken().then(sendFetch('block-chat', formData));
|
||||
getCsrfToken().then(sendFetch('block-user', JSON.stringify(body)));
|
||||
}
|
||||
|
||||
const setUpButton = ({ modalId = '', otherModalId = '', btnName = '' }) => {
|
||||
|
|
@ -16,9 +18,7 @@ const setUpButton = ({ modalId = '', otherModalId = '', btnName = '' }) => {
|
|||
<button
|
||||
onClick={() => {
|
||||
const modal = document.getElementById(`${modalId}`);
|
||||
const otherModal = document.getElementById(
|
||||
`${otherModalId}`,
|
||||
);
|
||||
const otherModal = document.getElementById(`${otherModalId}`);
|
||||
otherModal.style.display = 'none';
|
||||
if (modal.style.display === 'none') {
|
||||
modal.style.display = 'block';
|
||||
|
|
@ -32,26 +32,26 @@ const setUpButton = ({ modalId = '', otherModalId = '', btnName = '' }) => {
|
|||
{btnName}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const userDetailsConfig = {
|
||||
twitter_username: {
|
||||
hostUrl: 'https://twitter.com/',
|
||||
srcImage: twitterImage,
|
||||
imageAltText: 'twitter logo'
|
||||
imageAltText: 'twitter logo',
|
||||
},
|
||||
github_username: {
|
||||
hostUrl: 'https://github.com/',
|
||||
srcImage: githubImage,
|
||||
imageAltText: 'github logo'
|
||||
imageAltText: 'github logo',
|
||||
},
|
||||
website_url: {
|
||||
className: 'external-link-img',
|
||||
hostUrl: '',
|
||||
srcImage: websiteImage,
|
||||
imageAltText: 'external link icon'
|
||||
}
|
||||
}
|
||||
imageAltText: 'external link icon',
|
||||
},
|
||||
};
|
||||
|
||||
export default class UserDetails extends Component {
|
||||
render() {
|
||||
|
|
@ -60,14 +60,11 @@ export default class UserDetails extends Component {
|
|||
const channel = this.props.activeChannel || {};
|
||||
const socialIcons = [];
|
||||
const userMeta = ['twitter_username', 'github_username', 'website_url'];
|
||||
userMeta.forEach((metaProp) => {
|
||||
userMeta.forEach(metaProp => {
|
||||
if (user[metaProp]) {
|
||||
let { className, hostUrl, srcImage, imageAltText } = userDetailsConfig[metaProp];
|
||||
socialIcons.push(
|
||||
<a
|
||||
href={`${hostUrl}${user[metaProp]}`}
|
||||
target="_blank"
|
||||
>
|
||||
<a href={`${hostUrl}${user[metaProp]}`} target="_blank" rel="noopener noreferrer">
|
||||
<img
|
||||
className={className}
|
||||
src={srcImage}
|
||||
|
|
@ -89,10 +86,10 @@ export default class UserDetails extends Component {
|
|||
}
|
||||
let blockButton = '';
|
||||
if (channel.channel_type === 'direct' && window.currentUser.id != user.id) {
|
||||
blockButton = setUpButton({
|
||||
modalId: 'userdetails__blockmsg',
|
||||
otherModalId: 'userdetails__reportabuse',
|
||||
btnName: 'Block User'
|
||||
blockButton = setUpButton({
|
||||
modalId: 'userdetails__blockmsg',
|
||||
otherModalId: 'userdetails__reportabuse',
|
||||
btnName: 'Block User',
|
||||
});
|
||||
}
|
||||
return (
|
||||
|
|
@ -124,13 +121,11 @@ export default class UserDetails extends Component {
|
|||
</div>
|
||||
<div className="userdetails__blockreport">
|
||||
{blockButton}
|
||||
{
|
||||
setUpButton({
|
||||
modalId: 'userdetails__reportabuse',
|
||||
otherModalId: 'userdetails__blockmsg',
|
||||
btnName: 'Report Abuse'
|
||||
})
|
||||
}
|
||||
{setUpButton({
|
||||
modalId: 'userdetails__reportabuse',
|
||||
otherModalId: 'userdetails__blockmsg',
|
||||
btnName: 'Report Abuse',
|
||||
})}
|
||||
</div>
|
||||
<div id="userdetails__reportabuse" style="display:none">
|
||||
<div className="userdetails__reportabuse">
|
||||
|
|
@ -154,7 +149,7 @@ export default class UserDetails extends Component {
|
|||
tabIndex="0"
|
||||
href="/report-abuse"
|
||||
onClick={() => {
|
||||
blockChat(channelId);
|
||||
blockUser(channelId);
|
||||
}}
|
||||
>
|
||||
Yes, Report
|
||||
|
|
@ -204,12 +199,12 @@ export default class UserDetails extends Component {
|
|||
<a
|
||||
tabIndex="0"
|
||||
onClick={() => {
|
||||
blockChat(channelId);
|
||||
blockUser(user.id);
|
||||
window.location.href = `/connect`;
|
||||
}}
|
||||
onKeyUp={e => {
|
||||
if (e.keyCode === 13) {
|
||||
blockChat(channelId);
|
||||
blockUser(user.id);
|
||||
window.location.href = `/connect`;
|
||||
}
|
||||
}}
|
||||
|
|
|
|||
26
app/javascript/contentDisplayPolicy/hideBlockedContent.js
Normal file
26
app/javascript/contentDisplayPolicy/hideBlockedContent.js
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
export default function hideBlockedContent() {
|
||||
const contentUserElements = Array.from(
|
||||
document.querySelectorAll('div[data-content-user-id]'),
|
||||
);
|
||||
const blockedUserIds = userData().blocked_user_ids;
|
||||
|
||||
const divsToHide = contentUserElements.filter(div => {
|
||||
const { contentUserId } = div.dataset;
|
||||
return blockedUserIds.includes(parseInt(contentUserId, 10));
|
||||
});
|
||||
|
||||
divsToHide.forEach(div => {
|
||||
if (div.className.includes('single-article')) {
|
||||
div.style.display = 'none';
|
||||
} else if (div.className.includes('single-comment-node')) {
|
||||
const divInnerComment = div.querySelector('div.inner-comment');
|
||||
divInnerComment.innerHTML = `
|
||||
<div class="body " style="padding-bottom:32px;opacity:0.3;user-select:none;cursor:default">
|
||||
[blocked content]
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener('checkBlockedContent', hideBlockedContent);
|
||||
7
app/javascript/packs/contentDisplayPolicy.js
Normal file
7
app/javascript/packs/contentDisplayPolicy.js
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
import hideBlockedContent from '../contentDisplayPolicy/hideBlockedContent';
|
||||
|
||||
window.InstantClick.on('change', () => {
|
||||
hideBlockedContent();
|
||||
});
|
||||
|
||||
hideBlockedContent();
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
/* eslint-disable no-alert */
|
||||
|
||||
export default function initBlock() {
|
||||
const blockButton = document.getElementById(
|
||||
'user-profile-dropdownmenu-block-button',
|
||||
|
|
@ -25,13 +27,18 @@ export default function initBlock() {
|
|||
.then(response => {
|
||||
if (response.result === 'unblocked') {
|
||||
blockButton.innerText = 'Block';
|
||||
/* eslint-disable-next-line no-use-before-define */
|
||||
blockButton.addEventListener('click', block, { once: true });
|
||||
} else if (response.status === 422) {
|
||||
window.alert(`Something went wrong: ${e} -- Please refresh the page to try again.`)
|
||||
window.alert(
|
||||
`Something went wrong: ${response.error} -- Please refresh the page to try again.`,
|
||||
);
|
||||
}
|
||||
})
|
||||
.catch(e => {
|
||||
window.alert(`Something went wrong: ${e}. -- Please refresh the page to try again.`);
|
||||
window.alert(
|
||||
`Something went wrong: ${e}. -- Please refresh the page to try again.`,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -43,7 +50,7 @@ export default function initBlock() {
|
|||
- prevent them from messaging you via DEV Connect`,
|
||||
);
|
||||
if (confirmBlock) {
|
||||
fetch(`/user_blocks/${profileUserId}`, {
|
||||
fetch(`/user_blocks`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
|
|
@ -62,11 +69,15 @@ export default function initBlock() {
|
|||
blockButton.innerText = 'Unblock';
|
||||
blockButton.addEventListener('click', unblock, { once: true });
|
||||
} else if (response.status === 422) {
|
||||
window.alert(`Something went wrong: ${e}. -- Please refresh the page to try again.`)
|
||||
window.alert(
|
||||
`Something went wrong: ${response.error}. -- Please refresh the page to try again.`,
|
||||
);
|
||||
}
|
||||
})
|
||||
.catch(e => {
|
||||
window.alert(`Something went wrong: ${e}. -- Please refresh the page to try again.`);
|
||||
window.alert(
|
||||
`Something went wrong: ${e}. -- Please refresh the page to try again.`,
|
||||
);
|
||||
});
|
||||
} else {
|
||||
blockButton.addEventListener('click', block, { once: true });
|
||||
|
|
@ -74,6 +85,7 @@ export default function initBlock() {
|
|||
}
|
||||
|
||||
// userData() is a global function
|
||||
/* eslint-disable-next-line no-undef */
|
||||
const currentUserId = userData().id;
|
||||
|
||||
if (currentUserId === parseInt(profileUserId, 10)) {
|
||||
|
|
@ -91,3 +103,5 @@ export default function initBlock() {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
/* eslint-enable no-alert */
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<div class="single-article single-article-small-pic">
|
||||
<div class="single-article single-article-small-pic" data-content-user-id="<%= story.user_id %>">
|
||||
<% if story.video.present? && story.video_thumbnail_url.present? %>
|
||||
<a class="single-article-video-preview" style="background-image:url(<%= story.cloudinary_video_url %>)" href="<%= story.path %>">
|
||||
<div class="single-article-video-duration">
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@
|
|||
<div id="featured-story-marker" data-featured-article="articles-<%= @featured_story.id %>"></div>
|
||||
<img src="<%= cloud_cover_url(@featured_story.main_image) %>" style="display:none" alt="<%= @featured_story.title %>" />
|
||||
<a href="<%= @featured_story.path %>" id="article-link-<%= @featured_story.id %>" class="index-article-link" aria-label="Main Story" data-featured-article="articles-<%= @featured_story.id %>">
|
||||
<div class="single-article big-article">
|
||||
<div class="single-article big-article" data-content-user-id="<%= @featured_story.user_id %>">
|
||||
<div class="picture image-final" style="background-color:<%= @featured_story.main_image_background_hex_color %>;background-image:url(<%= cloud_cover_url(@featured_story.main_image) %>)"></div>
|
||||
<div class="content-wrapper">
|
||||
<h3>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<div class="comment-hash-marker" id="<%= comment.id_code_generated %>"></div>
|
||||
<div id="comment-node-<%= comment.id %>" class="single-comment-node <%= comment_class(comment, is_view_root) %> <%= "flat-node" if comment.depth > 3 %> comment-deep-<%= comment.depth %>" data-comment-id="<%= comment.id %>" data-comment-author-id="<%= comment_user_id_unless_deleted comment %>">
|
||||
<div id="comment-node-<%= comment.id %>" class="single-comment-node <%= comment_class(comment, is_view_root) %> <%= "flat-node" if comment.depth > 3 %> comment-deep-<%= comment.depth %>" data-comment-id="<%= comment.id %>" data-comment-author-id="<%= comment_user_id_unless_deleted comment %>" data-content-user-id="<%= comment_user_id_unless_deleted comment %>">
|
||||
<% if comment.deleted %>
|
||||
<div class="inner-comment">
|
||||
<div class="body" style="padding-bottom:32px;opacity:0.3;user-select:none;cursor:default">
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
<%= javascript_include_tag "base", defer: true %>
|
||||
<% if user_signed_in? %>
|
||||
<%= javascript_pack_tag "onboardingRedirectCheck", defer: true %>
|
||||
<%= javascript_pack_tag "contentDisplayPolicy", defer: true %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% if !core_pages? %>
|
||||
|
|
|
|||
|
|
@ -179,9 +179,7 @@ Rails.application.routes.draw do
|
|||
resources :display_ad_events, only: [:create]
|
||||
resources :badges, only: [:index]
|
||||
resource :pro_membership, path: :pro, only: %i[show create update]
|
||||
resources :user_blocks, param: :blocked_id, only: %i[show destroy] do
|
||||
post ":blocked_id", on: :collection, to: "user_blocks#create"
|
||||
end
|
||||
resources :user_blocks, param: :blocked_id, only: %i[show create destroy]
|
||||
resolve("ProMembership") { [:pro_membership] } # see https://guides.rubyonrails.org/routing.html#using-resolve
|
||||
|
||||
get "/chat_channel_memberships/find_by_chat_channel_id" => "chat_channel_memberships#find_by_chat_channel_id"
|
||||
|
|
|
|||
|
|
@ -32,10 +32,10 @@ RSpec.describe "UserBlock", type: :request do
|
|||
end
|
||||
end
|
||||
|
||||
describe "POST /user_blocks/:blocked_id or #create" do
|
||||
describe "POST /user_blocks or #create" do
|
||||
it "renders 'not-logged-in' when not logged in" do
|
||||
sign_out blocker
|
||||
post "/user_blocks/#{blocked.id}", params: { user_block: { blocked_id: blocked.id } }
|
||||
post "/user_blocks", params: { user_block: { blocked_id: blocked.id } }
|
||||
json_response = JSON.parse(response.body)
|
||||
expect(response.content_type).to eq "application/json"
|
||||
expect(response.status).to eq 401
|
||||
|
|
@ -43,14 +43,14 @@ RSpec.describe "UserBlock", type: :request do
|
|||
end
|
||||
|
||||
it "creates the correct user_block" do
|
||||
post "/user_blocks/#{blocked.id}", params: { user_block: { blocked_id: blocked.id } }
|
||||
post "/user_blocks", params: { user_block: { blocked_id: blocked.id } }
|
||||
expect(UserBlock.count).to eq 1
|
||||
expect(UserBlock.first.blocker_id).to eq blocker.id
|
||||
expect(UserBlock.first.blocked_id).to eq blocked.id
|
||||
end
|
||||
|
||||
it "returns a JSON response with blocked" do
|
||||
post "/user_blocks/#{blocked.id}", params: { user_block: { blocked_id: blocked.id } }
|
||||
post "/user_blocks", params: { user_block: { blocked_id: blocked.id } }
|
||||
json_response = JSON.parse(response.body)
|
||||
expect(response.content_type).to eq "application/json"
|
||||
expect(json_response["result"]).to eq "blocked"
|
||||
|
|
@ -60,7 +60,7 @@ RSpec.describe "UserBlock", type: :request do
|
|||
chat_channel = create(:chat_channel, channel_type: "direct", slug: "#{blocker.username}/#{blocked.username}", status: "active")
|
||||
create(:chat_channel_membership, chat_channel_id: chat_channel.id, user_id: blocker.id)
|
||||
create(:chat_channel_membership, chat_channel_id: chat_channel.id, user_id: blocked.id)
|
||||
post "/user_blocks/#{blocked.id}", params: { user_block: { blocked_id: blocked.id } }
|
||||
post "/user_blocks", params: { user_block: { blocked_id: blocked.id } }
|
||||
expect(chat_channel.reload.status).to eq "blocked"
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue