Skip to content

Commit ebf6d9d

Browse files
authored
Merge pull request #23841 from opf/impl/STC-847-multiple-versions-data
STC-847 Include work package associated versions model
2 parents c8a191d + d375c36 commit ebf6d9d

7 files changed

Lines changed: 187 additions & 0 deletions

File tree

app/models/version.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ class Version < ApplicationRecord
3434

3535
belongs_to :project
3636
has_many :work_packages, dependent: :nullify
37+
has_many :work_package_versions, dependent: :delete_all
38+
has_many :targeted_work_packages,
39+
-> { where(work_package_versions: { kind: "target" }) },
40+
through: :work_package_versions, source: :work_package
41+
has_many :observed_in_work_packages,
42+
-> { where(work_package_versions: { kind: "observed_in" }) },
43+
through: :work_package_versions, source: :work_package
3744
acts_as_customizable
3845

3946
VERSION_STATUSES = %w(open locked closed).freeze

app/models/work_package.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,14 @@ class WorkPackage < ApplicationRecord
6565
has_many :time_entries, dependent: :delete_all, inverse_of: :entity, as: :entity
6666
has_many :file_links, dependent: :delete_all, class_name: "Storages::FileLink", as: :container
6767
has_many :storages, through: :project
68+
has_many :work_package_versions, dependent: :delete_all
69+
has_many :versions, through: :work_package_versions, source: :version
70+
has_many :target_versions,
71+
-> { where(work_package_versions: { kind: "target" }) },
72+
through: :work_package_versions, source: :version
73+
has_many :observed_in_versions,
74+
-> { where(work_package_versions: { kind: "observed_in" }) },
75+
through: :work_package_versions, source: :version
6876

