Skip to content

Commit bf5c5d6

Browse files
committed
backlog bucket for_project class method
1 parent d0c7495 commit bf5c5d6

2 files changed

Lines changed: 66 additions & 1 deletion

File tree

modules/backlogs/app/models/agile/backlog_bucket.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,15 @@ class Agile::BacklogBucket < ApplicationRecord
3737
scope :order_alphabetically, -> { order(:name) }
3838

3939
validates :name, :project, presence: true
40+
41+
def self.for_project(project)
42+
buckets = where(project:).order_alphabetically.includes(:work_packages)
43+
44+
inbox = new(
45+
name: I18n.t("label_inbox"),
46+
work_packages: WorkPackage.where(project:, sprint: nil, backlog_bucket: nil).order_by_position
47+
)
48+
49+
buckets + [inbox]
50+
end
4051
end

modules/backlogs/spec/models/agile/backlog_bucket_spec.rb

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
require "rails_helper"
3232

3333
RSpec.describe Agile::BacklogBucket do
34-
let(:project) { create(:project) }
34+
shared_let(:project) { create(:project) }
3535

3636
subject(:backlog_bucket) do
3737
described_class.new(name: "Bla Bla", project:)
@@ -79,4 +79,58 @@
7979
expect(described_class.order_alphabetically).to eq([bucket1, bucket2, bucket3])
8080
end
8181
end
82+
83+
describe ".for_project" do
84+
shared_let(:other_project) { create(:project) }
85+
86+
shared_let(:bucket2) { create(:backlog_bucket, project:, name: "2") }
87+
shared_let(:bucket1) { create(:backlog_bucket, project:, name: "1") }
88+
shared_let(:other_bucket) { create(:backlog_bucket, project: other_project) }
89+
90+
shared_let(:wp_nil_in_bucket1) do
91+
create(:work_package, project:, backlog_bucket: bucket1).tap { it.update_columns(position: nil) }
92+
end
93+
shared_let(:wp2_in_bucket1) { create(:work_package, project:, backlog_bucket: bucket1, position: 2) }
94+
shared_let(:wp1_in_bucket1_first) { create(:work_package, project:, backlog_bucket: bucket1, position: 1) }
95+
96+
shared_let(:wp_in_bucket2) { create(:work_package, project:, backlog_bucket: bucket2) }
97+
98+
shared_let(:wp_unbucketed_nil) do
99+
create(:work_package, project:, backlog_bucket: nil).tap { it.update_columns(position: nil) }
100+
end
101+
shared_let(:wp_unbucketed2) { create(:work_package, project:, backlog_bucket: nil, position: 2) }
102+
shared_let(:wp_unbucketed1) { create(:work_package, project:, backlog_bucket: nil, position: 1) }
103+
104+
shared_let(:wp_other_project) { create(:work_package, project: other_project, backlog_bucket: other_bucket) }
105+
shared_let(:wp_other_project_unbucketed) { create(:work_package, project: other_project, backlog_bucket: nil) }
106+
107+
subject(:result) { described_class.for_project(project) }
108+
109+
it "returns the project buckets followed by the inbox" do
110+
expect(result).to match([bucket1, bucket2, be_a(described_class).and(be_new_record)])
111+
end
112+
113+
it "does not include buckets from other projects" do
114+
expect(result).not_to include(other_bucket)
115+
end
116+
117+
it "appends an unsaved inbox bucket at the end" do
118+
inbox = result.last
119+
expect(inbox).to be_a(described_class)
120+
expect(inbox).to be_new_record
121+
expect(inbox).to have_attributes(name: I18n.t("label_inbox"))
122+
end
123+
124+
it "inbox contains only unbucketed work packages from the project" do
125+
expect(result.last.work_packages).to contain_exactly(wp_unbucketed2, wp_unbucketed1, wp_unbucketed_nil)
126+
end
127+
128+
it "orders work packages within a bucket by position, with nil position last" do
129+
expect(bucket1.work_packages.reload).to eq([wp1_in_bucket1_first, wp2_in_bucket1, wp_nil_in_bucket1])
130+
end
131+
132+
it "orders inbox work packages by position, with nil position last" do
133+
expect(result.last.work_packages.to_a).to eq([wp_unbucketed1, wp_unbucketed2, wp_unbucketed_nil])
134+
end
135+
end
82136
end

0 commit comments

Comments
 (0)