mirror of
https://github.com/opf/openproject.git
synced 2026-06-14 03:30:14 +00:00
add a sprint GET end point to v3
This commit is contained in:
@@ -5706,6 +5706,7 @@ en:
|
||||
project: Undisclosed - The project is invisible because of lacking permissions.
|
||||
ancestor: Undisclosed - The ancestor is invisible because of lacking permissions.
|
||||
definingProject: Undisclosed - The project is invisible because of lacking permissions.
|
||||
definingWorkspace: Undisclosed - The workspace is invisible because of lacking permissions.
|
||||
|
||||
doorkeeper:
|
||||
pre_authorization:
|
||||
|
||||
@@ -70,7 +70,7 @@ module API
|
||||
representer: ::API::V3::Projects::ProjectRepresenter,
|
||||
skip_render:,
|
||||
link: ::API::V3::Workspaces::WorkspaceRepresenterFactory
|
||||
.create_link_lambda(name),
|
||||
.create_link_lambda(name, property_name: as),
|
||||
setter: ::API::V3::Workspaces::WorkspaceRepresenterFactory
|
||||
.create_setter_lambda(name)
|
||||
}
|
||||
|
||||
@@ -76,6 +76,10 @@ module Agile
|
||||
|
||||
validate :validate_only_one_active_sprint_per_project
|
||||
|
||||
include ::Scopes::Scoped
|
||||
|
||||
scopes :visible
|
||||
|
||||
# TODO: validate sharing is set to an allowed value, e.g. only admins may share systemwide (#71374, #71253)
|
||||
# TODO: implement sharing logic once it has been defined (#71374)
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) the OpenProject GmbH
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License version 3.
|
||||
#
|
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
# Copyright (C) 2010-2013 the ChiliProject Team
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# See COPYRIGHT and LICENSE files for more details.
|
||||
#++
|
||||
|
||||
module Agile::Sprints::Scopes
|
||||
module Visible
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
class_methods do
|
||||
# Returns all sprints the user is allowed to see.
|
||||
# A sprint is visible if the user has the :view_sprints permission
|
||||
# in the project the sprint belongs to.
|
||||
def visible(user = User.current)
|
||||
joins(:project)
|
||||
.merge(Project.allowed_to(user, :view_sprints))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -40,6 +40,10 @@ en:
|
||||
goal: "Sprint goal"
|
||||
name: "Sprint name"
|
||||
sharing: "Sharing"
|
||||
statuses:
|
||||
in_planning: "In planning"
|
||||
active: "Active"
|
||||
completed: "Completed"
|
||||
sprint:
|
||||
duration: "Sprint duration"
|
||||
work_package:
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) the OpenProject GmbH
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License version 3.
|
||||
#
|
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
# Copyright (C) 2010-2013 the ChiliProject Team
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# See COPYRIGHT and LICENSE files for more details.
|
||||
#++
|
||||
|
||||
require "roar/decorator"
|
||||
require "roar/json/hal"
|
||||
|
||||
module API
|
||||
module V3
|
||||
module Sprints
|
||||
class SprintRepresenter < ::API::Decorators::Single
|
||||
include API::Decorators::LinkedResource
|
||||
include API::V3::Workspaces::LinkedResource
|
||||
include API::Decorators::DateProperty
|
||||
|
||||
self_link
|
||||
|
||||
link :status do
|
||||
{
|
||||
href: "#{::API::V3::URN_PREFIX}sprints:status:#{represented.status}",
|
||||
title: I18n.t("activerecord.attributes.agile/sprint.statuses.#{represented.status}")
|
||||
}
|
||||
end
|
||||
|
||||
associated_project as: :definingWorkspace
|
||||
|
||||
property :id,
|
||||
render_nil: true
|
||||
|
||||
property :name,
|
||||
render_nil: true
|
||||
|
||||
date_property :start_date
|
||||
|
||||
date_property :finish_date
|
||||
|
||||
date_time_property :created_at
|
||||
date_time_property :updated_at
|
||||
|
||||
def _type
|
||||
"Sprint"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,49 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) the OpenProject GmbH
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License version 3.
|
||||
#
|
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
# Copyright (C) 2010-2013 the ChiliProject Team
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# See COPYRIGHT and LICENSE files for more details.
|
||||
#++
|
||||
|
||||
module API
|
||||
module V3
|
||||
module Sprints
|
||||
class SprintsAPI < ::API::OpenProjectAPI
|
||||
resources :sprints do
|
||||
route_param :id, type: Integer, desc: "Sprint ID" do
|
||||
after_validation do
|
||||
guard_feature_flag(:scrum_projects)
|
||||
|
||||
@sprint = Agile::Sprint.visible(current_user).find(params[:id])
|
||||
end
|
||||
|
||||
get &::API::V3::Utilities::Endpoints::Show.new(model: Agile::Sprint).mount
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -180,6 +180,14 @@ module OpenProject::Backlogs
|
||||
"#{root}/backlogs_types/#{id}"
|
||||
end
|
||||
|
||||
add_api_path :sprint do |id|
|
||||
"#{root}/sprints/#{id}"
|
||||
end
|
||||
|
||||
add_api_endpoint "API::V3::Root" do
|
||||
mount ::API::V3::Sprints::SprintsAPI
|
||||
end
|
||||
|
||||
config.to_prepare do
|
||||
OpenProject::Backlogs::Hooks::LayoutHook
|
||||
OpenProject::Backlogs::Hooks::UserSettingsHook
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) the OpenProject GmbH
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License version 3.
|
||||
#
|
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
# Copyright (C) 2010-2013 the ChiliProject Team
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# See COPYRIGHT and LICENSE files for more details.
|
||||
#++
|
||||
|
||||
require "spec_helper"
|
||||
|
||||
RSpec.describe API::V3::Sprints::SprintRepresenter, "rendering" do
|
||||
include API::V3::Utilities::PathHelper
|
||||
|
||||
let(:workspace) { build_stubbed(:project) }
|
||||
let(:start_date) { Date.new(2024, 1, 1) }
|
||||
let(:finish_date) { Date.new(2024, 1, 10) }
|
||||
let(:status) { "in_planning" }
|
||||
let(:sprint) do
|
||||
build_stubbed(:agile_sprint,
|
||||
project: workspace,
|
||||
status:,
|
||||
name: "Sprint 1",
|
||||
start_date:,
|
||||
finish_date:)
|
||||
end
|
||||
let(:current_user) { build_stubbed(:user) }
|
||||
let(:embed_links) { true }
|
||||
let(:representer) { described_class.create(sprint, current_user:, embed_links:) }
|
||||
|
||||
subject(:generated) { representer.to_json }
|
||||
|
||||
it { is_expected.to include_json("Sprint".to_json).at_path("_type") }
|
||||
|
||||
describe "links" do
|
||||
it { is_expected.to have_json_type(Object).at_path("_links") }
|
||||
|
||||
describe "self" do
|
||||
it_behaves_like "has a titled link" do
|
||||
let(:link) { "self" }
|
||||
let(:href) { api_v3_paths.sprint(sprint.id) }
|
||||
let(:title) { sprint.name }
|
||||
end
|
||||
end
|
||||
|
||||
describe "definingWorkspace" do
|
||||
it_behaves_like "has workspace linked" do
|
||||
let(:link) { "definingWorkspace" }
|
||||
end
|
||||
end
|
||||
|
||||
describe "status" do
|
||||
let(:link) { "status" }
|
||||
|
||||
context "with in_planning value" do
|
||||
it_behaves_like "has a titled link" do
|
||||
let(:href) { "urn:openproject-org:api:v3:sprints:status:in_planning" }
|
||||
let(:title) { I18n.t("activerecord.attributes.agile/sprint.statuses.in_planning") }
|
||||
end
|
||||
end
|
||||
|
||||
context "with active value" do
|
||||
let(:status) { "active" }
|
||||
|
||||
it_behaves_like "has a titled link" do
|
||||
let(:href) { "urn:openproject-org:api:v3:sprints:status:active" }
|
||||
let(:title) { I18n.t("activerecord.attributes.agile/sprint.statuses.active") }
|
||||
end
|
||||
end
|
||||
|
||||
context "with completed value" do
|
||||
let(:status) { "completed" }
|
||||
|
||||
it_behaves_like "has a titled link" do
|
||||
let(:href) { "urn:openproject-org:api:v3:sprints:status:completed" }
|
||||
let(:title) { I18n.t("activerecord.attributes.agile/sprint.statuses.completed") }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "properties" do
|
||||
describe "_type" do
|
||||
it_behaves_like "property", :_type do
|
||||
let(:value) { "Sprint" }
|
||||
end
|
||||
end
|
||||
|
||||
describe "id" do
|
||||
it_behaves_like "property", :id do
|
||||
let(:value) { sprint.id }
|
||||
end
|
||||
end
|
||||
|
||||
describe "name" do
|
||||
it_behaves_like "property", :name do
|
||||
let(:value) { sprint.name }
|
||||
end
|
||||
end
|
||||
|
||||
describe "startDate" do
|
||||
it_behaves_like "has ISO 8601 date only" do
|
||||
let(:date) { start_date }
|
||||
let(:json_path) { "startDate" }
|
||||
end
|
||||
end
|
||||
|
||||
describe "finishDate" do
|
||||
it_behaves_like "has ISO 8601 date only" do
|
||||
let(:date) { finish_date }
|
||||
let(:json_path) { "finishDate" }
|
||||
end
|
||||
end
|
||||
|
||||
describe "createdAt" do
|
||||
it_behaves_like "has UTC ISO 8601 date and time" do
|
||||
let(:date) { sprint.created_at }
|
||||
let(:json_path) { "createdAt" }
|
||||
end
|
||||
end
|
||||
|
||||
describe "updatedAt" do
|
||||
it_behaves_like "has UTC ISO 8601 date and time" do
|
||||
let(:date) { sprint.updated_at }
|
||||
let(:json_path) { "updatedAt" }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "embedded" do
|
||||
it_behaves_like "has workspace embedded" do
|
||||
let(:embedded_path) { "_embedded/definingWorkspace" }
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,105 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) the OpenProject GmbH
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License version 3.
|
||||
#
|
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
# Copyright (C) 2010-2013 the ChiliProject Team
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# See COPYRIGHT and LICENSE files for more details.
|
||||
#++
|
||||
|
||||
require "spec_helper"
|
||||
|
||||
RSpec.describe Agile::Sprints::Scopes::Visible do
|
||||
shared_let(:project) { create(:project) }
|
||||
shared_let(:other_project) { create(:project) }
|
||||
shared_let(:sprint) { create(:agile_sprint, project:) }
|
||||
shared_let(:sprint_in_other_project) { create(:agile_sprint, project: other_project) }
|
||||
shared_let(:role) { create(:project_role, permissions: [:view_sprints]) }
|
||||
shared_let(:user_with_permission) do
|
||||
create(:user).tap do |u|
|
||||
create(:member, project:, user: u, roles: [role])
|
||||
end
|
||||
end
|
||||
shared_let(:user_with_permission_in_both) do
|
||||
create(:user).tap do |u|
|
||||
create(:member, project:, user: u, roles: [role])
|
||||
create(:member, project: other_project, user: u, roles: [role])
|
||||
end
|
||||
end
|
||||
shared_let(:user_without_permission) do
|
||||
create(:user).tap do |u|
|
||||
create(:member,
|
||||
project:,
|
||||
user: u,
|
||||
roles: [create(:project_role, permissions: [:view_work_packages])])
|
||||
end
|
||||
end
|
||||
shared_let(:user_without_membership) { create(:user) }
|
||||
|
||||
subject { Agile::Sprint.visible(current_user) }
|
||||
|
||||
context "for a user with view_sprints in one project" do
|
||||
current_user { user_with_permission }
|
||||
|
||||
it "returns the sprint in that project" do
|
||||
expect(subject).to contain_exactly(sprint)
|
||||
end
|
||||
|
||||
it "does not return sprints from projects the user has no permission in" do
|
||||
expect(subject).not_to include(sprint_in_other_project)
|
||||
end
|
||||
end
|
||||
|
||||
context "for a user with view_sprnts in both projects" do
|
||||
current_user { user_with_permission_in_both }
|
||||
|
||||
it "returns sprints from both projects" do
|
||||
expect(subject).to contain_exactly(sprint, sprint_in_other_project)
|
||||
end
|
||||
end
|
||||
|
||||
context "for a user with a different permission but not view_sprints" do
|
||||
current_user { user_without_permission }
|
||||
|
||||
it "returns no sprints" do
|
||||
expect(subject).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context "for a user without any membership" do
|
||||
current_user { user_without_membership }
|
||||
|
||||
it "returns no sprints" do
|
||||
expect(subject).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context "when called without a user argument" do
|
||||
current_user { user_with_permission }
|
||||
|
||||
it "uses User.current" do
|
||||
expect(Agile::Sprint.visible).to contain_exactly(sprint)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,80 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
#-- copyright
|
||||
# OpenProject is an open source project management software.
|
||||
# Copyright (C) the OpenProject GmbH
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License version 3.
|
||||
#
|
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
|
||||
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
||||
# Copyright (C) 2010-2013 the ChiliProject Team
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# See COPYRIGHT and LICENSE files for more details.
|
||||
#++
|
||||
|
||||
require "spec_helper"
|
||||
require "rack/test"
|
||||
|
||||
RSpec.describe "API v3 Sprint resource", content_type: :json do
|
||||
include Rack::Test::Methods
|
||||
include API::V3::Utilities::PathHelper
|
||||
|
||||
shared_let(:project) { create(:project, public: false) }
|
||||
shared_let(:sprint) { create(:agile_sprint, project:) }
|
||||
|
||||
let(:permissions) { %i[view_sprints] }
|
||||
|
||||
current_user do
|
||||
create(:user, member_with_permissions: { project => permissions })
|
||||
end
|
||||
|
||||
describe "GET /api/v3/sprints/:id", with_flag: :scrum_projects do
|
||||
let(:get_path) { api_v3_paths.sprint(sprint.id) }
|
||||
|
||||
before do
|
||||
get get_path
|
||||
end
|
||||
|
||||
context "for a user with view_sprints permission" do
|
||||
it_behaves_like "successful response", 200, "Sprint"
|
||||
end
|
||||
|
||||
context "for a user without view_sprints permission" do
|
||||
let(:permissions) { [] }
|
||||
|
||||
it_behaves_like "not found"
|
||||
end
|
||||
|
||||
context "for an anonymous user" do
|
||||
let(:current_user) { User.anonymous }
|
||||
|
||||
it_behaves_like "unauthenticated access"
|
||||
end
|
||||
|
||||
context "for a sprint that does not exist" do
|
||||
let(:get_path) { api_v3_paths.sprint(0) }
|
||||
|
||||
it_behaves_like "not found"
|
||||
end
|
||||
|
||||
context "when the feature flag is turned off", with_flag: { scrum_projects: false } do
|
||||
it_behaves_like "not found"
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user