6977
has_and_belongs_to_many :changesets, -> { # rubocop:disable Rails/HasAndBelongsToMany
7078
order("#{Changeset.table_name}.committed_on ASC, #{Changeset.table_name}.id ASC")

app/models/work_package_version.rb

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# frozen_string_literal: true
2+
3+
#-- copyright
4+
# OpenProject is an open source project management software.
5+
# Copyright (C) the OpenProject GmbH
6+
#
7+
# This program is free software; you can redistribute it and/or
8+
# modify it under the terms of the GNU General Public License version 3.
9+
#
10+
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
11+
# Copyright (C) 2006-2013 Jean-Philippe Lang
12+
# Copyright (C) 2010-2013 the ChiliProject Team
13+
#
14+
# This program is free software; you can redistribute it and/or
15+
# modify it under the terms of the GNU General Public License
16+
# as published by the Free Software Foundation; either version 2
17+
# of the License, or (at your option) any later version.
18+
#
19+
# This program is distributed in the hope that it will be useful,
20+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
21+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22+
# GNU General Public License for more details.
23+
#
24+
# You should have received a copy of the GNU General Public License
25+
# along with this program; if not, write to the Free Software
26+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27+
#
28+
# See COPYRIGHT and LICENSE files for more details.
29+
#++
30+
31+
class WorkPackageVersion < ApplicationRecord
32+
enum :kind, { target: "target", observed_in: "observed_in" }, validate: true
33+
34+
belongs_to :work_package
35+
belongs_to :version
36+
end

config/locales/en.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2169,6 +2169,8 @@ en:
21692169
type: "Type"
21702170
version: "Version"
21712171
watcher: "Watcher"
2172+
work_package_version:
2173+
kind: "Kind"
21722174
ordered_persisted_query_entity:
21732175
persisted_query: "Persisted query"
21742176
entity: "Entity"
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# frozen_string_literal: true
2+
3+
#-- copyright
4+
# OpenProject is an open source project management software.
5+
# Copyright (C) the OpenProject GmbH
6+
#
7+
# This program is free software; you can redistribute it and/or
8+
# modify it under the terms of the GNU General Public License version 3.
9+
#
10+
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
11+
# Copyright (C) 2006-2013 Jean-Philippe Lang
12+
# Copyright (C) 2010-2013 the ChiliProject Team
13+
#
14+
# This program is free software; you can redistribute it and/or
15+
# modify it under the terms of the GNU General Public License
16+
# as published by the Free Software Foundation; either version 2
17+
# of the License, or (at your option) any later version.
18+
#
19+
# This program is distributed in the hope that it will be useful,
20+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
21+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22+
# GNU General Public License for more details.
23+
#
24+
# You should have received a copy of the GNU General Public License
25+
# along with this program; if not, write to the Free Software
26+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27+
#
28+
# See COPYRIGHT and LICENSE files for more details.
29+
#++
30+
31+
class CreateWorkPackageVersions < ActiveRecord::Migration[8.1]
32+
def change
33+
create_enum :work_package_version_kind, ["target", "observed_in"]
34+
35+
create_table :work_package_versions do |t|
36+
t.references :work_package, null: false, foreign_key: { on_delete: :cascade }, index: false
37+
t.references :version, null: false, foreign_key: { on_delete: :cascade }, index: false
38+
t.enum :kind, enum_type: :work_package_version_kind, null: false
39+
t.timestamps
40+
end
41+
42+
add_index :work_package_versions, %i[work_package_id version_id kind],
43+
unique: true,
44+
name: "idx_wp_versions_on_wp_version_kind"
45+
add_index :work_package_versions, :version_id,
46+
name: "idx_wp_versions_on_version"
47+
end
48+
end

spec/models/work_package_spec.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@
8484
it { is_expected.to have_many(:member_principals).through(:members).class_name("Principal").source(:principal) }
8585
it { is_expected.to have_many(:meeting_agenda_items) }
8686
it { is_expected.to have_many(:meetings).through(:meeting_agenda_items).source(:meeting) }
87+
it { is_expected.to have_many(:work_package_versions).dependent(:delete_all) }
88+
it { is_expected.to have_many(:versions).through(:work_package_versions).source(:version) }
89+
it { is_expected.to have_many(:target_versions).through(:work_package_versions).source(:version) }
90+
it { is_expected.to have_many(:observed_in_versions).through(:work_package_versions).source(:version) }
8791
end
8892

8993
describe ".new" do
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# frozen_string_literal: true
2+
3+
#-- copyright
4+
# OpenProject is an open source project management software.
5+
# Copyright (C) the OpenProject GmbH
6+
#
7+
# This program is free software; you can redistribute it and/or
8+
# modify it under the terms of the GNU General Public License version 3.
9+
#
10+
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
11+
# Copyright (C) 2006-2013 Jean-Philippe Lang
12+
# Copyright (C) 2010-2013 the ChiliProject Team
13+
#
14+
# This program is free software; you can redistribute it and/or
15+
# modify it under the terms of the GNU General Public License
16+
# as published by the Free Software Foundation; either version 2
17+
# of the License, or (at your option) any later version.
18+
#
19+
# This program is distributed in the hope that it will be useful,
20+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
21+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22+
# GNU General Public License for more details.
23+
#
24+
# You should have received a copy of the GNU General Public License
25+
# along with this program; if not, write to the Free Software
26+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
27+
#
28+
# See COPYRIGHT and LICENSE files for more details.
29+
#++
30+
31+
require "spec_helper"
32+
33+
RSpec.describe WorkPackageVersion do
34+
subject(:record) { described_class.new(work_package:, version:, kind: "target") }
35+
36+
let(:work_package) { create(:work_package) }
37+
let(:version) { create(:version, project: work_package.project) }
38+
39+
describe "associations" do
40+
it { is_expected.to belong_to(:work_package) }
41+
it { is_expected.to belong_to(:version) }
42+
end
43+
44+
describe "validations" do
45+
it { is_expected.to be_valid }
46+
47+
it "is invalid with an unknown kind" do
48+
record.kind = "unknown"
49+
expect(record).not_to be_valid
50+
expect(record.errors[:kind]).to be_present
51+
end
52+
53+
it do
54+
expect(subject).to define_enum_for(:kind)
55+
.with_values(target: "target", observed_in: "observed_in")
56+
.backed_by_column_of_type(:enum)
57+
end
58+
end
59+
60+
describe "kind scoping via through associations" do
61+
let(:other_version) { create(:version, project: work_package.project) }
62+
63+
before do
64+
described_class.create!(work_package:, version:, kind: "target")
65+
described_class.create!(work_package:, version: other_version, kind: "observed_in")
66+
end
67+
68+
it "target version appears in target_versions but not observed_in_versions" do
69+
expect(work_package.target_versions).to include(version)
70+
expect(work_package.observed_in_versions).not_to include(version)
71+
end
72+
73+
it "observed_in version appears in observed_in_versions but not target_versions" do
74+
expect(work_package.observed_in_versions).to include(other_version)
75+
expect(work_package.target_versions).not_to include(other_version)
76+
end
77+
78+
it "all versions appear in work_package.versions" do
79+
expect(work_package.versions).to include(version, other_version)
80+
end
81+
end
82+
end

0 commit comments

Comments
 (0)