-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #16884 from opf/implementation/58105-item-persiste…
…nce-service Implementation/58105 item persistence service
- Loading branch information
Showing
9 changed files
with
626 additions
and
0 deletions.
There are no files selected for viewing
43 changes: 43 additions & 0 deletions
43
app/contracts/custom_fields/hierarchy/generate_root_contract.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
# frozen_string_literal: true | ||
|
||
#-- copyright | ||
# OpenProject is an open source project management software. | ||
# Copyright (C) the OpenProject GmbH | ||
# | ||
# This program is free software; you can redistribute it and/or | ||
# modify it under the terms of the GNU General Public License version 3. | ||
# | ||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: | ||
# Copyright (C) 2006-2013 Jean-Philippe Lang | ||
# Copyright (C) 2010-2013 the ChiliProject Team | ||
# | ||
# This program is free software; you can redistribute it and/or | ||
# modify it under the terms of the GNU General Public License | ||
# as published by the Free Software Foundation; either version 2 | ||
# of the License, or (at your option) any later version. | ||
# | ||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU General Public License | ||
# along with this program; if not, write to the Free Software | ||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
# | ||
# See COPYRIGHT and LICENSE files for more details. | ||
#++ | ||
|
||
module CustomFields | ||
module Hierarchy | ||
class GenerateRootContract < Dry::Validation::Contract | ||
params do | ||
required(:hierarchy_root) | ||
end | ||
|
||
rule(:hierarchy_root) do | ||
key.failure("Hierarchical root already set") unless value.nil? | ||
end | ||
end | ||
end | ||
end |
57 changes: 57 additions & 0 deletions
57
app/contracts/custom_fields/hierarchy/insert_item_contract.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# frozen_string_literal: true | ||
|
||
#-- copyright | ||
# OpenProject is an open source project management software. | ||
# Copyright (C) the OpenProject GmbH | ||
# | ||
# This program is free software; you can redistribute it and/or | ||
# modify it under the terms of the GNU General Public License version 3. | ||
# | ||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: | ||
# Copyright (C) 2006-2013 Jean-Philippe Lang | ||
# Copyright (C) 2010-2013 the ChiliProject Team | ||
# | ||
# This program is free software; you can redistribute it and/or | ||
# modify it under the terms of the GNU General Public License | ||
# as published by the Free Software Foundation; either version 2 | ||
# of the License, or (at your option) any later version. | ||
# | ||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU General Public License | ||
# along with this program; if not, write to the Free Software | ||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
# | ||
# See COPYRIGHT and LICENSE files for more details. | ||
#++ | ||
|
||
module CustomFields | ||
module Hierarchy | ||
class InsertItemContract < Dry::Validation::Contract | ||
params do | ||
required(:parent).filled | ||
required(:label).filled(:string) | ||
optional(:short).filled(:string) | ||
end | ||
|
||
rule(:parent) do | ||
if value.is_a?(CustomField::Hierarchy::Item) | ||
unless value.persisted? | ||
key.failure("Parent must exist") | ||
end | ||
else | ||
key.failure("Parent must be of type 'Item'") | ||
end | ||
end | ||
|
||
rule(:label) do | ||
if CustomField::Hierarchy::Item.exists?(parent_id: values[:parent], label: value) | ||
key.failure("Label must be unique within the same hierarchy level") | ||
end | ||
end | ||
end | ||
end | ||
end |
43 changes: 43 additions & 0 deletions
43
app/contracts/custom_fields/hierarchy/service_initialization_contract.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
# frozen_string_literal: true | ||
|
||
#-- copyright | ||
# OpenProject is an open source project management software. | ||
# Copyright (C) the OpenProject GmbH | ||
# | ||
# This program is free software; you can redistribute it and/or | ||
# modify it under the terms of the GNU General Public License version 3. | ||
# | ||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: | ||
# Copyright (C) 2006-2013 Jean-Philippe Lang | ||
# Copyright (C) 2010-2013 the ChiliProject Team | ||
# | ||
# This program is free software; you can redistribute it and/or | ||
# modify it under the terms of the GNU General Public License | ||
# as published by the Free Software Foundation; either version 2 | ||
# of the License, or (at your option) any later version. | ||
# | ||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU General Public License | ||
# along with this program; if not, write to the Free Software | ||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
# | ||
# See COPYRIGHT and LICENSE files for more details. | ||
#++ | ||
|
||
module CustomFields | ||
module Hierarchy | ||
class ServiceInitializationContract < Dry::Validation::Contract | ||
params do | ||
required(:field_format).filled(:string) | ||
end | ||
|
||
rule(:field_format) do | ||
key.failure("Custom field must have field format 'hierarchy'") if value != "hierarchy" | ||
end | ||
end | ||
end | ||
end |
79 changes: 79 additions & 0 deletions
79
app/services/custom_fields/hierarchy/hierarchical_item_service.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
# frozen_string_literal: true | ||
|
||
#-- copyright | ||
# OpenProject is an open source project management software. | ||
# Copyright (C) the OpenProject GmbH | ||
# | ||
# This program is free software; you can redistribute it and/or | ||
# modify it under the terms of the GNU General Public License version 3. | ||
# | ||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: | ||
# Copyright (C) 2006-2013 Jean-Philippe Lang | ||
# Copyright (C) 2010-2013 the ChiliProject Team | ||
# | ||
# This program is free software; you can redistribute it and/or | ||
# modify it under the terms of the GNU General Public License | ||
# as published by the Free Software Foundation; either version 2 | ||
# of the License, or (at your option) any later version. | ||
# | ||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU General Public License | ||
# along with this program; if not, write to the Free Software | ||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
# | ||
# See COPYRIGHT and LICENSE files for more details. | ||
#++ | ||
|
||
module CustomFields | ||
module Hierarchy | ||
class HierarchicalItemService | ||
include Dry::Monads[:result] | ||
|
||
def initialize(custom_field) | ||
validation = ServiceInitializationContract.new.call(field_format: custom_field.field_format) | ||
# rubocop:disable Rails/DeprecatedActiveModelErrorsMethods | ||
raise ArgumentError, "Invalid custom field: #{validation.errors.to_h}" if validation.failure? | ||
# rubocop:enable Rails/DeprecatedActiveModelErrorsMethods | ||
|
||
@custom_field = custom_field | ||
end | ||
|
||
def generate_root | ||
CustomFields::Hierarchy::GenerateRootContract | ||
.new | ||
.call(hierarchy_root: @custom_field.hierarchy_root) | ||
.to_monad | ||
.bind { create_root_item } | ||
end | ||
|
||
def insert_item(parent:, label:, short: nil) | ||
CustomFields::Hierarchy::InsertItemContract | ||
.new | ||
.call({ parent:, label:, short: }.compact) | ||
.to_monad | ||
.bind { |validation| create_child_item(validation) } | ||
end | ||
|
||
private | ||
|
||
def create_root_item | ||
item = CustomField::Hierarchy::Item.create(custom_field: @custom_field) | ||
return Failure(item.errors) unless item.persisted? | ||
|
||
Success(item) | ||
end | ||
|
||
def create_child_item(validation) | ||
item = CustomField::Hierarchy::Item | ||
.create(parent: validation[:parent], label: validation[:label], short: validation[:short]) | ||
return Failure(item.errors) unless item.persisted? | ||
|
||
Success(item) | ||
end | ||
end | ||
end | ||
end |
78 changes: 78 additions & 0 deletions
78
spec/contracts/custom_fields/hierarchy/generate_root_contract_spec.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
# frozen_string_literal: true | ||
|
||
#-- copyright | ||
# OpenProject is an open source project management software. | ||
# Copyright (C) the OpenProject GmbH | ||
# | ||
# This program is free software; you can redistribute it and/or | ||
# modify it under the terms of the GNU General Public License version 3. | ||
# | ||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: | ||
# Copyright (C) 2006-2013 Jean-Philippe Lang | ||
# Copyright (C) 2010-2013 the ChiliProject Team | ||
# | ||
# This program is free software; you can redistribute it and/or | ||
# modify it under the terms of the GNU General Public License | ||
# as published by the Free Software Foundation; either version 2 | ||
# of the License, or (at your option) any later version. | ||
# | ||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU General Public License | ||
# along with this program; if not, write to the Free Software | ||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
# | ||
# See COPYRIGHT and LICENSE files for more details. | ||
#++ | ||
|
||
require "rails_helper" | ||
|
||
RSpec.describe CustomFields::Hierarchy::GenerateRootContract do | ||
subject { described_class.new } | ||
|
||
describe "#call" do | ||
context "when hierarchy_root is nil" do | ||
let(:custom_field) { create(:custom_field, field_format: "hierarchy", hierarchy_root: nil) } | ||
|
||
it "is valid" do | ||
result = subject.call(hierarchy_root: custom_field.hierarchy_root) | ||
expect(result).to be_success | ||
end | ||
end | ||
|
||
context "when hierarchy_root is not nil" do | ||
let(:hierarchy_root) { create(:hierarchy_item) } | ||
let(:custom_field) { create(:custom_field, field_format: "hierarchy", hierarchy_root:) } | ||
|
||
it "is invalid" do | ||
result = subject.call(hierarchy_root: custom_field.hierarchy_root) | ||
expect(result).to be_failure | ||
# rubocop:disable Rails/DeprecatedActiveModelErrorsMethods | ||
expect(result.errors.to_h).to include(hierarchy_root: ["Hierarchical root already set"]) | ||
# rubocop:enable Rails/DeprecatedActiveModelErrorsMethods | ||
end | ||
end | ||
|
||
context "when inputs are valid" do | ||
it "creates a success result" do | ||
[ | ||
{ hierarchy_root: nil } | ||
].each { |params| expect(subject.call(params)).to be_success } | ||
end | ||
end | ||
|
||
context "when inputs are invalid" do | ||
it "creates a failure result" do | ||
[ | ||
{}, | ||
{ hierarchy_root: create(:hierarchy_item) }, | ||
{ hierarchy_root: "" }, | ||
{ hierarchy_root: 42 } | ||
].each { |params| expect(subject.call(params)).to be_failure } | ||
end | ||
end | ||
end | ||
end |
Oops, something went wrong.