mirror of
https://github.com/opf/openproject.git
synced 2026-06-14 03:30:14 +00:00
[#38833] BCF API Comments Service
- https://community.openproject.org/work_packages/38833 - added requests tests - added check for expected body length - added representer and api for bcf_comments - added create and set attributes service for bcf_comments - added migration for comment hierarchy - added create and update service for journals
This commit is contained in:
@@ -100,6 +100,10 @@ Naming/AccessorMethodName:
|
||||
Naming/AsciiIdentifiers:
|
||||
Enabled: false
|
||||
|
||||
Naming/ClassAndModuleCamelCase:
|
||||
AllowedNames:
|
||||
- V2_1
|
||||
|
||||
Naming/FileName:
|
||||
Enabled: false
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 Journals
|
||||
class UpdateContract < BaseContract
|
||||
attribute :notes
|
||||
|
||||
validate :user_allowed_to_edit
|
||||
|
||||
private
|
||||
|
||||
def user_allowed_to_edit
|
||||
errors.add(:base, :error_unauthorized) unless model.editable_by?(user)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -28,8 +28,6 @@
|
||||
# See COPYRIGHT and LICENSE files for more details.
|
||||
#++
|
||||
|
||||
require 'work_packages/base_contract'
|
||||
|
||||
module WorkPackages
|
||||
class UpdateContract < BaseContract
|
||||
include UnchangedProject
|
||||
|
||||
@@ -1,3 +1,33 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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.
|
||||
#++
|
||||
|
||||
# Will create journals for a journable (e.g. WorkPackage and Meeting)
|
||||
# As a journal is basically a copy of the current state of the database, consisting of the journable as well as its
|
||||
# custom values and attachments, those entries are copied in the database.
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 Journals
|
||||
class SetAttributesService < ::BaseServices::SetAttributes; end
|
||||
end
|
||||
@@ -0,0 +1,33 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 Journals
|
||||
class UpdateService < ::BaseServices::Update; end
|
||||
end
|
||||
@@ -0,0 +1,6 @@
|
||||
class AddBcfCommentHierarchy < ActiveRecord::Migration[6.1]
|
||||
def change
|
||||
add_column :bcf_comments, :reply_to, :bigint, default: nil, null: true
|
||||
add_foreign_key :bcf_comments, :bcf_comments, column: :reply_to, on_delete: :nullify
|
||||
end
|
||||
end
|
||||
@@ -26,8 +26,6 @@
|
||||
# See COPYRIGHT and LICENSE files for more details.
|
||||
#++
|
||||
|
||||
require 'api/v3/activities/activity_representer'
|
||||
|
||||
module API
|
||||
module V3
|
||||
module Activities
|
||||
@@ -42,18 +40,6 @@ module API
|
||||
end
|
||||
end
|
||||
|
||||
helpers do
|
||||
def save_activity(activity)
|
||||
unless activity.save
|
||||
fail ::API::Errors::ErrorBase.create_and_merge_errors(activity.errors)
|
||||
end
|
||||
end
|
||||
|
||||
def authorize_edit_own(activity)
|
||||
authorize_by_with_raise activity.editable_by?(current_user)
|
||||
end
|
||||
end
|
||||
|
||||
get &::API::V3::Utilities::Endpoints::Show.new(model: ::Journal,
|
||||
api_name: 'Activity',
|
||||
instance_generator: ->(*) { @activity })
|
||||
@@ -63,14 +49,13 @@ module API
|
||||
requires :comment, type: String
|
||||
end
|
||||
|
||||
patch do
|
||||
# TODO: Write a journal update notes service and mount default endpoint
|
||||
authorize_edit_own(@activity)
|
||||
@activity.notes = declared_params[:comment]
|
||||
save_activity(@activity)
|
||||
|
||||
ActivityRepresenter.new(@activity, current_user: current_user)
|
||||
end
|
||||
patch &::API::V3::Utilities::Endpoints::Update.new(model: ::Journal,
|
||||
api_name: 'Activity',
|
||||
instance_generator: ->(*) { @activity },
|
||||
params_modifier: ->(*) {
|
||||
{ notes: declared_params[:comment] }
|
||||
})
|
||||
.mount
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 API
|
||||
module V3
|
||||
module Activities
|
||||
class ActivityPayloadRepresenter < ::API::V3::Activities::ActivityRepresenter
|
||||
include API::Utilities::PayloadRepresenter
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,61 @@
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 Bim::Bcf
|
||||
module Comments
|
||||
class CreateContract < BaseContract
|
||||
attribute :journal
|
||||
attribute :issue
|
||||
attribute :viewpoint
|
||||
attribute :reply_to
|
||||
|
||||
validate :user_allowed_to_create
|
||||
validate :validate_journal
|
||||
validate :validate_viewpoint_reference
|
||||
validate :validate_reply_to_comment
|
||||
|
||||
private
|
||||
|
||||
def user_allowed_to_create
|
||||
errors.add :base, :error_unauthorized unless @user.allowed_to?(:manage_bcf, model.issue.work_package.project)
|
||||
end
|
||||
|
||||
def validate_journal
|
||||
errors.add(:base, :invalid) if model.journal.journable != model.issue.work_package
|
||||
end
|
||||
|
||||
def validate_viewpoint_reference
|
||||
errors.add(:viewpoint, :does_not_exist) if model.viewpoint.is_a?(::Bim::Bcf::NonExistentViewpoint)
|
||||
end
|
||||
|
||||
def validate_reply_to_comment
|
||||
errors.add(:bcf_comment, :does_not_exist) if model.reply_to.is_a?(::Bim::Bcf::NonExistentComment)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,54 @@
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 Bim::Bcf
|
||||
module Comments
|
||||
class UpdateContract < BaseContract
|
||||
attribute :viewpoint
|
||||
attribute :reply_to
|
||||
|
||||
validate :user_allowed_to_update
|
||||
validate :validate_viewpoint_reference
|
||||
validate :validate_reply_to_comment
|
||||
|
||||
private
|
||||
|
||||
def user_allowed_to_update
|
||||
errors.add :base, :error_unauthorized unless @user.allowed_to?(:manage_bcf, model.issue.work_package.project)
|
||||
end
|
||||
|
||||
def validate_viewpoint_reference
|
||||
errors.add(:viewpoint, :does_not_exist) if model.viewpoint.is_a?(::Bim::Bcf::NonExistentViewpoint)
|
||||
end
|
||||
|
||||
def validate_reply_to_comment
|
||||
errors.add(:bcf_comment, :does_not_exist) if model.reply_to.is_a?(::Bim::Bcf::NonExistentComment)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -104,7 +104,7 @@ module Bim::Bcf
|
||||
end
|
||||
|
||||
def validate_json_viewpoint_present
|
||||
errors.add(:json_viewpoint, :blank) unless viewpoint.present?
|
||||
errors.add(:json_viewpoint, :blank) if viewpoint.blank?
|
||||
end
|
||||
|
||||
def validate_json_viewpoint_hash
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 Bim::Bcf::API::V2_1
|
||||
module Comments
|
||||
class API < ::API::OpenProjectAPI
|
||||
resources :comments do
|
||||
helpers do
|
||||
def all_comments
|
||||
@issue.comments.includes(:journal, :issue, :viewpoint)
|
||||
end
|
||||
|
||||
def transform_create_parameter(params)
|
||||
viewpoint = if params[:viewpoint_guid] == nil
|
||||
nil
|
||||
else
|
||||
@issue.viewpoints
|
||||
.find_by(uuid: params[:viewpoint_guid]) || ::Bim::Bcf::NonExistentViewpoint.new
|
||||
end
|
||||
replied_comment = if params[:reply_to_comment_guid] == nil
|
||||
nil
|
||||
else
|
||||
@issue.comments
|
||||
.find_by(uuid: params[:reply_to_comment_guid]) || ::Bim::Bcf::NonExistentComment.new
|
||||
end
|
||||
{
|
||||
issue: @issue,
|
||||
viewpoint: viewpoint,
|
||||
reply_to: replied_comment
|
||||
}
|
||||
end
|
||||
|
||||
def transform_update_parameter(params)
|
||||
viewpoint = if params[:viewpoint_guid] == nil
|
||||
nil
|
||||
else
|
||||
@issue.viewpoints
|
||||
.find_by(uuid: params[:viewpoint_guid]) || ::Bim::Bcf::NonExistentViewpoint.new
|
||||
end
|
||||
replied_comment = if params[:reply_to_comment_guid] == nil
|
||||
nil
|
||||
else
|
||||
@issue.comments
|
||||
.find_by(uuid: params[:reply_to_comment_guid]) || ::Bim::Bcf::NonExistentComment.new
|
||||
end
|
||||
|
||||
{
|
||||
original_comment: @comment,
|
||||
viewpoint: viewpoint,
|
||||
reply_to: replied_comment
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
get &::Bim::Bcf::API::V2_1::Endpoints::Index.new(model: Bim::Bcf::Comment, scope: -> { all_comments }).mount
|
||||
|
||||
post &::Bim::Bcf::API::V2_1::Endpoints::Create
|
||||
.new(model: Bim::Bcf::Comment,
|
||||
params_modifier: ->(params) { transform_create_parameter(params).merge(params) })
|
||||
.mount
|
||||
|
||||
route_param :comment_guid, regexp: /\A[a-f0-9\-]+\z/ do
|
||||
after_validation do
|
||||
@comment = all_comments.find_by!(uuid: params[:comment_guid])
|
||||
end
|
||||
|
||||
get &::Bim::Bcf::API::V2_1::Endpoints::Show.new(model: Bim::Bcf::Comment).mount
|
||||
|
||||
put &::Bim::Bcf::API::V2_1::Endpoints::Update
|
||||
.new(model: Bim::Bcf::Comment,
|
||||
params_modifier: ->(params) { transform_update_parameter(params).merge(params) })
|
||||
.mount
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -28,7 +28,9 @@
|
||||
# See COPYRIGHT and LICENSE files for more details.
|
||||
#++
|
||||
|
||||
# rubocop:disable Naming/ClassAndModuleCamelCase
|
||||
module Bim::Bcf::API::V2_1
|
||||
# rubocop:enable Naming/ClassAndModuleCamelCase
|
||||
class ProjectsAPI < ::API::OpenProjectAPI
|
||||
resources :projects do
|
||||
helpers do
|
||||
|
||||
@@ -28,7 +28,9 @@
|
||||
# See COPYRIGHT and LICENSE files for more details.
|
||||
#++
|
||||
|
||||
# rubocop:disable Naming/ClassAndModuleCamelCase
|
||||
module Bim::Bcf::API::V2_1
|
||||
# rubocop:enable Naming/ClassAndModuleCamelCase
|
||||
class TopicsAPI < ::API::OpenProjectAPI
|
||||
resources :topics do
|
||||
helpers do
|
||||
@@ -85,7 +87,7 @@ module Bim::Bcf::API::V2_1
|
||||
|
||||
route_param :topic_uuid, regexp: /\A[a-f0-9\-]+\z/ do
|
||||
after_validation do
|
||||
@issue = topics.find_by_uuid!(params[:topic_uuid])
|
||||
@issue = topics.find_by!(uuid: params[:topic_uuid])
|
||||
end
|
||||
|
||||
get &::Bim::Bcf::API::V2_1::Endpoints::Show
|
||||
@@ -108,6 +110,7 @@ module Bim::Bcf::API::V2_1
|
||||
.mount
|
||||
|
||||
mount ::Bim::Bcf::API::V2_1::Viewpoints::API
|
||||
mount ::Bim::Bcf::API::V2_1::Comments::API
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,18 +1,50 @@
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 Bim::Bcf
|
||||
class Comment < ActiveRecord::Base
|
||||
self.table_name = :bcf_comments
|
||||
|
||||
include InitializeWithUuid
|
||||
|
||||
CREATE_ATTRIBUTES = %i[journal issue viewpoint reply_to].freeze
|
||||
UPDATE_ATTRIBUTES = %i[viewpoint reply_to].freeze
|
||||
|
||||
belongs_to :journal
|
||||
belongs_to :issue, foreign_key: :issue_id, class_name: "Bim::Bcf::Issue"
|
||||
belongs_to :viewpoint, foreign_key: :viewpoint_id, class_name: "Bim::Bcf::Viewpoint", optional: true
|
||||
belongs_to :reply_to, foreign_key: :reply_to, class_name: "Bim::Bcf::Comment", optional: true
|
||||
|
||||
validates_presence_of :uuid
|
||||
validates_uniqueness_of :uuid, scope: [:issue_id]
|
||||
|
||||
def self.has_uuid?(uuid, issue_id)
|
||||
where(uuid: uuid, issue_id: issue_id).exists?
|
||||
exists?(uuid: uuid, issue_id: issue_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
module Bim::Bcf
|
||||
class NonExistentComment < Comment
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,4 @@
|
||||
module Bim::Bcf
|
||||
class NonExistentViewpoint < Viewpoint
|
||||
end
|
||||
end
|
||||
@@ -33,5 +33,9 @@ module Bim::Bcf::API::V2_1
|
||||
include Representable::JSON
|
||||
|
||||
defaults render_nil: true
|
||||
|
||||
def datetime_formatter
|
||||
::API::V3::Utilities::DateTimeFormatter
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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.
|
||||
#++
|
||||
|
||||
# rubocop:disable Naming/ClassAndModuleCamelCase
|
||||
module Bim::Bcf::API::V2_1
|
||||
# rubocop:enable Naming/ClassAndModuleCamelCase
|
||||
class Comments::AuthorizationRepresenter < BaseRepresenter
|
||||
property :comment_actions,
|
||||
getter: ->(decorator:, **) {
|
||||
if decorator.manage_bcf_allowed?
|
||||
%w[update]
|
||||
else
|
||||
[]
|
||||
end
|
||||
}
|
||||
|
||||
def manage_bcf_allowed?
|
||||
represented.user.allowed_to?(:manage_bcf, represented.model.project)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,88 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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.
|
||||
#++
|
||||
|
||||
# rubocop:disable Naming/ClassAndModuleCamelCase
|
||||
module Bim::Bcf::API::V2_1
|
||||
# rubocop:enable Naming/ClassAndModuleCamelCase
|
||||
class Comments::SingleRepresenter < BaseRepresenter
|
||||
include API::Decorators::DateProperty
|
||||
|
||||
property :uuid,
|
||||
as: :guid
|
||||
|
||||
property :date,
|
||||
getter: ->(represented:, decorator:, **) {
|
||||
decorator.datetime_formatter.format_datetime(represented.journal.created_at, allow_nil: true)
|
||||
}
|
||||
|
||||
property :author,
|
||||
getter: ->(represented:, **) {
|
||||
represented.journal.user.mail
|
||||
}
|
||||
|
||||
property :comment,
|
||||
getter: ->(represented:, **) {
|
||||
represented.journal.notes
|
||||
}
|
||||
|
||||
property :topic_guid,
|
||||
getter: ->(represented:, **) {
|
||||
represented.issue.uuid
|
||||
}
|
||||
|
||||
# not required properties
|
||||
property :viewpoint_guid,
|
||||
getter: ->(represented:, **) {
|
||||
represented.viewpoint&.uuid
|
||||
}
|
||||
|
||||
property :reply_to_comment_guid,
|
||||
getter: ->(represented:, **) {
|
||||
represented.reply_to&.uuid
|
||||
}
|
||||
|
||||
property :modified_date,
|
||||
getter: ->(represented:, decorator:, **) {
|
||||
decorator.datetime_formatter.format_datetime(represented.journal.updated_at, allow_nil: true)
|
||||
}
|
||||
|
||||
# we do not store the author when editing a journal, hence the "modified author" is the same as the creator
|
||||
property :modified_author,
|
||||
getter: ->(represented:, **) {
|
||||
represented.journal.user.mail
|
||||
}
|
||||
|
||||
property :authorization,
|
||||
getter: ->(represented:, **) {
|
||||
contract = WorkPackages::UpdateContract.new(represented.issue.work_package, User.current)
|
||||
Comments::AuthorizationRepresenter.new(contract)
|
||||
}
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,52 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 Bim::Bcf
|
||||
module Comments
|
||||
class CreateService < ::BaseServices::Create
|
||||
private
|
||||
|
||||
def before_perform(params)
|
||||
journal_call = create_journal(params[:issue].work_package,
|
||||
params[:comment])
|
||||
return journal_call if journal_call.failure?
|
||||
|
||||
input = { journal: journal_call.result }
|
||||
.merge(params)
|
||||
.slice(*::Bim::Bcf::Comment::CREATE_ATTRIBUTES)
|
||||
super input
|
||||
end
|
||||
|
||||
def create_journal(work_package, comment)
|
||||
::Journals::CreateService.new(work_package, user).call(notes: comment)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,36 @@
|
||||
#-- encoding: UTF-8
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 Bim::Bcf
|
||||
module Comments
|
||||
class SetAttributesService < ::BaseServices::SetAttributes
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,49 @@
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 Bim::Bcf
|
||||
module Comments
|
||||
class UpdateService < ::BaseServices::Update
|
||||
private
|
||||
|
||||
def before_perform(params)
|
||||
journal_call = update_journal(params[:original_comment].journal, params[:comment])
|
||||
return journal_call if journal_call.failure?
|
||||
|
||||
super params.slice(*::Bim::Bcf::Comment::UPDATE_ATTRIBUTES)
|
||||
end
|
||||
|
||||
def update_journal(journal, comment)
|
||||
::Journals::UpdateService.new(user: user,
|
||||
model: journal,
|
||||
contract_class: ::EmptyContract)
|
||||
.call(notes: comment)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -28,8 +28,16 @@
|
||||
|
||||
FactoryBot.define do
|
||||
factory :bcf_comment, class: '::Bim::Bcf::Comment' do
|
||||
after(:create) do |bcf_comment|
|
||||
bcf_comment.journal = create(:work_package_journal)
|
||||
transient do
|
||||
author { nil }
|
||||
end
|
||||
|
||||
after(:create) do |bcf_comment, evaluator|
|
||||
bcf_comment.journal = if evaluator.author == nil
|
||||
create(:work_package_journal)
|
||||
else
|
||||
create(:work_package_journal, user: evaluator.author)
|
||||
end
|
||||
bcf_comment.journal.update_attribute(:notes, 'Some BCF comment.')
|
||||
bcf_comment.journal.save
|
||||
bcf_comment.save
|
||||
|
||||
@@ -0,0 +1,611 @@
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) 2012-2021 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 'spec_helper'
|
||||
require 'rack/test'
|
||||
|
||||
require_relative './shared_responses'
|
||||
|
||||
describe 'BCF 2.1 comments resource', type: :request, content_type: :json, with_mail: false do
|
||||
include Rack::Test::Methods
|
||||
include API::V3::Utilities::PathHelper
|
||||
|
||||
let(:project) do
|
||||
FactoryBot.create(:project, enabled_module_names: %i[bim work_package_tracking])
|
||||
end
|
||||
|
||||
let(:view_only_user) do
|
||||
FactoryBot.create(:user,
|
||||
member_in_project: project,
|
||||
member_with_permissions: %i[view_linked_issues view_work_packages])
|
||||
end
|
||||
|
||||
let(:edit_user) do
|
||||
FactoryBot.create(:user,
|
||||
member_in_project: project,
|
||||
member_with_permissions: %i[view_linked_issues view_work_packages manage_bcf])
|
||||
end
|
||||
|
||||
let(:user_without_permission) { FactoryBot.create(:user, member_in_project: project) }
|
||||
|
||||
let(:assignee) { FactoryBot.create(:user) }
|
||||
|
||||
let(:work_package) do
|
||||
FactoryBot.create(:work_package, assigned_to: assignee, due_date: Date.today, project: project)
|
||||
end
|
||||
|
||||
let(:bcf_issue) { FactoryBot.create(:bcf_issue_with_viewpoint, work_package: work_package) }
|
||||
let(:viewpoint) { bcf_issue.viewpoints.first }
|
||||
|
||||
let(:bcf_comment) { FactoryBot.create(:bcf_comment, issue: bcf_issue, author: view_only_user) }
|
||||
let(:bcf_answer) { FactoryBot.create(:bcf_comment, issue: bcf_issue, reply_to: bcf_comment, author: assignee) }
|
||||
let(:bcf_comment_to_viewpoint) do
|
||||
FactoryBot.create(:bcf_comment, issue: bcf_issue, viewpoint: viewpoint, author: edit_user)
|
||||
end
|
||||
|
||||
subject(:response) { last_response }
|
||||
|
||||
describe 'GET /api/bcf/2.1/projects/:project_id/topics/:topic_guid/comments' do
|
||||
let(:path) { "/api/bcf/2.1/projects/#{project.id}/topics/#{bcf_issue.uuid}/comments" }
|
||||
let(:current_user) { view_only_user }
|
||||
let(:comments) { bcf_comment }
|
||||
|
||||
before do
|
||||
login_as(current_user)
|
||||
comments
|
||||
get path
|
||||
end
|
||||
|
||||
it_behaves_like 'bcf api successful response' do
|
||||
let(:comments) { [bcf_comment, bcf_answer, bcf_comment_to_viewpoint] }
|
||||
|
||||
let(:expected_body) do
|
||||
[
|
||||
{
|
||||
guid: bcf_comment.uuid,
|
||||
date: bcf_comment.journal.created_at,
|
||||
author: view_only_user.mail,
|
||||
comment: bcf_comment.journal.notes,
|
||||
modified_date: bcf_comment.journal.updated_at,
|
||||
modified_author: view_only_user.mail,
|
||||
topic_guid: bcf_issue.uuid,
|
||||
reply_to_comment_guid: nil,
|
||||
viewpoint_guid: nil,
|
||||
authorization: {
|
||||
comment_actions: []
|
||||
}
|
||||
},
|
||||
{
|
||||
guid: bcf_answer.uuid,
|
||||
date: bcf_answer.journal.created_at,
|
||||
author: assignee.mail,
|
||||
comment: bcf_answer.journal.notes,
|
||||
modified_date: bcf_answer.journal.updated_at,
|
||||
modified_author: assignee.mail,
|
||||
topic_guid: bcf_issue.uuid,
|
||||
reply_to_comment_guid: bcf_comment.uuid,
|
||||
viewpoint_guid: nil,
|
||||
authorization: {
|
||||
comment_actions: []
|
||||
}
|
||||
},
|
||||
{
|
||||
guid: bcf_comment_to_viewpoint.uuid,
|
||||
date: bcf_comment_to_viewpoint.journal.created_at,
|
||||
author: edit_user.mail,
|
||||
comment: bcf_comment_to_viewpoint.journal.notes,
|
||||
modified_date: bcf_comment_to_viewpoint.journal.updated_at,
|
||||
modified_author: edit_user.mail,
|
||||
topic_guid: bcf_issue.uuid,
|
||||
reply_to_comment_guid: nil,
|
||||
viewpoint_guid: viewpoint.uuid,
|
||||
authorization: {
|
||||
comment_actions: []
|
||||
}
|
||||
}
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
context 'with edit comments permission' do
|
||||
let(:current_user) { edit_user }
|
||||
|
||||
it_behaves_like 'bcf api successful response' do
|
||||
let(:expected_body) do
|
||||
[
|
||||
{
|
||||
guid: bcf_comment.uuid,
|
||||
date: bcf_comment.journal.created_at,
|
||||
author: view_only_user.mail,
|
||||
comment: bcf_comment.journal.notes,
|
||||
modified_date: bcf_comment.journal.updated_at,
|
||||
modified_author: view_only_user.mail,
|
||||
topic_guid: bcf_issue.uuid,
|
||||
reply_to_comment_guid: nil,
|
||||
viewpoint_guid: nil,
|
||||
authorization: {
|
||||
comment_actions: [
|
||||
"update"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'without view permissions' do
|
||||
let(:current_user) { user_without_permission }
|
||||
|
||||
it_behaves_like 'bcf api not allowed response'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST /api/bcf/2.1/projects/:project_id/topics/:topic_guid/comments' do
|
||||
let(:path) { "/api/bcf/2.1/projects/#{project.id}/topics/#{bcf_issue.uuid}/comments" }
|
||||
let(:current_user) { edit_user }
|
||||
let(:params) do
|
||||
{
|
||||
comment: "this is a new bcf comment"
|
||||
}
|
||||
end
|
||||
|
||||
before do
|
||||
login_as(current_user)
|
||||
post path, params.to_json
|
||||
end
|
||||
|
||||
it_behaves_like 'bcf api successful response' do
|
||||
let(:expected_status) { 201 }
|
||||
let(:expected_body) do
|
||||
comment = Bim::Bcf::Comment.last.reload
|
||||
creation_date = comment&.journal&.created_at&.iso8601
|
||||
|
||||
{
|
||||
guid: comment&.uuid,
|
||||
date: creation_date,
|
||||
author: edit_user.mail,
|
||||
comment: "this is a new bcf comment",
|
||||
modified_date: creation_date,
|
||||
modified_author: edit_user.mail,
|
||||
topic_guid: bcf_issue.uuid,
|
||||
reply_to_comment_guid: nil,
|
||||
viewpoint_guid: nil,
|
||||
authorization: {
|
||||
comment_actions: [
|
||||
"update"
|
||||
]
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
context 'if user has no permission to write comments' do
|
||||
let(:current_user) { view_only_user }
|
||||
|
||||
it_behaves_like 'bcf api not allowed response'
|
||||
end
|
||||
|
||||
context 'if request contains viewpoint guid' do
|
||||
let(:params) do
|
||||
{
|
||||
comment: "this is a comment to a specific viewpoint",
|
||||
viewpoint_guid: viewpoint.uuid
|
||||
}
|
||||
end
|
||||
|
||||
it_behaves_like 'bcf api successful response' do
|
||||
let(:expected_status) { 201 }
|
||||
let(:expected_body) do
|
||||
comment = Bim::Bcf::Comment.last.reload
|
||||
creation_date = comment&.journal&.created_at&.iso8601
|
||||
|
||||
{
|
||||
guid: comment&.uuid,
|
||||
date: creation_date,
|
||||
author: edit_user.mail,
|
||||
comment: "this is a comment to a specific viewpoint",
|
||||
modified_date: creation_date,
|
||||
modified_author: edit_user.mail,
|
||||
topic_guid: bcf_issue.uuid,
|
||||
reply_to_comment_guid: nil,
|
||||
viewpoint_guid: viewpoint.uuid,
|
||||
authorization: {
|
||||
comment_actions: [
|
||||
"update"
|
||||
]
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
context 'if the viewpoint guid does not exist' do
|
||||
let(:params) do
|
||||
{
|
||||
comment: "this is a comment to a specific viewpoint",
|
||||
viewpoint_guid: "00000000-0000-0000-0000-000000000000"
|
||||
}
|
||||
end
|
||||
|
||||
it_behaves_like 'bcf api unprocessable response' do
|
||||
let(:message) { 'Viewpoint does not exist.' }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'if request contains reply comment' do
|
||||
let(:params) do
|
||||
{
|
||||
comment: "this is a reply comment to another comment",
|
||||
reply_to_comment_guid: bcf_comment.uuid
|
||||
}
|
||||
end
|
||||
|
||||
it_behaves_like 'bcf api successful response' do
|
||||
let(:expected_status) { 201 }
|
||||
let(:expected_body) do
|
||||
comment = Bim::Bcf::Comment.last.reload
|
||||
creation_date = comment&.journal&.created_at&.iso8601
|
||||
|
||||
{
|
||||
guid: comment&.uuid,
|
||||
date: creation_date,
|
||||
author: edit_user.mail,
|
||||
comment: "this is a reply comment to another comment",
|
||||
modified_date: creation_date,
|
||||
modified_author: edit_user.mail,
|
||||
topic_guid: bcf_issue.uuid,
|
||||
reply_to_comment_guid: bcf_comment.uuid,
|
||||
viewpoint_guid: nil,
|
||||
authorization: {
|
||||
comment_actions: [
|
||||
"update"
|
||||
]
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
context 'if the comment guid does not exist' do
|
||||
let(:params) do
|
||||
{
|
||||
comment: "this is a reply comment to another comment",
|
||||
reply_to_comment_guid: "00000000-0000-0000-0000-000000000000"
|
||||
}
|
||||
end
|
||||
|
||||
it_behaves_like 'bcf api unprocessable response' do
|
||||
let(:message) { 'Bcf comment does not exist.' }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'if request contains reply comment and viewpoint reference' do
|
||||
let(:params) do
|
||||
{
|
||||
comment: "this is a reply comment to another comment with a specific reference to a viewpoint",
|
||||
reply_to_comment_guid: bcf_comment.uuid,
|
||||
viewpoint_guid: viewpoint.uuid
|
||||
}
|
||||
end
|
||||
|
||||
it_behaves_like 'bcf api successful response' do
|
||||
let(:expected_status) { 201 }
|
||||
let(:expected_body) do
|
||||
comment = Bim::Bcf::Comment.last.reload
|
||||
creation_date = comment&.journal&.created_at&.iso8601
|
||||
|
||||
{
|
||||
guid: comment&.uuid,
|
||||
date: creation_date,
|
||||
author: edit_user.mail,
|
||||
comment: "this is a reply comment to another comment with a specific reference to a viewpoint",
|
||||
modified_date: creation_date,
|
||||
modified_author: edit_user.mail,
|
||||
topic_guid: bcf_issue.uuid,
|
||||
reply_to_comment_guid: bcf_comment.uuid,
|
||||
viewpoint_guid: viewpoint.uuid,
|
||||
authorization: {
|
||||
comment_actions: [
|
||||
"update"
|
||||
]
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
context 'if the comment guid does not exist' do
|
||||
let(:params) do
|
||||
{
|
||||
comment: "this is a reply comment to another comment",
|
||||
reply_to_comment_guid: "00000000-0000-0000-0000-000000000000",
|
||||
viewpoint_guid: viewpoint.uuid
|
||||
}
|
||||
end
|
||||
|
||||
it_behaves_like 'bcf api unprocessable response' do
|
||||
let(:message) { 'Bcf comment does not exist.' }
|
||||
end
|
||||
end
|
||||
|
||||
context 'if the viewpoint guid does not exist' do
|
||||
let(:params) do
|
||||
{
|
||||
comment: "this is a reply comment to another comment",
|
||||
viewpoint_guid: "00000000-0000-0000-0000-000000000000",
|
||||
reply_to_comment_guid: bcf_comment.uuid
|
||||
}
|
||||
end
|
||||
|
||||
it_behaves_like 'bcf api unprocessable response' do
|
||||
let(:message) { 'Viewpoint does not exist.' }
|
||||
end
|
||||
end
|
||||
|
||||
context 'if the comment and viewpoint guid does not exist' do
|
||||
let(:params) do
|
||||
{
|
||||
comment: "this is a reply comment to another comment",
|
||||
reply_to_comment_guid: "00000000-0000-0000-0000-000000000000",
|
||||
viewpoint_guid: "00000000-0000-0000-0000-000000000000"
|
||||
}
|
||||
end
|
||||
|
||||
it_behaves_like 'bcf api unprocessable response' do
|
||||
let(:message) { 'Multiple field constraints have been violated. Viewpoint does not exist. Bcf comment does not exist.' }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PUT /api/bcf/2.1/projects/:project_id/topics/:topic_guid/comments' do
|
||||
let(:path) { "/api/bcf/2.1/projects/#{project.id}/topics/#{bcf_issue.uuid}/comments" }
|
||||
let(:current_user) { edit_user }
|
||||
let(:params) { { comment: "This is a bad comment update ... " } }
|
||||
|
||||
before do
|
||||
login_as(current_user)
|
||||
put path, params.to_json
|
||||
end
|
||||
|
||||
it_behaves_like 'bcf api method not allowed response'
|
||||
end
|
||||
|
||||
describe 'GET /api/bcf/2.1/projects/:project_id/topics/:topic_guid/comments/:comment_guid' do
|
||||
let(:path) { "/api/bcf/2.1/projects/#{project.id}/topics/#{bcf_issue.uuid}/comments/#{bcf_comment.uuid}" }
|
||||
let(:current_user) { view_only_user }
|
||||
let(:comments) { [bcf_comment, bcf_answer, bcf_comment_to_viewpoint] }
|
||||
|
||||
before do
|
||||
login_as(current_user)
|
||||
comments
|
||||
get path
|
||||
end
|
||||
|
||||
it_behaves_like 'bcf api successful response' do
|
||||
let(:expected_body) do
|
||||
{
|
||||
guid: bcf_comment.uuid,
|
||||
date: bcf_comment.journal.created_at,
|
||||
author: view_only_user.mail,
|
||||
comment: bcf_comment.journal.notes,
|
||||
modified_date: bcf_comment.journal.updated_at,
|
||||
modified_author: view_only_user.mail,
|
||||
topic_guid: bcf_issue.uuid,
|
||||
reply_to_comment_guid: nil,
|
||||
viewpoint_guid: nil,
|
||||
authorization: { comment_actions: [] }
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
context 'if user has editing permissions' do
|
||||
let(:current_user) { edit_user }
|
||||
|
||||
it_behaves_like 'bcf api successful response' do
|
||||
let(:expected_body) do
|
||||
{
|
||||
guid: bcf_comment.uuid,
|
||||
date: bcf_comment.journal.created_at,
|
||||
author: view_only_user.mail,
|
||||
comment: bcf_comment.journal.notes,
|
||||
modified_date: bcf_comment.journal.updated_at,
|
||||
modified_author: view_only_user.mail,
|
||||
topic_guid: bcf_issue.uuid,
|
||||
reply_to_comment_guid: nil,
|
||||
viewpoint_guid: nil,
|
||||
authorization: {
|
||||
comment_actions: [
|
||||
"update"
|
||||
]
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'if comment id does not exist' do
|
||||
let(:invalid_id) { "1337" }
|
||||
let(:path) { "/api/bcf/2.1/projects/#{project.id}/topics/#{bcf_issue.uuid}/comments/#{invalid_id}" }
|
||||
|
||||
it_behaves_like 'bcf api not found response'
|
||||
end
|
||||
|
||||
context 'without view permissions' do
|
||||
let(:current_user) { user_without_permission }
|
||||
|
||||
it_behaves_like 'bcf api not allowed response'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PUT /api/bcf/2.1/projects/:project_id/topics/:topic_guid/comments/:comment_guid' do
|
||||
let(:updated_comment) { bcf_comment }
|
||||
let(:path) { "/api/bcf/2.1/projects/#{project.id}/topics/#{bcf_issue.uuid}/comments/#{updated_comment.uuid}" }
|
||||
let(:current_user) { edit_user }
|
||||
let(:params) { { comment: "Update comment to this elaborate text." } }
|
||||
|
||||
before do
|
||||
login_as(current_user)
|
||||
put path, params.to_json
|
||||
end
|
||||
|
||||
it_behaves_like 'bcf api successful response' do
|
||||
let(:expected_body) do
|
||||
{
|
||||
guid: updated_comment.uuid,
|
||||
date: updated_comment.journal.created_at,
|
||||
author: view_only_user.mail,
|
||||
comment: "Update comment to this elaborate text.",
|
||||
modified_date: updated_comment.journal.updated_at,
|
||||
# we cannot store another author then the journal creator
|
||||
modified_author: view_only_user.mail,
|
||||
topic_guid: bcf_issue.uuid,
|
||||
reply_to_comment_guid: nil,
|
||||
viewpoint_guid: nil,
|
||||
authorization: {
|
||||
comment_actions: [
|
||||
"update"
|
||||
]
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
context 'if user has no edit permissions' do
|
||||
let(:current_user) { view_only_user }
|
||||
|
||||
it_behaves_like 'bcf api not allowed response'
|
||||
end
|
||||
|
||||
context 'if viewpoint reference and reply to is changed' do
|
||||
let(:params) do
|
||||
{
|
||||
comment: "A new updated text",
|
||||
viewpoint_guid: viewpoint.uuid,
|
||||
reply_to_comment_guid: bcf_comment_to_viewpoint.uuid
|
||||
}
|
||||
end
|
||||
|
||||
it_behaves_like 'bcf api successful response' do
|
||||
let(:expected_body) do
|
||||
{
|
||||
guid: updated_comment.uuid,
|
||||
date: updated_comment.journal.created_at,
|
||||
author: view_only_user.mail,
|
||||
comment: "A new updated text",
|
||||
modified_date: updated_comment.journal.updated_at,
|
||||
# we cannot store another author then the journal creator
|
||||
modified_author: view_only_user.mail,
|
||||
topic_guid: bcf_issue.uuid,
|
||||
reply_to_comment_guid: bcf_comment_to_viewpoint.uuid,
|
||||
viewpoint_guid: viewpoint.uuid,
|
||||
authorization: {
|
||||
comment_actions: [
|
||||
"update"
|
||||
]
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'if an invalid viewpoint guid is given' do
|
||||
let(:params) do
|
||||
{
|
||||
comment: "A new updated text",
|
||||
viewpoint_guid: "00000000-0000-0000-0000-000000000000"
|
||||
}
|
||||
end
|
||||
|
||||
it_behaves_like 'bcf api unprocessable response' do
|
||||
let(:message) { 'Viewpoint does not exist.' }
|
||||
end
|
||||
end
|
||||
|
||||
context 'if an invalid comment guid is given' do
|
||||
let(:params) do
|
||||
{
|
||||
comment: "A new updated text",
|
||||
reply_to_comment_guid: "00000000-0000-0000-0000-000000000000"
|
||||
}
|
||||
end
|
||||
|
||||
it_behaves_like 'bcf api unprocessable response' do
|
||||
let(:message) { 'Bcf comment does not exist.' }
|
||||
end
|
||||
end
|
||||
|
||||
context 'if the updated comment contains viewpoint reference and is a reply, but update does not set those attributes' do
|
||||
let(:updated_comment) do
|
||||
FactoryBot.create(:bcf_comment,
|
||||
issue: bcf_issue,
|
||||
viewpoint: viewpoint,
|
||||
reply_to: bcf_comment,
|
||||
author: edit_user)
|
||||
end
|
||||
|
||||
let(:params) { { comment: "Only change the comment text and leave the reply and viewpoint guid empty." } }
|
||||
|
||||
it_behaves_like 'bcf api successful response' do
|
||||
let(:expected_body) do
|
||||
{
|
||||
guid: updated_comment.uuid,
|
||||
date: updated_comment.journal.created_at,
|
||||
author: edit_user.mail,
|
||||
comment: "Only change the comment text and leave the reply and viewpoint guid empty.",
|
||||
modified_date: updated_comment.journal.updated_at,
|
||||
# we cannot store another author then the journal creator
|
||||
modified_author: edit_user.mail,
|
||||
topic_guid: bcf_issue.uuid,
|
||||
reply_to_comment_guid: nil,
|
||||
viewpoint_guid: nil,
|
||||
authorization: {
|
||||
comment_actions: [
|
||||
"update"
|
||||
]
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST /api/bcf/2.1/projects/:project_id/topics/:topic_guid/comments/:comment_guid' do
|
||||
let(:path) { "/api/bcf/2.1/projects/#{project.id}/topics/#{bcf_issue.uuid}/comments/#{bcf_comment.uuid}" }
|
||||
let(:current_user) { edit_user }
|
||||
let(:params) { { comment: "This is an invalid try to create a comment ..." } }
|
||||
|
||||
before do
|
||||
login_as(current_user)
|
||||
post path, params.to_json
|
||||
end
|
||||
|
||||
it_behaves_like 'bcf api method not allowed response'
|
||||
end
|
||||
end
|
||||
@@ -48,6 +48,7 @@ describe 'BCF 2.1 projects resource', type: :request, content_type: :json do
|
||||
end
|
||||
|
||||
let(:project) { FactoryBot.create(:project, enabled_module_names: [:bim]) }
|
||||
|
||||
subject(:response) { last_response }
|
||||
|
||||
describe 'GET /api/bcf/2.1/projects/:project_id' do
|
||||
|
||||
@@ -28,12 +28,15 @@
|
||||
|
||||
shared_examples_for 'bcf api successful response' do
|
||||
def expect_identical_without_time(subject, expected_body)
|
||||
# Remove modified date
|
||||
body = Array.wrap(JSON.parse(subject.body))
|
||||
Array.wrap(expected_body).each_with_index do |expected_item, index|
|
||||
expected = Array.wrap(expected_body)
|
||||
expect(body.size).to eql(expected.size)
|
||||
|
||||
expected.each_with_index do |expected_item, index|
|
||||
subject_body = body[index]
|
||||
|
||||
expected_item.stringify_keys!
|
||||
# Remove date strings and compare separately
|
||||
subject_modified_date = subject_body.delete('modified_date')&.to_time
|
||||
expected_modified_date = expected_item.delete('modified_date')&.to_time
|
||||
|
||||
@@ -43,6 +46,15 @@ shared_examples_for 'bcf api successful response' do
|
||||
expect(subject_modified_date).to eql(expected_modified_date)
|
||||
end
|
||||
|
||||
subject_created_date = subject_body.delete('date')&.to_time
|
||||
expected_created_date = expected_item.delete('date')&.to_time
|
||||
|
||||
if expected_created_date
|
||||
expect(subject_created_date).to be_within(10.seconds).of(expected_created_date)
|
||||
else
|
||||
expect(subject_created_date).to eql(expected_created_date)
|
||||
end
|
||||
|
||||
expect(subject_body.to_json).to be_json_eql(expected_item.to_json)
|
||||
end
|
||||
end
|
||||
@@ -83,6 +95,16 @@ shared_examples_for 'bcf api not found response' do
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples_for 'bcf api method not allowed response' do
|
||||
let(:expect_405) { "405 Not Allowed" }
|
||||
|
||||
it 'responds 405 METHOD NOT ALLOWED', :aggregate_failures do
|
||||
expect(subject.status).to eq 405
|
||||
expect(subject.body).to eql(expect_405)
|
||||
expect(subject.headers['Content-Type']).to eql 'application/json; charset=utf-8'
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples_for 'bcf api not allowed response' do
|
||||
let(:expect_403) do
|
||||
{ message: 'You are not authorized to access this resource.' }
|
||||
|
||||
Reference in New Issue
Block a user