Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIX: Sum assignments for group and group users #482

Merged
merged 1 commit into from Jul 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
29 changes: 13 additions & 16 deletions app/controllers/discourse_assign/assign_controller.rb
Expand Up @@ -125,7 +125,7 @@ def group_members

guardian.ensure_can_see_group_members!(group)

members =
users_with_assignments_count =
User
.joins("LEFT OUTER JOIN group_users g ON g.user_id = users.id")
.joins(
Expand All @@ -140,25 +140,22 @@ def group_members
.limit(limit)
.offset(offset)

members = members.where(<<~SQL, pattern: "%#{params[:filter]}%") if params[:filter]
users_with_assignments_count =
users_with_assignments_count.where(<<~SQL, pattern: "%#{params[:filter]}%") if params[
users.name ILIKE :pattern OR users.username_lower ILIKE :pattern
SQL

group_assignments =
Topic
.joins("JOIN assignments a ON a.topic_id = topics.id")
.where(<<~SQL, group_id: group.id)
a.assigned_to_id = :group_id AND a.assigned_to_type = 'Group' AND a.active
SQL
.pluck(:topic_id)

assignments =
TopicQuery.new(current_user).group_topics_assigned_results(group).pluck("topics.id")
:filter
]
group_assignments_count = Assignment.active_for_group(group).count
users_assignments_count =
users_with_assignments_count.reduce(0) do |sum, assignment|
sum + assignment.assignments_count
end

render json: {
members: serialize_data(members, GroupUserAssignedSerializer),
assignment_count: (assignments | group_assignments).count,
group_assignment_count: group_assignments.count,
members: serialize_data(users_with_assignments_count, GroupUserAssignedSerializer),
assignment_count: users_assignments_count + group_assignments_count,
group_assignment_count: group_assignments_count,
}
end

Expand Down
2 changes: 2 additions & 0 deletions app/models/assignment.rb
Expand Up @@ -15,6 +15,8 @@ class Assignment < ActiveRecord::Base
)
}

scope :active_for_group, ->(group) { where(assigned_to: group, active: true) }

before_validation :default_status

validate :validate_status, if: -> { SiteSetting.enable_assign_status }
Expand Down
17 changes: 17 additions & 0 deletions spec/fabricators/assignment_fabricator.rb
@@ -0,0 +1,17 @@
# frozen_string_literal: true

Fabricator(:topic_assignment, class_name: :assignment) do
topic
target { |attrs| attrs[:topic] }
target_type "Topic"
assigned_by_user { Fabricate(:user) }
assigned_to { Fabricate(:user) }
end

Fabricator(:post_assignment, class_name: :assignment) do
topic { |attrs| attrs[:post]&.topic || Fabricate(:topic) }
target { |attrs| attrs[:post] || Fabricate(:post, topic: attrs[:topic]) }
target_type "Post"
assigned_by_user { Fabricate(:user) }
assigned_to { Fabricate(:user) }
end
27 changes: 27 additions & 0 deletions spec/models/assignment_spec.rb
@@ -0,0 +1,27 @@
# frozen_string_literal: true

require "rails_helper"

describe Assignment do
fab!(:group) { Fabricate(:group) }
fab!(:user1) { Fabricate(:user) }
fab!(:user2) { Fabricate(:user) }
fab!(:group_user1) { Fabricate(:group_user, user: user1, group: group) }
fab!(:group_user1) { Fabricate(:group_user, user: user2, group: group) }

fab!(:wrong_group) { Fabricate(:group) }

before { SiteSetting.assign_enabled = true }

describe "#active_for_group" do
it "returns active assignments for the group" do
assignment1 = Fabricate(:topic_assignment, assigned_to: group)
assignment2 = Fabricate(:post_assignment, assigned_to: group)
Fabricate(:post_assignment, assigned_to: group, active: false)
Fabricate(:post_assignment, assigned_to: user1)
Fabricate(:topic_assignment, assigned_to: wrong_group)

expect(Assignment.active_for_group(group)).to contain_exactly(assignment1, assignment2)
end
end
end
114 changes: 78 additions & 36 deletions spec/requests/assign_controller_spec.rb
Expand Up @@ -364,56 +364,98 @@ def assign_user_to_post
describe "#group_members" do
include_context "with group that is allowed to assign"

fab!(:post1) { Fabricate(:post) }
fab!(:post2) { Fabricate(:post) }
fab!(:post3) { Fabricate(:post) }

before do
add_to_assign_allowed_group(user2)
add_to_assign_allowed_group(user)

