Merge pull request #3129 from ulferts/feature/create_work_package_for_release_4_2
Feature/create work package for release 4 2pull/3130/head
commit
159482b378
@ -0,0 +1,52 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
# |
||||
# 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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
class CreateWorkPackageService |
||||
attr_accessor :user, :project, :work_package |
||||
|
||||
def initialize(user:, project:, send_notifications: true) |
||||
self.user = user |
||||
self.project = project |
||||
|
||||
WorkPackageObserver.instance.send_notification = send_notifications |
||||
end |
||||
|
||||
def create |
||||
hash = { |
||||
project: project, |
||||
author: user, |
||||
type: project.types.where(is_default: true).first || project.types.first |
||||
} |
||||
self.work_package = project.add_work_package(hash) |
||||
end |
||||
|
||||
def save(work_package) |
||||
work_package.save |
||||
end |
||||
end |
@ -0,0 +1,47 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
# |
||||
# 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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'api/v3/work_packages/work_packages_shared_helpers' |
||||
|
||||
module API |
||||
module V3 |
||||
module WorkPackages |
||||
class CreateFormAPI < ::API::OpenProjectAPI |
||||
resource :form do |
||||
helpers ::API::V3::WorkPackages::WorkPackagesSharedHelpers |
||||
|
||||
post do |
||||
create_work_package_form(create_service.create, |
||||
contract_class: CreateContract, |
||||
form_class: CreateFormRepresenter) |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,67 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
# |
||||
# 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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module API |
||||
module V3 |
||||
module WorkPackages |
||||
class CreateFormRepresenter < FormRepresenter |
||||
link :self do |
||||
{ |
||||
href: api_v3_paths.create_work_package_form(represented.project_id), |
||||
method: :post |
||||
} |
||||
end |
||||
|
||||
link :validate do |
||||
{ |
||||
href: api_v3_paths.create_work_package_form(represented.project_id), |
||||
method: :post |
||||
} |
||||
end |
||||
|
||||
link :previewMarkup do |
||||
{ |
||||
href: api_v3_paths.render_markup(link: api_v3_paths.project(represented.project_id)), |
||||
method: :post |
||||
} |
||||
end |
||||
|
||||
link :commit do |
||||
{ |
||||
href: api_v3_paths.work_packages_by_project(represented.project_id), |
||||
method: :post |
||||
} if current_user.allowed_to?(:edit_work_packages, represented.project) && |
||||
# Calling valid? on represented empties the list of errors |
||||
# also removing errors from other sources (like contracts). |
||||
represented.errors.empty? |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -1,113 +0,0 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
# |
||||
# 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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'roar/decorator' |
||||
require 'roar/json/hal' |
||||
|
||||
module API |
||||
module V3 |
||||
module WorkPackages |
||||
module Form |
||||
class FormRepresenter < Roar::Decorator |
||||
include Roar::JSON::HAL |
||||
include Roar::Hypermedia |
||||
include API::V3::Utilities::PathHelper |
||||
|
||||
self.as_strategy = ::API::Utilities::CamelCasingStrategy.new |
||||
|
||||
def initialize(model, options = {}) |
||||
@current_user = options[:current_user] |
||||
|
||||
super(model) |
||||
end |
||||
|
||||
property :_type, exec_context: :decorator, writeable: false |
||||
|
||||
link :self do |
||||
{ |
||||
href: api_v3_paths.work_package_form(represented.id), |
||||
} |
||||
end |
||||
|
||||
link :validate do |
||||
{ |
||||
href: api_v3_paths.work_package_form(represented.id), |
||||
method: :post |
||||
} |
||||
end |
||||
|
||||
link :previewMarkup do |
||||
{ |
||||
href: api_v3_paths.render_markup(link: api_v3_paths.work_package(represented.id)), |
||||
method: :post |
||||
} |
||||
end |
||||
|
||||
link :commit do |
||||
{ |
||||
href: api_v3_paths.work_package(represented.id), |
||||
method: :patch |
||||
} if @current_user.allowed_to?(:edit_work_packages, represented.project) && |
||||
# Calling valid? on represented empties the list of errors |
||||
# also removing errors from other sources (like contracts). |
||||
represented.errors.empty? |
||||
end |
||||
|
||||
property :payload, |
||||
embedded: true, |
||||
decorator: -> (represented, *) { |
||||
Form::WorkPackagePayloadRepresenter.create_class(represented) |
||||
}, |
||||
getter: -> (*) { self } |
||||
property :schema, |
||||
embedded: true, |
||||
exec_context: :decorator, |
||||
getter: -> (*) { |
||||
schema = Schema::WorkPackageSchema.new(work_package: represented) |
||||
Schema::WorkPackageSchemaRepresenter.create(schema, |
||||
form_embedded: true, |
||||
current_user: @current_user) |
||||
} |
||||
property :validation_errors, embedded: true, exec_context: :decorator |
||||
|
||||
def _type |
||||
'Form' |
||||
end |
||||
|
||||
def validation_errors |
||||
::API::Errors::Validation.create(represented.errors.dup).inject({}) do |h, (k, v)| |
||||
h[k] = ::API::V3::Errors::ErrorRepresenter.new(v) |
||||
h |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -1,119 +0,0 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
# |
||||
# 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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'roar/decorator' |
||||
require 'roar/json/hal' |
||||
|
||||
module API |
||||
module V3 |
||||
module WorkPackages |
||||
module Form |
||||
class WorkPackageAttributeLinksRepresenter < Roar::Decorator |
||||
include Roar::JSON::HAL |
||||
include Roar::Hypermedia |
||||
include API::V3::Utilities::PathHelper |
||||
|
||||
class << self |
||||
def create_class(work_package) |
||||
injector_class = ::API::V3::Utilities::CustomFieldInjector |
||||
injector_class.create_value_representer_for_link_patching(work_package, |
||||
WorkPackageAttributeLinksRepresenter) |
||||
end |
||||
|
||||
def create(work_package) |
||||
create_class(work_package).new(work_package) |
||||
end |
||||
end |
||||
|
||||
self.as_strategy = ::API::Utilities::CamelCasingStrategy.new |
||||
|
||||
def self.linked_property(property, |
||||
namespace: property.to_s.pluralize, |
||||
association: "#{property}_id", |
||||
path: property, |
||||
show_if: true) |
||||
|
||||
property property, |
||||
exec_context: :decorator, |
||||
getter: -> (*) { |
||||
get_path(get_method: association, |
||||
path: path) |
||||
}, |
||||
setter: -> (value, *) { |
||||
parse_link(property: property, |
||||
namespace: namespace, |
||||
value: value, |
||||
setter_method: :"#{association}=") |
||||
}, |
||||
if: show_if |
||||
end |
||||
|
||||
linked_property :type |
||||
linked_property :status |
||||
linked_property :assignee, |
||||
namespace: :users, |
||||
association: :assigned_to_id, |
||||
path: :user |
||||
linked_property :responsible, |
||||
namespace: :users, |
||||
association: :responsible_id, |
||||
path: :user |
||||
linked_property :category |
||||
linked_property :version, |
||||
association: :fixed_version_id |
||||
linked_property :priority |
||||
|
||||
private |
||||
|
||||
def get_path(get_method: nil, path: nil) |
||||
id = represented.send(get_method) |
||||
|
||||
{ href: (api_v3_paths.send(path, id) if id) } |
||||
end |
||||
|
||||
def parse_link(property: nil, namespace: nil, value: {}, setter_method: nil) |
||||
return unless value.has_key?('href') |
||||
resource = parse_resource(property, namespace, value['href']) |
||||
|
||||
represented.send(setter_method, resource) |
||||
end |
||||
|
||||
def parse_resource(property, ns, href) |
||||
return nil unless href |
||||
|
||||
::API::Utilities::ResourceLinkParser.parse_id href, |
||||
property: property, |
||||
expected_version: '3', |
||||
expected_namespace: ns |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -1,157 +0,0 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
# |
||||
# 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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'roar/decorator' |
||||
require 'roar/json/hal' |
||||
|
||||
module API |
||||
module V3 |
||||
module WorkPackages |
||||
module Form |
||||
class WorkPackagePayloadRepresenter < Roar::Decorator |
||||
include Roar::JSON::HAL |
||||
include Roar::Hypermedia |
||||
|
||||
class << self |
||||
def create_class(work_package) |
||||
injector_class = ::API::V3::Utilities::CustomFieldInjector |
||||
injector_class.create_value_representer_for_property_patching(work_package, |
||||
WorkPackagePayloadRepresenter) |
||||
end |
||||
|
||||
def create(work_package, options = {}) |
||||
create_class(work_package).new(work_package, options) |
||||
end |
||||
end |
||||
|
||||
self.as_strategy = ::API::Utilities::CamelCasingStrategy.new |
||||
|
||||
def initialize(represented, options = {}) |
||||
if options[:enforce_lock_version_validation] |
||||
# enforces availibility validation of lock_version |
||||
represented.lock_version = nil |
||||
end |
||||
|
||||
super(represented) |
||||
end |
||||
|
||||
property :linked_resources, |
||||
as: :_links, |
||||
exec_context: :decorator, |
||||
getter: -> (*) { |
||||
work_package_attribute_links_representer represented |
||||
}, |
||||
setter: -> (value, *) { |
||||
representer = work_package_attribute_links_representer represented |
||||
representer.from_json(value.to_json) |
||||
} |
||||
|
||||
property :lock_version |
||||
property :subject, render_nil: true |
||||
property :done_ratio, |
||||
as: :percentageDone, |
||||
render_nil: true, |
||||
if: -> (*) { Setting.work_package_done_ratio != 'disabled' } |
||||
|
||||
property :estimated_hours, |
||||
as: :estimatedTime, |
||||
exec_context: :decorator, |
||||
getter: -> (*) { |
||||
datetime_formatter.format_duration_from_hours(represented.estimated_hours, |
||||
allow_nil: true) |
||||
}, |
||||
setter: -> (value, *) { |
||||
represented.estimated_hours = datetime_formatter.parse_duration_to_hours( |
||||
value, |
||||
'estimated_hours', |
||||
allow_nil: true) |
||||
}, |
||||
render_nil: true |
||||
|
||||
property :description, |
||||
exec_context: :decorator, |
||||
getter: -> (*) { |
||||
API::Decorators::Formattable.new(represented.description, object: represented) |
||||
}, |
||||
setter: -> (value, *) { represented.description = value['raw'] }, |
||||
render_nil: true |
||||
|
||||
property :parent_id, |
||||
writeable: true, |
||||
render_nil: true |
||||
|
||||
property :project_id, |
||||
getter: -> (*) { nil }, |
||||
render_nil: false |
||||
|
||||
property :start_date, |
||||
exec_context: :decorator, |
||||
getter: -> (*) { |
||||
datetime_formatter.format_date(represented.start_date, allow_nil: true) |
||||
}, |
||||
setter: -> (value, *) { |
||||
represented.start_date = datetime_formatter.parse_date(value, |
||||
'startDate', |
||||
allow_nil: true) |
||||
}, |
||||
render_nil: true |
||||
property :due_date, |
||||
exec_context: :decorator, |
||||
getter: -> (*) { |
||||
datetime_formatter.format_date(represented.due_date, allow_nil: true) |
||||
}, |
||||
setter: -> (value, *) { |
||||
represented.due_date = datetime_formatter.parse_date(value, |
||||
'dueDate', |
||||
allow_nil: true) |
||||
}, |
||||
render_nil: true |
||||
property :version_id, |
||||
getter: -> (*) { nil }, |
||||
setter: -> (value, *) { self.fixed_version_id = value }, |
||||
render_nil: false |
||||
property :created_at, |
||||
getter: -> (*) { nil }, render_nil: false |
||||
property :updated_at, |
||||
getter: -> (*) { nil }, render_nil: false |
||||
|
||||
private |
||||
|
||||
def datetime_formatter |
||||
API::V3::Utilities::DateTimeFormatter |
||||
end |
||||
|
||||
def work_package_attribute_links_representer(represented) |
||||
::API::V3::WorkPackages::Form::WorkPackageAttributeLinksRepresenter.create represented |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,64 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
# |
||||
# 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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module API |
||||
module V3 |
||||
module WorkPackages |
||||
class FormRepresenter < ::API::Decorators::Single |
||||
property :payload, |
||||
embedded: true, |
||||
decorator: -> (represented, *) { |
||||
WorkPackagePayloadRepresenter.create_class(represented) |
||||
}, |
||||
getter: -> (*) { self } |
||||
property :schema, |
||||
embedded: true, |
||||
exec_context: :decorator, |
||||
getter: -> (*) { |
||||
schema = Schema::WorkPackageSchema.new(work_package: represented) |
||||
Schema::WorkPackageSchemaRepresenter.create(schema, |
||||
form_embedded: true, |
||||
current_user: current_user) |
||||
} |
||||
property :validation_errors, embedded: true, exec_context: :decorator |
||||
|
||||
def _type |
||||
'Form' |
||||
end |
||||
|
||||
def validation_errors |
||||
::API::Errors::Validation.create(represented.errors.dup).inject({}) do |h, (k, v)| |
||||
h[k] = ::API::V3::Errors::ErrorRepresenter.new(v) |
||||
h |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,59 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
# |
||||
# 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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module API |
||||
module V3 |
||||
module WorkPackages |
||||
class UpdateContract < BaseContract |
||||
attribute :lock_version do |
||||
errors.add :error_conflict, '' if model.lock_version.nil? || model.lock_version_changed? |
||||
end |
||||
|
||||
validate :user_allowed_to_access |
||||
|
||||
validate :user_allowed_to_edit |
||||
|
||||
private |
||||
|
||||
def user_allowed_to_edit |
||||
errors.add :error_unauthorized, '' unless @can.allowed?(model, :edit) |
||||
end |
||||
|
||||
# TODO: when someone ever fixes the way errors are added in the contract: |
||||
# find a solution to ensure that THIS validation supersedes others (i.e. show 404 if |
||||
# there is no access allowed) |
||||
def user_allowed_to_access |
||||
unless ::WorkPackage.visible(@user).exists?(model) || true |
||||
errors.add :error_not_found, I18n.t('api_v3.errors.code_404') |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,47 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
# |
||||
# 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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'api/v3/work_packages/work_packages_shared_helpers' |
||||
|
||||
module API |
||||
module V3 |
||||
module WorkPackages |
||||
class UpdateFormAPI < ::API::OpenProjectAPI |
||||
resource :form do |
||||
helpers ::API::V3::WorkPackages::WorkPackagesSharedHelpers |
||||
|
||||
post do |
||||
create_work_package_form(@work_package, |
||||
contract_class: UpdateContract, |
||||
form_class: UpdateFormRepresenter) |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,67 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
# |
||||
# 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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
module API |
||||
module V3 |
||||
module WorkPackages |
||||
class UpdateFormRepresenter < FormRepresenter |
||||
link :self do |
||||
{ |
||||
href: api_v3_paths.work_package_form(represented.id), |
||||
method: :post |
||||
} |
||||
end |
||||
|
||||
link :validate do |
||||
{ |
||||
href: api_v3_paths.work_package_form(represented.id), |
||||
method: :post |
||||
} |
||||
end |
||||
|
||||
link :previewMarkup do |
||||
{ |
||||
href: api_v3_paths.render_markup(link: api_v3_paths.work_package(represented.id)), |
||||
method: :post |
||||
} |
||||
end |
||||
|
||||
link :commit do |
||||
{ |
||||
href: api_v3_paths.work_package(represented.id), |
||||
method: :patch |
||||
} if current_user.allowed_to?(:edit_work_packages, represented.project) && |
||||
# Calling valid? on represented empties the list of errors |
||||
# also removing errors from other sources (like contracts). |
||||
represented.errors.empty? |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,118 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
# |
||||
# 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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'roar/decorator' |
||||
require 'roar/json/hal' |
||||
|
||||
module API |
||||
module V3 |
||||
module WorkPackages |
||||
class WorkPackageAttributeLinksRepresenter < Roar::Decorator |
||||
include Roar::JSON::HAL |
||||
include Roar::Hypermedia |
||||
include API::V3::Utilities::PathHelper |
||||
|
||||
class << self |
||||
def create_class(work_package) |
||||
injector_class = ::API::V3::Utilities::CustomFieldInjector |
||||
injector_class.create_value_representer_for_link_patching( |
||||
work_package, |
||||
WorkPackageAttributeLinksRepresenter) |
||||
end |
||||
|
||||
def create(work_package) |
||||
create_class(work_package).new(work_package) |
||||
end |
||||
end |
||||
|
||||
self.as_strategy = ::API::Utilities::CamelCasingStrategy.new |
||||
|
||||
def self.linked_property(property, |
||||
namespace: property.to_s.pluralize, |
||||
association: "#{property}_id", |
||||
path: property, |
||||
show_if: true) |
||||
|
||||
property property, |
||||
exec_context: :decorator, |
||||
getter: -> (*) { |
||||
get_path(get_method: association, |
||||
path: path) |
||||
}, |
||||
setter: -> (value, *) { |
||||
parse_link(property: property, |
||||
namespace: namespace, |
||||
value: value, |
||||
setter_method: :"#{association}=") |
||||
}, |
||||
if: show_if |
||||
end |
||||
|
||||
linked_property :type |
||||
linked_property :status |
||||
linked_property :assignee, |
||||
namespace: :users, |
||||
association: :assigned_to_id, |
||||
path: :user |
||||
linked_property :responsible, |
||||
namespace: :users, |
||||
association: :responsible_id, |
||||
path: :user |
||||
linked_property :category |
||||
linked_property :version, |
||||
association: :fixed_version_id |
||||
linked_property :priority |
||||
|
||||
private |
||||
|
||||
def get_path(get_method: nil, path: nil) |
||||
id = represented.send(get_method) |
||||
|
||||
{ href: (api_v3_paths.send(path, id) if id) } |
||||
end |
||||
|
||||
def parse_link(property: nil, namespace: nil, value: {}, setter_method: nil) |
||||
return unless value.has_key?('href') |
||||
resource = parse_resource(property, namespace, value['href']) |
||||
|
||||
represented.send(setter_method, resource) |
||||
end |
||||
|
||||
def parse_resource(property, ns, href) |
||||
return nil unless href |
||||
|
||||
::API::Utilities::ResourceLinkParser.parse_id href, |
||||
property: property, |
||||
expected_version: '3', |
||||
expected_namespace: ns |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,147 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
# |
||||
# 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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'roar/decorator' |
||||
require 'roar/json/hal' |
||||
|
||||
module API |
||||
module V3 |
||||
module WorkPackages |
||||
class WorkPackagePayloadRepresenter < Roar::Decorator |
||||
include Roar::JSON::HAL |
||||
include Roar::Hypermedia |
||||
|
||||
class << self |
||||
def create_class(work_package) |
||||
injector_class = ::API::V3::Utilities::CustomFieldInjector |
||||
injector_class.create_value_representer_for_property_patching( |
||||
work_package, |
||||
WorkPackagePayloadRepresenter) |
||||
end |
||||
|
||||
def create(work_package) |
||||
create_class(work_package).new(work_package) |
||||
end |
||||
end |
||||
|
||||
self.as_strategy = ::API::Utilities::CamelCasingStrategy.new |
||||
|
||||
def initialize(represented) |
||||
super(represented) |
||||
end |
||||
|
||||
property :linked_resources, |
||||
as: :_links, |
||||
exec_context: :decorator, |
||||
getter: -> (*) { |
||||
work_package_attribute_links_representer represented |
||||
}, |
||||
setter: -> (value, *) { |
||||
representer = work_package_attribute_links_representer represented |
||||
representer.from_json(value.to_json) |
||||
} |
||||
|
||||
property :lock_version |
||||
property :subject, render_nil: true |
||||
property :done_ratio, |
||||
as: :percentageDone, |
||||
render_nil: true, |
||||
if: -> (*) { Setting.work_package_done_ratio != 'disabled' } |
||||
|
||||
property :estimated_hours, |
||||
as: :estimatedTime, |
||||
exec_context: :decorator, |
||||
getter: -> (*) { |
||||
datetime_formatter.format_duration_from_hours(represented.estimated_hours, |
||||
allow_nil: true) |
||||
}, |
||||
setter: -> (value, *) { |
||||
represented.estimated_hours = datetime_formatter.parse_duration_to_hours( |
||||
value, |
||||
'estimated_hours', |
||||
allow_nil: true) |
||||
}, |
||||
render_nil: true |
||||
|
||||
property :description, |
||||
exec_context: :decorator, |
||||
getter: -> (*) { |
||||
API::Decorators::Formattable.new(represented.description, object: represented) |
||||
}, |
||||
setter: -> (value, *) { represented.description = value['raw'] }, |
||||
render_nil: true |
||||
|
||||
property :parent_id, |
||||
writeable: true, |
||||
render_nil: true |
||||
|
||||
property :start_date, |
||||
exec_context: :decorator, |
||||
getter: -> (*) { |
||||
datetime_formatter.format_date(represented.start_date, allow_nil: true) |
||||
}, |
||||
setter: -> (value, *) { |
||||
represented.start_date = datetime_formatter.parse_date(value, |
||||
'startDate', |
||||
allow_nil: true) |
||||
}, |
||||
render_nil: true |
||||
property :due_date, |
||||
exec_context: :decorator, |
||||
getter: -> (*) { |
||||
datetime_formatter.format_date(represented.due_date, allow_nil: true) |
||||
}, |
||||
setter: -> (value, *) { |
||||
represented.due_date = datetime_formatter.parse_date(value, |
||||
'dueDate', |
||||
allow_nil: true) |
||||
}, |
||||
render_nil: true |
||||
property :version_id, |
||||
getter: -> (*) { nil }, |
||||
setter: -> (value, *) { self.fixed_version_id = value }, |
||||
render_nil: false |
||||
property :created_at, |
||||
getter: -> (*) { nil }, render_nil: false |
||||
property :updated_at, |
||||
getter: -> (*) { nil }, render_nil: false |
||||
|
||||
private |
||||
|
||||
def datetime_formatter |
||||
API::V3::Utilities::DateTimeFormatter |
||||
end |
||||
|
||||
def work_package_attribute_links_representer(represented) |
||||
::API::V3::WorkPackages::WorkPackageAttributeLinksRepresenter.create represented |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,69 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
# |
||||
# 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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'api/v3/work_packages/work_package_representer' |
||||
require 'api/v3/work_packages/work_packages_shared_helpers' |
||||
|
||||
module API |
||||
module V3 |
||||
module WorkPackages |
||||
class WorkPackagesByProjectAPI < ::API::OpenProjectAPI |
||||
resources :work_packages do |
||||
helpers ::API::V3::WorkPackages::WorkPackagesSharedHelpers |
||||
helpers do |
||||
def create_service |
||||
@create_service ||= |
||||
CreateWorkPackageService.new( |
||||
user: current_user, |
||||
project: @project, |
||||
send_notifications: !(params.has_key?(:notify) && params[:notify] == 'false')) |
||||
end |
||||
end |
||||
|
||||
post do |
||||
work_package = create_service.create |
||||
|
||||
write_work_package_attributes work_package |
||||
|
||||
if write_request_valid?(work_package, WorkPackages::CreateContract) && |
||||
create_service.save(work_package) |
||||
work_package.reload |
||||
|
||||
WorkPackages::WorkPackageRepresenter.create(work_package, |
||||
current_user: current_user) |
||||
else |
||||
fail ::API::Errors::ErrorBase.create(work_package.errors.dup) |
||||
end |
||||
end |
||||
|
||||
mount ::API::V3::WorkPackages::CreateFormAPI |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,99 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
# |
||||
# 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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'api/v3/work_packages/base_contract' |
||||
require 'api/v3/work_packages/work_package_payload_representer' |
||||
|
||||
module API |
||||
module V3 |
||||
module WorkPackages |
||||
module WorkPackagesSharedHelpers |
||||
extend Grape::API::Helpers |
||||
def request_body |
||||
env['api.request.body'] |
||||
end |
||||
|
||||
# merges the given JSON representation into @work_package |
||||
def merge_json_into_work_package!(work_package, json) |
||||
payload = ::API::V3::WorkPackages::WorkPackagePayloadRepresenter.create(work_package) |
||||
payload.from_json(json) |
||||
end |
||||
|
||||
def write_work_package_attributes(work_package, reset_lock_version: false) |
||||
if request_body |
||||
begin |
||||
work_package.lock_version = nil if reset_lock_version |
||||
# we need to merge the JSON two times: |
||||
# In Pass 1 the representer only has custom fields for the current WP type |
||||
# After Pass 1 the correct type information is merged into the WP |
||||
# In Pass 2 the representer is created with the new type info and will be able |
||||
# to also parse custom fields successfully |
||||
merge_json_into_work_package!(work_package, request_body.to_json) |
||||
merge_json_into_work_package!(work_package, request_body.to_json) |
||||
rescue ::API::Errors::Form::InvalidResourceLink => e |
||||
fail ::API::Errors::Validation.new(e.message) |
||||
end |
||||
end |
||||
end |
||||
|
||||
def write_request_valid?(work_package, contract_class) |
||||
contract = contract_class.new(work_package, current_user) |
||||
|
||||
contract_valid = contract.validate |
||||
represented_valid = work_package.valid? |
||||
|
||||
return true if contract_valid && represented_valid |
||||
|
||||
# We need to merge the contract errors with the model errors in |
||||
# order to have them available at one place. |
||||
contract.errors.keys.each do |key| |
||||
contract.errors[key].each do |message| |
||||
work_package.errors.add(key, message) |
||||
end |
||||
end |
||||
|
||||
false |
||||
end |
||||
|
||||
def create_work_package_form(work_package, contract_class:, form_class:) |
||||
write_work_package_attributes(work_package, reset_lock_version: true) |
||||
write_request_valid?(work_package, contract_class) |
||||
|
||||
error = ::API::Errors::ErrorBase.create(work_package.errors) |
||||
|
||||
if error.is_a? ::API::Errors::Validation |
||||
status 200 |
||||
form_class.new(work_package, current_user: current_user) |
||||
else |
||||
fail error |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,73 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
# |
||||
# 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 doc/COPYRIGHT.rdoc for more details. |
||||
|
||||
require 'spec_helper' |
||||
|
||||
describe CreateWorkPackageService do |
||||
let(:user) { FactoryGirl.build(:user) } |
||||
let(:work_package) { FactoryGirl.build(:work_package) } |
||||
let(:project) { FactoryGirl.build(:project_with_types) } |
||||
|
||||
before do |
||||
allow(project).to receive(:add_work_package).and_return(work_package) |
||||
end |
||||
|
||||
subject(:service) { CreateWorkPackageService.new(user: user, project: project) } |
||||
|
||||
describe 'should use meaningful defaults for creation' do |
||||
it 'should use the project' do |
||||
expect(project).to receive(:add_work_package).with(hash_including(project: project)) |
||||
end |
||||
|
||||
it 'should use the user' do |
||||
expect(project).to receive(:add_work_package).with(hash_including(author: user)) |
||||
end |
||||
|
||||
it 'should use a type' do |
||||
expect(project).to receive(:add_work_package).with(hash_including(:type)) |
||||
end |
||||
|
||||
it 'should have a non-empty type' do |
||||
expect(project).to receive(:add_work_package).with(hash_excluding(type: nil)) |
||||
end |
||||
|
||||
after do |
||||
service.create |
||||
end |
||||
end |
||||
|
||||
it 'should create an unsaved work_package' do |
||||
expect(service.create.new_record?).to be_truthy |
||||
end |
||||
|
||||
it 'should #save records' do |
||||
wp = service.create |
||||
service.save(wp) |
||||
expect(WorkPackage.exists?(wp.id)).to be_truthy |
||||
end |
||||
end |
@ -0,0 +1,61 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
# |
||||
# 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 doc/COPYRIGHT.rdoc for more details. |
||||
|
||||
require 'spec_helper' |
||||
|
||||
describe ::API::Decorators::Single do |
||||
let(:user) { FactoryGirl.build(:user, member_in_project: project, member_through_role: role) } |
||||
let(:project) { FactoryGirl.create(:project_with_types) } |
||||
let(:role) { FactoryGirl.create(:role, permissions: permissions) } |
||||
let(:permissions) { [:view_work_packages] } |
||||
let(:model) { Object.new } |
||||
|
||||
context 'no user given' do |
||||
let(:single) { ::API::Decorators::Single.new(model, context: nil) } |
||||
|
||||
it 'should not authorize an empty user' do |
||||
expect(single.current_user_allowed_to(:view_work_packages, context: project)).to be_falsey |
||||
end |
||||
end |
||||
|
||||
context 'user given' do |
||||
let(:single) { ::API::Decorators::Single.new(model, current_user: user) } |
||||
|
||||
it 'should authorize for a given permission' do |
||||
expect(single.current_user_allowed_to(:view_work_packages, context: project)).to be_truthy |
||||
end |
||||
|
||||
context 'unauthorized user' do |
||||
let(:permissions) { [] } |
||||
|
||||
it 'should not authorize unauthorized user' do |
||||
expect(single.current_user_allowed_to(:view_work_packages, context: project)).to be_falsey |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,88 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
# |
||||
# 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 doc/COPYRIGHT.rdoc for more details. |
||||
|
||||
require 'spec_helper' |
||||
|
||||
describe ::API::Contracts::ModelContract do |
||||
let(:work_package) { FactoryGirl.build(:work_package) } |
||||
let(:child_contract) { ChildContract.new(work_package) } |
||||
let(:grand_child_contract) { GrandChildContract.new(work_package) } |
||||
|
||||
before do |
||||
child_contract.child_value = 0 |
||||
grand_child_contract.child_value = 0 |
||||
end |
||||
|
||||
describe 'child' do |
||||
class ChildContract < ::API::Contracts::ModelContract |
||||
attr_accessor :child_value |
||||
|
||||
attribute :child_attribute |
||||
attribute :overwritten_attribute do |
||||
@child_value = 1 |
||||
end |
||||
end |
||||
|
||||
it 'should collect its own writable attributes' do |
||||
expect(child_contract.writable_attributes).to include('child_attribute', |
||||
'overwritten_attribute') |
||||
end |
||||
|
||||
it 'should collect its own attribute validations' do |
||||
child_contract.validate |
||||
expect(child_contract.child_value).to eq(1) |
||||
end |
||||
end |
||||
|
||||
describe 'grand_child' do |
||||
class GrandChildContract < ChildContract |
||||
attr_accessor :grand_child_value |
||||
|
||||
attribute :grand_child_attribute |
||||
attribute :overwritten_attribute do |
||||
@grand_child_value = 2 |
||||
end |
||||
end |
||||
|
||||
it 'should consider its ancestor writable attributes' do |
||||
expect(grand_child_contract.writable_attributes).to include('child_attribute', |
||||
'overwritten_attribute', |
||||
'grand_child_attribute') |
||||
end |
||||
|
||||
it 'should not contain the same attribute twice' do |
||||
expect(grand_child_contract.writable_attributes.count).to eq(3) |
||||
end |
||||
|
||||
it 'should execute all the validations' do |
||||
grand_child_contract.validate |
||||
expect(grand_child_contract.child_value).to eq(1) |
||||
expect(grand_child_contract.grand_child_value).to eq(2) |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,119 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
# |
||||
# 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 doc/COPYRIGHT.rdoc for more details. |
||||
#++require 'rspec' |
||||
|
||||
require 'spec_helper' |
||||
|
||||
describe ::API::V3::WorkPackages::CreateFormRepresenter do |
||||
include API::V3::Utilities::PathHelper |
||||
|
||||
let(:work_package) { |
||||
FactoryGirl.build(:work_package, |
||||
id: 42, |
||||
created_at: DateTime.now, |
||||
updated_at: DateTime.now) |
||||
} |
||||
let(:current_user) { |
||||
FactoryGirl.build(:user, member_in_project: work_package.project) |
||||
} |
||||
let(:representer) { described_class.new(work_package, current_user: current_user) } |
||||
|
||||
context 'generation' do |
||||
subject(:generated) { representer.to_json } |
||||
|
||||
describe '_links' do |
||||
it do |
||||
is_expected.to be_json_eql( |
||||
api_v3_paths.create_work_package_form(work_package.project_id).to_json) |
||||
.at_path('_links/self/href') |
||||
end |
||||
|
||||
it { is_expected.to be_json_eql(:post.to_json).at_path('_links/self/method') } |
||||
|
||||
describe 'validate' do |
||||
it do |
||||
is_expected.to be_json_eql( |
||||
api_v3_paths.create_work_package_form(work_package.project_id).to_json) |
||||
.at_path('_links/validate/href') |
||||
end |
||||
|
||||
it { is_expected.to be_json_eql(:post.to_json).at_path('_links/validate/method') } |
||||
end |
||||
|
||||
describe 'preview markup' do |
||||
it do |
||||
is_expected.to be_json_eql( |
||||
api_v3_paths.render_markup( |
||||
link: api_v3_paths.project(work_package.project_id)).to_json) |
||||
.at_path('_links/previewMarkup/href') |
||||
end |
||||
|
||||
it { is_expected.to be_json_eql(:post.to_json).at_path('_links/previewMarkup/method') } |
||||
|
||||
it 'contains link to work package' do |
||||
expected_preview_link = |
||||
api_v3_paths.render_markup(format: 'textile', |
||||
link: "/api/v3/projects/#{work_package.project_id}") |
||||
expect(subject).to be_json_eql(expected_preview_link.to_json) |
||||
.at_path('_links/previewMarkup/href') |
||||
end |
||||
end |
||||
|
||||
describe 'commit' do |
||||
context 'valid work package' do |
||||
it do |
||||
is_expected.to be_json_eql( |
||||
api_v3_paths.work_packages_by_project(work_package.project_id).to_json) |
||||
.at_path('_links/commit/href') |
||||
end |
||||
|
||||
it { is_expected.to be_json_eql(:post.to_json).at_path('_links/commit/method') } |
||||
end |
||||
|
||||
context 'invalid work package' do |
||||
before { allow(work_package.errors).to receive(:empty?).and_return(false) } |
||||
|
||||
it { is_expected.not_to have_json_path('_links/commit/href') } |
||||
end |
||||
|
||||
context 'user with insufficient permissions' do |
||||
let(:role) { FactoryGirl.create(:role, permissions: []) } |
||||
let(:current_user) { |
||||
FactoryGirl.build(:user, |
||||
member_in_project: work_package.project, |
||||
member_through_role: role) |
||||
} |
||||
|
||||
before { allow(work_package.errors).to receive(:empty?).and_return(true) } |
||||
|
||||
it { is_expected.not_to have_json_path('_links/commit/href') } |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,82 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
# |
||||
# 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 doc/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'spec_helper' |
||||
|
||||
describe ::API::V3::WorkPackages::FormRepresenter do |
||||
include API::V3::Utilities::PathHelper |
||||
|
||||
let(:work_package) { |
||||
FactoryGirl.build(:work_package, |
||||
id: 42, |
||||
created_at: DateTime.now, |
||||
updated_at: DateTime.now) |
||||
} |
||||
let(:current_user) { |
||||
FactoryGirl.build(:user, member_in_project: work_package.project) |
||||
} |
||||
let(:representer) { described_class.new(work_package, current_user: current_user) } |
||||
|
||||
context 'generation' do |
||||
subject(:generated) { representer.to_json } |
||||
|
||||
it { is_expected.to be_json_eql('Form'.to_json).at_path('_type') } |
||||
|
||||
describe 'validation errors' do |
||||
context 'w/o errors' do |
||||
it { is_expected.to be_json_eql({}.to_json).at_path('_embedded/validationErrors') } |
||||
end |
||||
|
||||
context 'with errors' do |
||||
let(:subject_error_message) { 'Subject can\'t be blank!' } |
||||
let(:status_error_message) { 'Status can\'t be blank!' } |
||||
let(:errors) { |
||||
{ subject: [subject_error_message], status: [status_error_message] } |
||||
} |
||||
let(:subject_error) { ::API::Errors::Validation.new(subject_error_message) } |
||||
let(:status_error) { ::API::Errors::Validation.new(status_error_message) } |
||||
let(:api_subject_error) { ::API::V3::Errors::ErrorRepresenter.new(subject_error) } |
||||
let(:api_status_error) { ::API::V3::Errors::ErrorRepresenter.new(status_error) } |
||||
let(:api_errors) { { subject: api_subject_error, status: api_status_error } } |
||||
|
||||
before do |
||||
allow(work_package).to receive(:errors).and_return(errors) |
||||
allow(work_package.errors).to( |
||||
receive(:full_message).with(:subject, anything).and_return(subject_error_message)) |
||||
allow(work_package.errors).to( |
||||
receive(:full_message).with(:status, anything).and_return(status_error_message)) |
||||
end |
||||
|
||||
it { is_expected.to be_json_eql(api_errors.to_json).at_path('_embedded/validationErrors') } |
||||
end |
||||
end |
||||
|
||||
it { is_expected.to have_json_path('_embedded/payload') } |
||||
it { is_expected.to have_json_path('_embedded/schema') } |
||||
end |
||||
end |
@ -0,0 +1,68 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
# |
||||
# 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 doc/COPYRIGHT.rdoc for more details. |
||||
|
||||
require 'spec_helper' |
||||
|
||||
describe ::API::V3::WorkPackages::UpdateContract do |
||||
let(:work_package) { FactoryGirl.create(:work_package) } |
||||
let(:member) { FactoryGirl.build(:user) } |
||||
|
||||
subject(:contract) { described_class.new(work_package, member) } |
||||
|
||||
before do |
||||
allow(member).to receive(:allowed_to?).and_return(true) |
||||
end |
||||
|
||||
describe 'lock_version' do |
||||
context 'no lock_version present' do |
||||
before do |
||||
work_package.lock_version = nil |
||||
contract.validate |
||||
end |
||||
|
||||
it { expect(contract.errors).to include(:error_conflict) } |
||||
end |
||||
|
||||
context 'lock_version changed' do |
||||
before do |
||||
work_package.lock_version += 1 |
||||
contract.validate |
||||
end |
||||
|
||||
it { expect(contract.errors).to include(:error_conflict) } |
||||
end |
||||
|
||||
context 'lock_version present and unchanged' do |
||||
before do |
||||
contract.validate |
||||
end |
||||
|
||||
it { expect(contract.errors).not_to include(:error_conflict) } |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,103 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
# |
||||
# 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 doc/COPYRIGHT.rdoc for more details. |
||||
|
||||
require 'spec_helper' |
||||
|
||||
describe ::API::V3::WorkPackages::WorkPackagesSharedHelpers do |
||||
let(:work_package) { FactoryGirl.create(:work_package) } |
||||
let(:user) { FactoryGirl.build(:admin) } |
||||
let(:env) { { 'api.request.body' => { subject: 'foo' } } } |
||||
|
||||
let(:helper_class) { |
||||
Class.new do |
||||
include ::API::V3::WorkPackages::WorkPackagesSharedHelpers |
||||
|
||||
def initialize(user, env) |
||||
@user = user |
||||
@env = env |
||||
end |
||||
|
||||
def env |
||||
@env |
||||
end |
||||
|
||||
def current_user |
||||
@user |
||||
end |
||||
|
||||
def status(_code) |
||||
end |
||||
end |
||||
} |
||||
let(:helper) { helper_class.new(user, env) } |
||||
|
||||
describe '#create_work_package_form' do |
||||
subject do |
||||
helper.create_work_package_form(work_package, |
||||
contract_class: ::API::V3::WorkPackages::CreateContract, |
||||
form_class: ::API::V3::WorkPackages::CreateFormRepresenter) |
||||
end |
||||
|
||||
context 'valid parameters' do |
||||
it 'should return a form' do |
||||
expect(subject).to be_a(::API::V3::WorkPackages::CreateFormRepresenter) |
||||
end |
||||
end |
||||
|
||||
context 'invalid parameters' do |
||||
context 'validation errors' do |
||||
let(:env) { { 'api.request.body' => { subject: '' } } } |
||||
|
||||
it 'does not raise for validation errors' do |
||||
expect(subject.validation_errors.any?).to be_truthy |
||||
end |
||||
end |
||||
|
||||
context 'other errors' do |
||||
let(:env) { { 'api.request.body' => { percentageDone: 1 } } } |
||||
|
||||
subject do |
||||
lambda do |
||||
helper.create_work_package_form( |
||||
work_package, |
||||
contract_class: ::API::V3::WorkPackages::CreateContract, |
||||
form_class: ::API::V3::WorkPackages::CreateFormRepresenter) |
||||
end |
||||
end |
||||
|
||||
before do |
||||
allow(Setting).to receive(:work_package_done_ratio).and_return('status') |
||||
end |
||||
|
||||
it 'should return all other errors' do |
||||
expect(subject).to raise_error(API::Errors::UnwritableProperty) |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,54 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
# |
||||
# 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 doc/COPYRIGHT.rdoc for more details. |
||||
|
||||
require 'spec_helper' |
||||
require 'rack/test' |
||||
|
||||
describe ::API::V3::WorkPackages::CreateFormAPI do |
||||
include Rack::Test::Methods |
||||
include API::V3::Utilities::PathHelper |
||||
|
||||
let(:project) { FactoryGirl.create(:project, id: 5) } |
||||
let(:post_path) { api_v3_paths.create_work_package_form(project.id) } |
||||
let(:user) { FactoryGirl.build(:admin) } |
||||
|
||||
before do |
||||
allow(User).to receive(:current).and_return(user) |
||||
post post_path |
||||
end |
||||
|
||||
subject(:response) { last_response } |
||||
|
||||
it 'should return 200(OK)' do |
||||
expect(response.status).to eq(200) |
||||
end |
||||
|
||||
it 'should be of type form' do |
||||
expect(response.body).to be_json_eql('Form'.to_json).at_path('_type') |
||||
end |
||||
end |
@ -0,0 +1,148 @@ |
||||
#-- encoding: UTF-8 |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2015 the OpenProject Foundation (OPF) |
||||
# |
||||
# 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 doc/COPYRIGHT.rdoc for more details. |
||||
|
||||
require 'spec_helper' |
||||
require 'rack/test' |
||||
|
||||
describe API::V3::WorkPackages::WorkPackagesByProjectAPI, type: :request do |
||||
include Rack::Test::Methods |
||||
include API::V3::Utilities::PathHelper |
||||
|
||||
let(:project) { FactoryGirl.create(:project_with_types, is_public: false) } |
||||
|
||||
describe '#post' do |
||||
let(:status) { FactoryGirl.build(:status, is_default: true) } |
||||
let(:priority) { FactoryGirl.build(:priority, is_default: true) } |
||||
let(:parameters) { { subject: 'new work packages' } } |
||||
let(:permissions) { [:add_work_packages, :view_project] } |
||||
let(:role) { FactoryGirl.create(:role, permissions: permissions) } |
||||
let(:current_user) do |
||||
FactoryGirl.build(:user, member_in_project: project, member_through_role: role) |
||||
end |
||||
let(:path) { api_v3_paths.work_packages_by_project project.id } |
||||
|
||||
before do |
||||
status.save! |
||||
priority.save! |
||||
|
||||
allow(User).to receive(:current).and_return current_user |
||||
ActionMailer::Base.deliveries.clear |
||||
post path, parameters.to_json, 'CONTENT_TYPE' => 'application/json' |
||||
end |
||||
|
||||
context 'notifications' do |
||||
let(:permissions) { [:add_work_packages, :view_project, :view_work_packages] } |
||||
|
||||
it 'sends a mail by default' do |
||||
expect(ActionMailer::Base.deliveries.count).to eq(1) |
||||
end |
||||
|
||||
context 'without notifications' do |
||||
let(:path) { "#{api_v3_paths.work_packages_by_project(project.id)}?notify=false" } |
||||
|
||||
it 'should not send a mail' do |
||||
expect(ActionMailer::Base.deliveries.count).to eq(0) |
||||
end |
||||
end |
||||
|
||||
context 'with notifications' do |
||||
let(:path) { "#{api_v3_paths.work_packages_by_project(project.id)}?notify=true" } |
||||
|
||||
it 'should send a mail' do |
||||
expect(ActionMailer::Base.deliveries.count).to eq(1) |
||||
end |
||||
end |
||||
end |
||||
|
||||
it 'should return Created(201)' do |
||||
expect(last_response.status).to eq(201) |
||||
end |
||||
|
||||
it 'should create a work package' do |
||||
expect(WorkPackage.all.count).to eq(1) |
||||
end |
||||
|
||||
it 'should use the given parameters' do |
||||
expect(WorkPackage.first.subject).to eq(parameters[:subject]) |
||||
end |
||||
|
||||
context 'no permissions' do |
||||
let(:current_user) { FactoryGirl.build(:user) } |
||||
|
||||
it 'should hide the endpoint' do |
||||
expect(last_response.status).to eq(404) |
||||
end |
||||
end |
||||
|
||||
context 'view_project permission' do |
||||
# Note that this just removes the add_work_packages permission |
||||
# view_project is actually provided by being a member of the project |
||||
let(:permissions) { [:view_project] } |
||||
|
||||
it 'should point out the missing permission' do |
||||
expect(last_response.status).to eq(403) |
||||
end |
||||
end |
||||
|
||||
context 'empty parameters' do |
||||
let(:parameters) { {} } |
||||
|
||||
it_behaves_like 'constraint violation' do |
||||
let(:message) { "Subject can't be blank" } |
||||
end |
||||
|
||||
it 'should not create a work package' do |
||||
expect(WorkPackage.all.count).to eq(0) |
||||
end |
||||
end |
||||
|
||||
context 'bogus parameters' do |
||||
let(:parameters) { { bogus: nil } } |
||||
|
||||
it_behaves_like 'constraint violation' do |
||||
let(:message) { "Subject can't be blank" } |
||||
end |
||||
|
||||
it 'should not create a work package' do |
||||
expect(WorkPackage.all.count).to eq(0) |
||||
end |
||||
end |
||||
|
||||
context 'invalid value' do |
||||
let(:parameters) { { subject: nil } } |
||||
|
||||
it_behaves_like 'constraint violation' do |
||||
let(:message) { "Subject can't be blank" } |
||||
end |
||||
|
||||
it 'should not create a work package' do |
||||
expect(WorkPackage.all.count).to eq(0) |
||||
end |
||||
end |
||||
end |
||||
end |
Loading…
Reference in new issue