FIX: group membership leak

FIX: raised a proper NotFound exception when filtering groups by username with invalid username.
FIX: properly filter the groups based on current user visibility when viewing another user's groups.
DEV: Guardian.can_see_group?(group) is now using Guardian.can_see_groups(groups) instead of duplicating the same code.
FIX: spec for groups_controller#index when group directory is disabled for logged in user.
FIX: groups_controller.sortable specs to actually test all sorting combinations.
DEV: s/response_body/body/g for slightly shorter spec code.
FIX: rewrote the "view another user's groups" specs to test all group_visibility and members_group_visibility combinations.
DEV: Various refactoring for cleaner and more consistent code.
This commit is contained in:
Régis Hanol 2020-01-15 11:21:58 +01:00
parent ac865112a3
commit 5d75f90b27
4 changed files with 258 additions and 227 deletions

View File

@ -29,10 +29,7 @@ class GroupsController < ApplicationController
groups.where(public_admission: true, automatic: false)
},
close: Proc.new { |groups|
groups.where(
public_admission: false,
automatic: false
)
groups.where(public_admission: false, automatic: false)
},
automatic: Proc.new { |groups|
groups.where(automatic: true)
@ -44,24 +41,23 @@ class GroupsController < ApplicationController
raise Discourse::InvalidAccess.new(:enable_group_directory)
end
page_size = MobileDetection.mobile_device?(request.user_agent) ? 15 : 36
page = params[:page]&.to_i || 0
order = %w{name user_count}.delete(params[:order])
dir = params[:asc] ? 'ASC' : 'DESC'
groups = Group.visible_groups(current_user, order ? "#{order} #{dir}" : nil)
dir = params[:asc].to_s == "true" ? "ASC" : "DESC"
sort = order ? "#{order} #{dir}" : nil
groups = Group.visible_groups(current_user, sort)
type_filters = TYPE_FILTERS.keys
if (username = params[:username]).present?
raise Discourse::NotFound unless user = User.find_by_username(username)
groups = TYPE_FILTERS[:my].call(groups.members_visible_groups(current_user, sort), user)
type_filters = type_filters - [:my, :owner]
end
if (filter = params[:filter]).present?
groups = Group.search_groups(filter, groups: groups)
end
type_filters = TYPE_FILTERS.keys
if username = params[:username]
groups = TYPE_FILTERS[:my].call(groups, User.find_by_username(username))
type_filters = type_filters - [:my, :owner]
end
unless guardian.is_staff?
if !guardian.is_staff?
# hide automatic groups from all non stuff to de-clutter page
groups = groups.where("automatic IS FALSE OR groups.id = #{Group::AUTO_GROUPS[:moderators]}")
type_filters.delete(:automatic)
@ -72,10 +68,7 @@ class GroupsController < ApplicationController
end
if type = params[:type]&.to_sym
callback = TYPE_FILTERS[type]
if !callback
raise Discourse::InvalidParameters.new(:type)
end
raise Discourse::InvalidParameters.new(:type) unless callback = TYPE_FILTERS[type]
groups = callback.call(groups, current_user)
end
@ -87,7 +80,8 @@ class GroupsController < ApplicationController
type_filters = type_filters - [:my, :owner]
end
count = groups.count
page = params[:page].to_i
page_size = MobileDetection.mobile_device?(request.user_agent) ? 15 : 36
groups = groups.offset(page * page_size).limit(page_size)
render_json_dump(
@ -99,7 +93,7 @@ class GroupsController < ApplicationController
extras: {
type_filters: type_filters
},
total_rows_groups: count,
total_rows_groups: groups.count,
load_more_groups: groups_path(
page: page + 1,
type: type,
@ -122,10 +116,7 @@ class GroupsController < ApplicationController
format.json do
groups = Group.visible_groups(current_user)
if !guardian.is_staff?
groups = groups.where(automatic: false)
end
groups = groups.where(automatic: false) if !guardian.is_staff?
render_json_dump(
group: serialize_data(group, GroupShowSerializer, root: nil),
@ -214,7 +205,7 @@ class GroupsController < ApplicationController
raise Discourse::InvalidParameters.new(:limit) if limit < 0 || limit > 1000
raise Discourse::InvalidParameters.new(:offset) if offset < 0
dir = (params[:desc] && !params[:desc].blank?) ? 'DESC' : 'ASC'
dir = (params[:desc] && params[:desc].present?) ? 'DESC' : 'ASC'
order = ""
if params[:requesters]
@ -488,7 +479,7 @@ class GroupsController < ApplicationController
.where("groups.id <> ?", Group::AUTO_GROUPS[:everyone])
.order(:name)
if term = params[:term].to_s
if (term = params[:term]).present?
groups = groups.where("name ILIKE :term OR full_name ILIKE :term", term: "%#{term}%")
end
@ -557,8 +548,7 @@ class GroupsController < ApplicationController
def find_group(param_name, ensure_can_see: true)
name = params.require(param_name)
group = Group
group = group.find_by("lower(name) = ?", name.downcase)
group = Group.find_by("LOWER(name) = ?", name.downcase)
guardian.ensure_can_see!(group) if ensure_can_see
group
end

View File

@ -104,47 +104,46 @@ class Group < ActiveRecord::Base
groups = groups.where("groups.id > 0")
end
unless user&.admin
if !user&.admin
sql = <<~SQL
groups.id IN (
SELECT g.id FROM groups g WHERE g.visibility_level = :public
SELECT id
FROM groups
WHERE visibility_level = :public
UNION ALL
SELECT g.id FROM groups g
WHERE g.visibility_level = :logged_on_users AND :user_id IS NOT NULL
SELECT id
FROM groups
WHERE visibility_level = :logged_on_users
AND :user_id IS NOT NULL
UNION ALL
SELECT g.id FROM groups g
JOIN group_users gu ON gu.group_id = g.id AND
gu.user_id = :user_id
WHERE g.visibility_level = :members
SELECT g.id
FROM groups g
JOIN group_users gu ON gu.group_id = g.id AND gu.user_id = :user_id
WHERE g.visibility_level = :members
UNION ALL
SELECT g.id FROM groups g
LEFT JOIN group_users gu ON gu.group_id = g.id AND
gu.user_id = :user_id AND
gu.owner
WHERE g.visibility_level = :staff AND (gu.id IS NOT NULL OR :is_staff)
SELECT g.id
FROM groups g
LEFT JOIN group_users gu ON gu.group_id = g.id AND gu.user_id = :user_id AND gu.owner
WHERE g.visibility_level = :staff
AND (gu.id IS NOT NULL OR :is_staff)
UNION ALL
SELECT g.id FROM groups g
JOIN group_users gu ON gu.group_id = g.id AND
gu.user_id = :user_id AND
gu.owner
WHERE g.visibility_level = :owners
SELECT g.id
FROM groups g
JOIN group_users gu ON gu.group_id = g.id AND gu.user_id = :user_id AND gu.owner
WHERE g.visibility_level = :owners
)
SQL
groups = groups.where(
sql,
Group.visibility_levels.to_h.merge(user_id: user&.id, is_staff: !!user&.staff?)
)
params = Group.visibility_levels.to_h.merge(user_id: user&.id, is_staff: !!user&.staff?)
groups = groups.where(sql, params)
end
groups
@ -157,47 +156,46 @@ class Group < ActiveRecord::Base
groups = groups.where("groups.id > 0")
end
unless user&.admin
if !user&.admin
sql = <<~SQL
groups.id IN (
SELECT g.id FROM groups g WHERE g.members_visibility_level = :public
SELECT id
FROM groups
WHERE members_visibility_level = :public
UNION ALL
SELECT g.id FROM groups g
WHERE g.members_visibility_level = :logged_on_users AND :user_id IS NOT NULL
SELECT id
FROM groups
WHERE members_visibility_level = :logged_on_users
AND :user_id IS NOT NULL
UNION ALL
SELECT g.id FROM groups g
JOIN group_users gu ON gu.group_id = g.id AND
gu.user_id = :user_id
WHERE g.members_visibility_level = :members
SELECT g.id
FROM groups g
JOIN group_users gu ON gu.group_id = g.id AND gu.user_id = :user_id
WHERE g.members_visibility_level = :members
UNION ALL
SELECT g.id FROM groups g
LEFT JOIN group_users gu ON gu.group_id = g.id AND
gu.user_id = :user_id AND
gu.owner
WHERE g.members_visibility_level = :staff AND (gu.id IS NOT NULL OR :is_staff)
SELECT g.id
FROM groups g
LEFT JOIN group_users gu ON gu.group_id = g.id AND gu.user_id = :user_id AND gu.owner
WHERE g.members_visibility_level = :staff
AND (gu.id IS NOT NULL OR :is_staff)
UNION ALL
SELECT g.id FROM groups g
JOIN group_users gu ON gu.group_id = g.id AND
gu.user_id = :user_id AND
gu.owner
WHERE g.members_visibility_level = :owners
SELECT g.id
FROM groups g
JOIN group_users gu ON gu.group_id = g.id AND gu.user_id = :user_id AND gu.owner
WHERE g.members_visibility_level = :owners
)
SQL
groups = groups.where(
sql,
Group.visibility_levels.to_h.merge(user_id: user&.id, is_staff: !!user&.staff?)
)
params = Group.visibility_levels.to_h.merge(user_id: user&.id, is_staff: !!user&.staff?)
groups = groups.where(sql, params)
end
groups
@ -243,22 +241,24 @@ class Group < ActiveRecord::Base
end
def self.alias_levels(user)
levels = [ALIAS_LEVELS[:everyone]]
if user && user.admin?
levels = [ALIAS_LEVELS[:everyone],
ALIAS_LEVELS[:only_admins],
ALIAS_LEVELS[:mods_and_admins],
ALIAS_LEVELS[:members_mods_and_admins],
ALIAS_LEVELS[:owners_mods_and_admins]]
elsif user && user.moderator?
levels = [ALIAS_LEVELS[:everyone],
ALIAS_LEVELS[:mods_and_admins],
ALIAS_LEVELS[:members_mods_and_admins],
ALIAS_LEVELS[:owners_mods_and_admins]]
if user&.admin?
[
ALIAS_LEVELS[:everyone],
ALIAS_LEVELS[:only_admins],
ALIAS_LEVELS[:mods_and_admins],
ALIAS_LEVELS[:members_mods_and_admins],
ALIAS_LEVELS[:owners_mods_and_admins],
]
elsif user&.moderator?
[
ALIAS_LEVELS[:everyone],
ALIAS_LEVELS[:mods_and_admins],
ALIAS_LEVELS[:members_mods_and_admins],
ALIAS_LEVELS[:owners_mods_and_admins],
]
else
[ALIAS_LEVELS[:everyone]]
end
levels
end
def self.plugin_editable_group_custom_fields
@ -724,9 +724,9 @@ class Group < ActiveRecord::Base
end
def self.member_of(groups, user)
groups.joins(
"LEFT JOIN group_users gu ON gu.group_id = groups.id
").where("gu.user_id = ?", user.id)
groups
.joins("LEFT JOIN group_users gu ON gu.group_id = groups.id ")
.where("gu.user_id = ?", user.id)
end
def self.owner_of(groups, user)
@ -747,7 +747,6 @@ class Group < ActiveRecord::Base
protected
def name_format_validator
return if !name_changed?
# avoid strip! here, it works now

View File

@ -190,61 +190,38 @@ class Guardian
end
def can_see_group?(group)
return false if group.blank?
return true if group.visibility_level == Group.visibility_levels[:public]
return true if is_admin?
return true if is_staff? && group.visibility_level == Group.visibility_levels[:staff]
return true if authenticated? && group.visibility_level == Group.visibility_levels[:logged_on_users]
return false if user.blank?
membership = GroupUser.find_by(group_id: group.id, user_id: user.id)
return false unless membership
if !membership.owner
return false if group.visibility_level == Group.visibility_levels[:owners]
return false if group.visibility_level == Group.visibility_levels[:staff]
end
true
group.present? && can_see_groups?([group])
end
def can_see_group_members?(group)
return false if group.blank?
return true if group.members_visibility_level == Group.visibility_levels[:public]
return true if is_admin?
return true if is_admin? || group.members_visibility_level == Group.visibility_levels[:public]
return true if is_staff? && group.members_visibility_level == Group.visibility_levels[:staff]
return true if authenticated? && group.members_visibility_level == Group.visibility_levels[:logged_on_users]
return false if user.blank?
membership = GroupUser.find_by(group_id: group.id, user_id: user.id)
return false unless membership = GroupUser.find_by(group_id: group.id, user_id: user.id)
return true if membership.owner
return false unless membership
if !membership.owner
return false if group.members_visibility_level == Group.visibility_levels[:owners]
return false if group.members_visibility_level == Group.visibility_levels[:staff]
end
return false if group.members_visibility_level == Group.visibility_levels[:owners]
return false if group.members_visibility_level == Group.visibility_levels[:staff]
true
end
def can_see_groups?(groups)
return false if groups.blank?
return true if groups.all? { |g| g.visibility_level == Group.visibility_levels[:public] }
return true if is_admin?
return true if is_admin? || groups.all? { |g| g.visibility_level == Group.visibility_levels[:public] }
return true if is_staff? && groups.all? { |g| g.visibility_level == Group.visibility_levels[:staff] }
return true if authenticated? && groups.all? { |g| g.visibility_level == Group.visibility_levels[:logged_on_users] }
return false if user.blank?
memberships = GroupUser.where(group: groups, user_id: user.id).pluck(:owner)
return false if memberships.size < groups.size
return true if memberships.all? # owner of all groups
return false if memberships.empty? || memberships.length < groups.size
if !memberships.all?
return false if groups.all? { |g| g.visibility_level == Group.visibility_levels[:owners] }
return false if groups.all? { |g| g.visibility_level == Group.visibility_levels[:staff] }
end
return false if groups.all? { |g| g.visibility_level == Group.visibility_levels[:owners] }
return false if groups.all? { |g| g.visibility_level == Group.visibility_levels[:staff] }
true
end
@ -253,9 +230,9 @@ class Guardian
return false if groups.blank?
requested_group_ids = groups.map(&:id) # Can't use pluck, groups could be a regular array
matching_groups = Group.where(id: requested_group_ids).members_visible_groups(user)
matching_group_ids = Group.where(id: requested_group_ids).members_visible_groups(user).pluck(:id)
matching_groups.pluck(:id).sort == requested_group_ids.sort
matching_group_ids.sort == requested_group_ids.sort
end
# Can we impersonate this user?

View File

@ -11,7 +11,7 @@ describe GroupsController do
describe '#index' do
let(:staff_group) do
Fabricate(:group, name: '0000', visibility_level: Group.visibility_levels[:staff])
Fabricate(:group, name: 'staff_group', visibility_level: Group.visibility_levels[:staff])
end
context 'when group directory is disabled' do
@ -19,24 +19,26 @@ describe GroupsController do
SiteSetting.enable_group_directory = false
end
it 'should deny access for an anon user' do
it 'should deny access for an anon' do
get "/groups.json"
expect(response.status).to eq(403)
end
it 'should deny access for a normal user' do
sign_in(user)
get "/groups.json"
expect(response.status).to eq(403)
end
it 'should not deny access for an admin' do
it 'should allow access for an admin' do
sign_in(admin)
get "/groups.json"
expect(response.status).to eq(200)
end
it 'should not deny access for a moderator' do
it 'should allow access for a moderator' do
sign_in(moderator)
get "/groups.json"
@ -45,73 +47,85 @@ describe GroupsController do
end
context 'searchable' do
it 'should return the right response' do
other_group = Fabricate(:group, name: 'testing')
it 'should return the searched groups' do
testing_group = Fabricate(:group, name: 'testing')
get "/groups.json", params: { filter: 'test' }
expect(response.status).to eq(200)
response_body = JSON.parse(response.body)
body = JSON.parse(response.body)
expect(response_body["groups"].first["id"]).to eq(other_group.id)
expect(response_body["load_more_groups"]).to eq(
"/groups?filter=test&page=1"
)
expect(body["groups"].first["id"]).to eq(testing_group.id)
expect(body["load_more_groups"]).to eq("/groups?filter=test&page=1")
end
end
context 'sortable' do
before do
group
sign_in(user)
end
let!(:other_group) { Fabricate(:group, name: "zzzzzz", users: [user]) }
let!(:other_group) { Fabricate(:group, name: "other_group", users: [user]) }
%w{
desc
asc
}.each do |order|
context "#{order} order" do
it 'should return the right response' do
is_asc = order == 'asc'
params = { order: 'name' }
params.merge!(asc: true) if is_asc
group
get "/groups.json", params: params
expect(response.status).to eq(200)
group_ids = [moderator_group_id, group.id, other_group.id]
group_ids.reverse! if !is_asc
response_body = JSON.parse(response.body)
expect(response_body["groups"].map { |group| group["id"] })
.to eq(group_ids)
expect(response_body["load_more_groups"]).to eq(
"/groups?#{is_asc ? 'asc=true&' : '' }order=name&page=1"
)
end
end
end
context 'ascending order' do
it 'should return the right response' do
group
get "/groups.json", params: { order: 'name' }
context "with default (descending) order" do
it "sorts by name" do
get "/groups.json", params: { order: "name" }
expect(response.status).to eq(200)
response_body = JSON.parse(response.body)
body = JSON.parse(response.body)
expect(response_body["groups"].map { |group| group["id"] })
.to eq([other_group.id, group.id, moderator_group_id])
expect(body["groups"].map { |g| g["id"] }).to eq([
other_group.id, group.id, moderator_group_id
])
expect(response_body["load_more_groups"]).to eq(
"/groups?order=name&page=1"
)
expect(body["load_more_groups"]).to eq("/groups?order=name&page=1")
end
it "sorts by user_count" do
get "/groups.json", params: { order: "user_count" }
expect(response.status).to eq(200)
body = JSON.parse(response.body)
expect(body["groups"].map { |g| g["id"] }).to eq([
group.id, other_group.id, moderator_group_id
])
expect(body["load_more_groups"]).to eq("/groups?order=user_count&page=1")
end
end
context "with ascending order" do
it "sorts by name" do
get "/groups.json", params: { order: "name", asc: true }
expect(response.status).to eq(200)
body = JSON.parse(response.body)
expect(body["groups"].map { |g| g["id"] }).to eq([
moderator_group_id, group.id, other_group.id
])
expect(body["load_more_groups"]).to eq("/groups?asc=true&order=name&page=1")
end
it "sorts by user_count" do
get "/groups.json", params: { order: "user_count", asc: "true" }
expect(response.status).to eq(200)
body = JSON.parse(response.body)
expect(body["groups"].map { |g| g["id"] }).to eq([
moderator_group_id, group.id, other_group.id
])
expect(body["load_more_groups"]).to eq("/groups?asc=true&order=user_count&page=1")
end
end
end
@ -119,20 +133,20 @@ describe GroupsController do
it 'should return the right response' do
group
staff_group
get "/groups.json"
expect(response.status).to eq(200)
response_body = JSON.parse(response.body)
body = JSON.parse(response.body)
group_ids = response_body["groups"].map { |g| g["id"] }
group_ids = body["groups"].map { |g| g["id"] }
expect(group_ids).to include(group.id)
expect(group_ids).to_not include(staff_group.id)
expect(response_body["load_more_groups"]).to eq("/groups?page=1")
expect(response_body["total_rows_groups"]).to eq(1)
expect(group_ids).to contain_exactly(group.id)
expect(response_body["extras"]["type_filters"].map(&:to_sym)).to eq(
expect(body["load_more_groups"]).to eq("/groups?page=1")
expect(body["total_rows_groups"]).to eq(1)
expect(body["extras"]["type_filters"].map(&:to_sym)).to eq(
described_class::TYPE_FILTERS.keys - [:my, :owner, :automatic]
)
end
@ -148,19 +162,71 @@ describe GroupsController do
end
it 'should return the right response' do
user2 = Fabricate(:user)
group
sign_in(user2)
u = Fabricate(:user)
m = Fabricate(:user)
o = Fabricate(:user)
get "/groups.json", params: { username: user.username }
levels = Group.visibility_levels.values
levels.product(levels).each { |group_level, members_level|
g = Fabricate(:group,
name: "#{group_level}_#{members_level}",
visibility_level: group_level,
members_visibility_level: members_level,
users: [u]
)
g.add(m) if group_level == Group.visibility_levels[:members] || members_level == Group.visibility_levels[:members]
g.add_owner(o) if group_level == Group.visibility_levels[:owners] || members_level == Group.visibility_levels[:owners]
}
# anonymous user
get "/groups.json", params: { username: u.username }
expect(response.status).to eq(200)
group_names = JSON.parse(response.body)["groups"].map { |g| g["name"] }
expect(group_names).to contain_exactly("0_0")
response_body = JSON.parse(response.body)
# logged in user
sign_in(Fabricate(:user))
get "/groups.json", params: { username: u.username }
group_ids = response_body["groups"].map { |g| g["id"] }
expect(response.status).to eq(200)
group_names = JSON.parse(response.body)["groups"].map { |g| g["name"] }
expect(group_names).to contain_exactly("0_0", "0_1", "1_0", "1_1")
expect(group_ids).to contain_exactly(group.id)
# member of the group
sign_in(m)
get "/groups.json", params: { username: u.username }
expect(response.status).to eq(200)
group_names = JSON.parse(response.body)["groups"].map { |g| g["name"] }
expect(group_names).to contain_exactly("0_0", "0_1", "0_2", "1_0", "1_1", "1_2", "2_0", "2_1", "2_2")
# owner
sign_in(o)
get "/groups.json", params: { username: u.username }
expect(response.status).to eq(200)
group_names = JSON.parse(response.body)["groups"].map { |g| g["name"] }
expect(group_names).to contain_exactly("0_0", "0_1", "0_4", "1_0", "1_1", "1_4", "2_4", "3_4", "4_0", "4_1", "4_2", "4_3", "4_4")
# moderator
sign_in(moderator)
get "/groups.json", params: { username: u.username }
expect(response.status).to eq(200)
group_names = JSON.parse(response.body)["groups"].map { |g| g["name"] }
expect(group_names).to contain_exactly("0_0", "0_1", "0_3", "1_0", "1_1", "1_3", "3_0", "3_1", "3_3")
# admin
sign_in(admin)
get "/groups.json", params: { username: u.username }
expect(response.status).to eq(200)
group_names = JSON.parse(response.body)["groups"].map { |g| g["name"] }
all_group_names = levels.product(levels).map { |a, b| "#{a}_#{b}" }
expect(group_names).to contain_exactly(*all_group_names)
end
end
@ -179,18 +245,18 @@ describe GroupsController do
expect(response.status).to eq(200)
response_body = JSON.parse(response.body)
body = JSON.parse(response.body)
group_ids = response_body["groups"].map { |g| g["id"] }
group_body = response_body["groups"].find { |g| g["id"] == group.id }
group_ids = body["groups"].map { |g| g["id"] }
group_body = body["groups"].find { |g| g["id"] == group.id }
expect(group_body["is_group_user"]).to eq(true)
expect(group_body["is_group_owner"]).to eq(true)
expect(group_ids).to include(group.id, staff_group.id)
expect(response_body["load_more_groups"]).to eq("/groups?page=1")
expect(response_body["total_rows_groups"]).to eq(10)
expect(body["load_more_groups"]).to eq("/groups?page=1")
expect(body["total_rows_groups"]).to eq(10)
expect(response_body["extras"]["type_filters"].map(&:to_sym)).to eq(
expect(body["extras"]["type_filters"].map(&:to_sym)).to eq(
described_class::TYPE_FILTERS.keys
)
end
@ -201,10 +267,10 @@ describe GroupsController do
expect(response.status).to eq(200)
response_body = JSON.parse(response.body)
group_ids = response_body["groups"].map { |g| g["id"] }
body = JSON.parse(response.body)
group_ids = body["groups"].map { |g| g["id"] }
expect(response_body["total_rows_groups"]).to eq(expected_group_ids.count)
expect(body["total_rows_groups"]).to eq(expected_group_ids.count)
expect(group_ids).to contain_exactly(*expected_group_ids)
end
@ -269,10 +335,10 @@ describe GroupsController do
expect(response.status).to eq(200)
response_body = JSON.parse(response.body)
body = JSON.parse(response.body)
expect(response_body['group']['id']).to eq(group.id)
expect(response_body['extras']["visible_group_names"]).to eq([group.name])
expect(body['group']['id']).to eq(group.id)
expect(body['extras']["visible_group_names"]).to eq([group.name])
end
context 'as an admin' do
@ -282,15 +348,15 @@ describe GroupsController do
expect(response.status).to eq(200)
response_body = JSON.parse(response.body)
body = JSON.parse(response.body)
expect(response_body['group']['id']).to eq(group.id)
expect(body['group']['id']).to eq(group.id)
groups = Group::AUTO_GROUPS.keys
groups.delete(:everyone)
groups.push(group.name)
expect(response_body['extras']["visible_group_names"])
expect(body['extras']["visible_group_names"])
.to contain_exactly(*groups.map(&:to_s))
end
end
@ -318,9 +384,9 @@ describe GroupsController do
expect(response.status).to eq(200)
response_body = JSON.parse(response.body)['group']
body = JSON.parse(response.body)['group']
expect(response_body["id"]).to eq(group.id)
expect(body["id"]).to eq(group.id)
end
end
end
@ -387,7 +453,6 @@ describe GroupsController do
end
it "ensures that membership can be paginated" do
freeze_time
first_user = Fabricate(:user)
@ -459,8 +524,8 @@ describe GroupsController do
get "/groups/#{group.name}/mentionable.json"
expect(response.status).to eq(200)
response_body = JSON.parse(response.body)
expect(response_body["mentionable"]).to eq(false)
body = JSON.parse(response.body)
expect(body["mentionable"]).to eq(false)
group.update!(
mentionable_level: Group::ALIAS_LEVELS[:everyone],
@ -470,8 +535,8 @@ describe GroupsController do
get "/groups/#{group.name}/mentionable.json"
expect(response.status).to eq(200)
response_body = JSON.parse(response.body)
expect(response_body["mentionable"]).to eq(true)
body = JSON.parse(response.body)
expect(body["mentionable"]).to eq(true)
group.update!(
mentionable_level: Group::ALIAS_LEVELS[:nobody],
@ -481,8 +546,8 @@ describe GroupsController do
get "/groups/#{group.name}/mentionable.json"
expect(response.status).to eq(200)
response_body = JSON.parse(response.body)
expect(response_body["mentionable"]).to eq(true)
body = JSON.parse(response.body)
expect(body["mentionable"]).to eq(true)
end
end
@ -493,8 +558,8 @@ describe GroupsController do
get "/groups/#{group.name}/messageable.json"
expect(response.status).to eq(200)
response_body = JSON.parse(response.body)
expect(response_body["messageable"]).to eq(false)
body = JSON.parse(response.body)
expect(body["messageable"]).to eq(false)
group.update!(
messageable_level: Group::ALIAS_LEVELS[:everyone],
@ -504,8 +569,8 @@ describe GroupsController do
get "/groups/#{group.name}/messageable.json"
expect(response.status).to eq(200)
response_body = JSON.parse(response.body)
expect(response_body["messageable"]).to eq(true)
body = JSON.parse(response.body)
expect(body["messageable"]).to eq(true)
end
end