mirror of
https://github.com/discourse/discourse.git
synced 2024-11-22 10:57:04 +08:00
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:
parent
ac865112a3
commit
5d75f90b27
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user