Assigner.new(post1.topic, user).assign(user)
Assigner.new(post2.topic, user).assign(user2)
Assigner.new(post3.topic, user).assign(user)
end

it "list members order by assignments_count" do
sign_in(user)
topic = Fabricate(:topic)
post_in_same_topic = Fabricate(:post, topic: topic)

get "/assign/members/#{get_assigned_allowed_group_name}.json"
expect(response.status).to eq(200)
expect(JSON.parse(response.body)["members"].map { |m| m["id"] }).to match_array(
[user.id, user2.id],
Fabricate(:post_assignment, assigned_to: user, target: topic, assigned_by_user: user)
Fabricate(
:topic_assignment,
assigned_to: user,
target: post_in_same_topic,
assigned_by_user: user,
)
Fabricate(:topic_assignment, assigned_to: user2, assigned_by_user: user)
Fabricate(:topic_assignment, assigned_to: user, assigned_by_user: user)

Fabricate(:topic_assignment, assigned_to: assign_allowed_group, assigned_by_user: user)
Fabricate(:post_assignment, assigned_to: assign_allowed_group, assigned_by_user: user)
end

it "doesn't include members with no assignments" do
sign_in(user)
add_to_assign_allowed_group(non_admin)
describe "members" do
describe "without filter" do
it "list members ordered by the number of assignments" do
sign_in(user)

get "/assign/members/#{get_assigned_allowed_group_name}.json"
expect(response.status).to eq(200)
expect(JSON.parse(response.body)["members"].map { |m| m["id"] }).to match_array(
[user.id, user2.id],
)
get "/assign/members/#{get_assigned_allowed_group_name}.json"
members = JSON.parse(response.body)["members"]

expect(response.status).to eq(200)
expect(members[0]).to include({ "id" => user.id, "assignments_count" => 3 })
expect(members[1]).to include({ "id" => user2.id, "assignments_count" => 1 })
end

it "doesn't include members with no assignments" do
sign_in(user)
add_to_assign_allowed_group(non_admin)

get "/assign/members/#{get_assigned_allowed_group_name}.json"
expect(response.status).to eq(200)
expect(JSON.parse(response.body)["members"].map { |m| m["id"] }).to_not include(
non_admin.id,
)
end
end

describe "with filter" do
it "returns members as according to filter" do
sign_in(user)

get "/assign/members/#{get_assigned_allowed_group_name}.json", params: { filter: "a" }
expect(response.status).to eq(200)
expect(JSON.parse(response.body)["members"].map { |m| m["id"] }).to match_array(
[user.id, user2.id],
)

get "/assign/members/#{get_assigned_allowed_group_name}.json", params: { filter: "david" }
expect(response.status).to eq(200)
expect(JSON.parse(response.body)["members"].map { |m| m["id"] }).to match_array(
[user2.id],
)

get "/assign/members/#{get_assigned_allowed_group_name}.json",
params: {
filter: "Taylor",
}
expect(response.status).to eq(200)
expect(JSON.parse(response.body)["members"].map { |m| m["id"] }).to match_array(
[user2.id],
)
end
end
end

it "returns members as according to filter" do
sign_in(user)
describe "assignment_count" do
it "returns the total number of assignments for group users and the group" do
sign_in(user)

get "/assign/members/#{get_assigned_allowed_group_name}.json", params: { filter: "a" }
expect(response.status).to eq(200)
expect(JSON.parse(response.body)["members"].map { |m| m["id"] }).to match_array(
[user.id, user2.id],
)
get "/assign/members/#{get_assigned_allowed_group_name}.json"

get "/assign/members/#{get_assigned_allowed_group_name}.json", params: { filter: "david" }
expect(response.status).to eq(200)
expect(JSON.parse(response.body)["members"].map { |m| m["id"] }).to match_array([user2.id])
expect(JSON.parse(response.body)["assignment_count"]).to eq(6)
end
end

get "/assign/members/#{get_assigned_allowed_group_name}.json", params: { filter: "Taylor" }
expect(response.status).to eq(200)
expect(JSON.parse(response.body)["members"].map { |m| m["id"] }).to match_array([user2.id])
describe "group_assignment_count" do
it "returns the number of assignments assigned to the group" do
sign_in(user)

get "/assign/members/#{get_assigned_allowed_group_name}.json"

expect(JSON.parse(response.body)["group_assignment_count"]).to eq(2)
end
end

it "404 error to non-group-members" do
Expand Down