Skip to content

Commit 94ee01f

Browse files
Fix: Strata and substrata are not duplicated (#28)
* Duplication is added for strata and substrata * Fix rubocop ci * Fix lints
1 parent ccc6954 commit 94ee01f

File tree

2 files changed

+126
-1
lines changed

2 files changed

+126
-1
lines changed

app/commands/decidim/stratified_sortitions/admin/duplicate_stratified_sortition.rb

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,31 @@ def duplicate_stratified_sortition
4141
current_user,
4242
) do
4343
@duplicated_stratified_sortition = stratified_sortition.dup
44-
@duplicated_stratified_sortition.save!
44+
@duplicated_stratified_sortition.status = :pending
45+
if @duplicated_stratified_sortition.save!
46+
duplicate_strata
47+
@duplicated_stratified_sortition
48+
else
49+
broadcast(:invalid)
50+
end
51+
end
52+
end
53+
54+
def duplicate_strata
55+
stratified_sortition.strata.order(:position).each do |stratum|
56+
new_stratum = stratum.dup
57+
new_stratum.decidim_stratified_sortition_id = @duplicated_stratified_sortition.id
58+
new_stratum.save!
59+
60+
duplicate_substrata(stratum, new_stratum)
61+
end
62+
end
63+
64+
def duplicate_substrata(stratum, new_stratum)
65+
stratum.substrata.order(:position).each do |substratum|
66+
new_substratum = substratum.dup
67+
new_substratum.decidim_stratified_sortitions_stratum_id = new_stratum.id
68+
new_substratum.save!
4569
end
4670
end
4771
end

spec/commands/decidim/sortitions/admin/duplicate_stratified_sortition_spec.rb

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,13 @@ module Admin
2929
expect(duplicated.component).to eq(stratified_sortition.component)
3030
end
3131

32+
it "sets the duplicated sortition status to pending" do
33+
command.call
34+
duplicated = Decidim::StratifiedSortitions::StratifiedSortition.last
35+
36+
expect(duplicated.status).to eq("pending")
37+
end
38+
3239
it "traces the action, versioning: true" do
3340
expect(Decidim.traceability)
3441
.to receive(:perform_action!)
@@ -39,6 +46,100 @@ module Admin
3946
action_log = Decidim::ActionLog.last
4047
expect(action_log.action).to eq("duplicate")
4148
end
49+
50+
context "when the sortition has strata and substrata" do
51+
let!(:stratum_1) { create(:stratum, stratified_sortition:, position: 0, name: { en: "Gender" }, kind: "value") }
52+
let!(:stratum_2) { create(:stratum, stratified_sortition:, position: 1, name: { en: "Age" }, kind: "numeric_range") }
53+
let!(:substratum_1a) { create(:substratum, stratum: stratum_1, position: 0, name: { en: "Male" }, value: { en: "M" }, max_quota_percentage: "60") }
54+
let!(:substratum_1b) { create(:substratum, stratum: stratum_1, position: 1, name: { en: "Female" }, value: { en: "F" }, max_quota_percentage: "60") }
55+
let!(:substratum_2a) { create(:substratum, stratum: stratum_2, position: 0, name: { en: "18-30" }, range: "18-30", max_quota_percentage: "50") }
56+
57+
it "duplicates all strata" do
58+
expect { command.call }.to change(Decidim::StratifiedSortitions::Stratum, :count).by(2)
59+
end
60+
61+
it "duplicates all substrata" do
62+
expect { command.call }.to change(Decidim::StratifiedSortitions::Substratum, :count).by(3)
63+
end
64+
65+
it "copies strata attributes and preserves position order" do
66+
command.call
67+
duplicated = Decidim::StratifiedSortitions::StratifiedSortition.last
68+
duplicated_strata = duplicated.strata.order(:position)
69+
70+
expect(duplicated_strata.size).to eq(2)
71+
expect(duplicated_strata[0].name).to eq(stratum_1.name)
72+
expect(duplicated_strata[0].kind).to eq(stratum_1.kind)
73+
expect(duplicated_strata[0].position).to eq(stratum_1.position)
74+
expect(duplicated_strata[1].name).to eq(stratum_2.name)
75+
expect(duplicated_strata[1].kind).to eq(stratum_2.kind)
76+
expect(duplicated_strata[1].position).to eq(stratum_2.position)
77+
end
78+
79+
it "copies substrata attributes and links them to the new strata" do
80+
command.call
81+
duplicated = Decidim::StratifiedSortitions::StratifiedSortition.last
82+
duplicated_strata = duplicated.strata.order(:position)
83+
84+
substrata_of_first = duplicated_strata[0].substrata.order(:position)
85+
expect(substrata_of_first.size).to eq(2)
86+
expect(substrata_of_first[0].name).to eq(substratum_1a.name)
87+
expect(substrata_of_first[0].value).to eq(substratum_1a.value)
88+
expect(substrata_of_first[0].max_quota_percentage).to eq(substratum_1a.max_quota_percentage)
89+
expect(substrata_of_first[0].position).to eq(substratum_1a.position)
90+
expect(substrata_of_first[1].name).to eq(substratum_1b.name)
91+
expect(substrata_of_first[1].position).to eq(substratum_1b.position)
92+
93+
substrata_of_second = duplicated_strata[1].substrata.order(:position)
94+
expect(substrata_of_second.size).to eq(1)
95+
expect(substrata_of_second[0].name).to eq(substratum_2a.name)
96+
expect(substrata_of_second[0].range).to eq(substratum_2a.range)
97+
expect(substrata_of_second[0].max_quota_percentage).to eq(substratum_2a.max_quota_percentage)
98+
end
99+
100+
it "does not modify the original strata" do
101+
expect { command.call }.not_to(change { stratified_sortition.strata.reload.count })
102+
end
103+
end
104+
105+
context "when the duplicated sortition fails to save" do
106+
let!(:stratum) { create(:stratum, stratified_sortition:, position: 0) }
107+
let!(:substratum) { create(:substratum, stratum:, position: 0) }
108+
109+
before do
110+
allow_any_instance_of(Decidim::StratifiedSortitions::StratifiedSortition).to receive(:dup).and_wrap_original do |method|
111+
duped = method.call
112+
allow(duped).to receive(:save!).and_raise(ActiveRecord::RecordInvalid)
113+
duped
114+
end
115+
end
116+
117+
it "raises an error" do
118+
expect { command.call }.to raise_error(ActiveRecord::RecordInvalid)
119+
end
120+
121+
it "does not create a new sortition" do
122+
expect do
123+
command.call
124+
rescue ActiveRecord::RecordInvalid
125+
nil
126+
end.not_to change(Decidim::StratifiedSortitions::StratifiedSortition, :count)
127+
end
128+
129+
it "does not duplicate strata or substrata" do
130+
expect do
131+
command.call
132+
rescue ActiveRecord::RecordInvalid
133+
nil
134+
end.not_to change(Decidim::StratifiedSortitions::Stratum, :count)
135+
136+
expect do
137+
command.call
138+
rescue ActiveRecord::RecordInvalid
139+
nil
140+
end.not_to change(Decidim::StratifiedSortitions::Substratum, :count)
141+
end
142+
end
42143
end
43144
end
44145
end

0 commit comments

Comments
 (0)