Skip to content

Commit f509ac2

Browse files
committed
show version on the UI when duplicating wps
1 parent 548a403 commit f509ac2

5 files changed

Lines changed: 122 additions & 0 deletions

File tree

app/models/work_package/versions.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,19 @@ def assignable_versions(only_open: true)
141141
def override_target_versions? = !target_version_ids_replacements.nil?
142142
def override_observed_in_versions? = !observed_in_version_ids_replacements.nil?
143143

144+
# The target versions as they would be after saving: pending replacements
145+
# (in their requested order) take precedence over the persisted association.
146+
# The association itself only reflects replacements after
147+
# #persist_version_associations ran, so anything rendering unsaved state
148+
# (e.g. form payloads) has to read this instead.
149+
def effective_target_versions
150+
effective_versions(target_versions, target_version_ids_replacements)
151+
end
152+
153+
def effective_observed_in_versions
154+
effective_versions(observed_in_versions, observed_in_version_ids_replacements)
155+
end
156+
144157
# An override can also originate from the system, e.g. when versions that are
145158
# not shared with the (new) project are cleared on a project change. Such
146159
# overrides are marked here so that contracts don't attribute them to the
@@ -155,6 +168,13 @@ def system_version_override?(kind)
155168

156169
private
157170

171+
def effective_versions(association, replacement_ids)
172+
return association if replacement_ids.nil?
173+
174+
versions_by_id = Version.where(id: replacement_ids).index_by(&:id)
175+
replacement_ids.filter_map { |id| versions_by_id[id] }
176+
end
177+
158178
def system_version_overrides
159179
@system_version_overrides ||= Set.new
160180
end

lib/api/v3/work_packages/work_package_representer.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,24 @@ def self_v3_path(*)
584584
associated_resources :target_versions,
585585
v3_path: :version,
586586
representer: ::API::V3::Versions::VersionRepresenter,
587+
getter: ->(*) {
588+
next unless embed_link?(:target_versions)
589+
590+
represented.effective_target_versions.map do |version|
591+
::API::V3::Versions::VersionRepresenter.create(version, current_user:)
592+
end
593+
},
594+
link: ->(*) {
595+
represented.effective_target_versions.map do |version|
596+
::API::Decorators::LinkObject
597+
.new(version,
598+
property_name: :itself,
599+
path: :version,
600+
getter: :id,
601+
title_attribute: :name)
602+
.to_hash
603+
end
604+
},
587605
setter: ->(fragment:, **) do
588606
represented.target_version_ids = parse_link_ids_from_fragment(fragment, :version).compact
589607
end

spec/lib/api/v3/work_packages/work_package_representer_spec.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,32 @@
744744
.at_path("_embedded/targetVersions/0/name")
745745
end
746746
end
747+
748+
context "when versions are assigned but not yet persisted" do
749+
let!(:version) { create(:version, project: workspace) }
750+
let!(:other_version) { create(:version, project: workspace) }
751+
752+
before do
753+
work_package.target_version_ids_replacements = [other_version.id, version.id]
754+
end
755+
756+
it "renders the pending versions in their requested order" do
757+
expect(subject).to have_json_size(2).at_path("_links/targetVersions")
758+
expect(subject)
759+
.to be_json_eql(api_v3_paths.version(other_version.id).to_json)
760+
.at_path("_links/targetVersions/0/href")
761+
expect(subject)
762+
.to be_json_eql(api_v3_paths.version(version.id).to_json)
763+
.at_path("_links/targetVersions/1/href")
764+
end
765+
766+
it "embeds the pending versions" do
767+
expect(subject).to have_json_size(2).at_path("_embedded/targetVersions")
768+
expect(subject)
769+
.to be_json_eql(other_version.name.to_json)
770+
.at_path("_embedded/targetVersions/0/name")
771+
end
772+
end
747773
end
748774

749775
describe "project" do

spec/requests/api/v3/work_packages/create_form_resource_spec.rb

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,41 @@
110110
end
111111
end
112112

113+
describe "with targetVersions (e.g. when duplicating a work package)" do
114+
shared_let(:version) { create(:version, project:) }
115+
116+
let(:parameters) do
117+
{
118+
_links: {
119+
project: {
120+
href: "/api/v3/projects/#{project.id}"
121+
},
122+
version: {
123+
href: api_v3_paths.version(version.id)
124+
},
125+
targetVersions: [
126+
{ href: api_v3_paths.version(version.id) }
127+
]
128+
},
129+
subject: "lorem ipsum"
130+
}
131+
end
132+
133+
it "has 0 validation errors" do
134+
expect(subject.body).to have_json_size(0).at_path("_embedded/validationErrors")
135+
end
136+
137+
it "echoes the versions in the payload although they are not persisted yet" do
138+
expect(subject.body)
139+
.to be_json_eql(api_v3_paths.version(version.id).to_json)
140+
.at_path("_embedded/payload/_links/targetVersions/0/href")
141+
142+
expect(subject.body)
143+
.to be_json_eql(api_v3_paths.version(version.id).to_json)
144+
.at_path("_embedded/payload/_links/version/href")
145+
end
146+
end
147+
113148
describe "custom fields" do
114149
context "when the custom field is required" do
115150
shared_let(:required_custom_field) do

spec/requests/api/v3/work_packages/form/work_package_form_resource_spec.rb

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,29 @@
585585
end
586586
end
587587

588+
describe "targetVersions" do
589+
let(:path) { "_embedded/payload/_links/targetVersions" }
590+
let(:target_version) { create(:version, project:) }
591+
let(:version_parameter) do
592+
{ _links: { targetVersions: [{ href: api_v3_paths.version(target_version.id) }] } }
593+
end
594+
let(:params) { valid_params.merge(version_parameter) }
595+
596+
context "for a valid version" do
597+
include_context "with post request"
598+
599+
it_behaves_like "valid payload"
600+
601+
it_behaves_like "having no errors"
602+
603+
it "echoes the requested target versions although they are not persisted yet" do
604+
expect(subject.body)
605+
.to be_json_eql(api_v3_paths.version(target_version.id).to_json)
606+
.at_path("#{path}/0/href")
607+
end
608+
end
609+
end
610+
588611
describe "category" do
589612
let(:path) { "_embedded/payload/_links/category/href" }
590613
let(:links_path) { "_embedded/schema/category/_links" }

0 commit comments

Comments
 (0)