OpenProject is the leading open source project management software.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
openproject/spec/requests/api/v3/project_resource_spec.rb

838 lines
21 KiB

#-- copyright
# OpenProject is an open source project management software.
# Copyright (C) 2012-2021 the OpenProject GmbH
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License version 3.
#
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
# Copyright (C) 2006-2013 Jean-Philippe Lang
# Copyright (C) 2010-2013 the ChiliProject Team
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# See docs/COPYRIGHT.rdoc for more details.
#++
require 'spec_helper'
require 'rack/test'
describe 'API v3 Project resource', type: :request, content_type: :json do
include Rack::Test::Methods
include API::V3::Utilities::PathHelper
let(:current_user) do
FactoryBot.create(:user, member_in_project: project, member_through_role: role)
end
let(:admin) { FactoryBot.create(:admin) }
let(:project) do
FactoryBot.create(:project, public: false, status: project_status, active: project_active)
end
let(:project_active) { true }
let(:project_status) do
FactoryBot.build(:project_status, project: nil)
end
let(:other_project) do
FactoryBot.create(:project, public: false)
end
let(:role) { FactoryBot.create(:role) }
let(:custom_field) do
FactoryBot.create(:text_project_custom_field)
end
let(:custom_value) do
CustomValue.create(custom_field: custom_field,
value: '1234',
customized: project)
end
before do
login_as(current_user)
end
describe '#get /projects/:id' do
let(:get_path) { api_v3_paths.project project.id }
let!(:parent_project) do
FactoryBot.create(:project, public: false).tap do |p|
project.parent = p
project.save!
end
end
let!(:parent_memberships) do
FactoryBot.create(:member,
user: current_user,
project: parent_project,
roles: [FactoryBot.create(:role, permissions: [])])
end
subject(:response) do
get get_path
last_response
end
context 'logged in user' do
it 'responds with 200 OK' do
expect(subject.status).to eq(200)
end
it 'responds with the correct project' do
expect(subject.body).to include_json('Project'.to_json).at_path('_type')
expect(subject.body).to be_json_eql(project.identifier.to_json).at_path('identifier')
end
it 'links to the parent project' do
expect(subject.body)
.to be_json_eql(api_v3_paths.project(parent_project.id).to_json)
.at_path('_links/parent/href')
end
it 'includes custom fields' do
custom_value
expect(subject.body)
.to be_json_eql(custom_value.value.to_json)
.at_path("customField#{custom_field.id}/raw")
end
it 'includes the project status' do
expect(subject.body)
.to be_json_eql(project_status.explanation.to_json)
.at_path("statusExplanation/raw")
expect(subject.body)
.to be_json_eql(project_status.code.tr('_', ' ').to_json)
.at_path("status")
end
context 'requesting nonexistent project' do
let(:get_path) { api_v3_paths.project 9999 }
before do
response
end
it_behaves_like 'not found' do
let(:id) { 9999 }
let(:type) { 'Project' }
end
end
context 'requesting project without sufficient permissions' do
let(:get_path) { api_v3_paths.project other_project.id }
before do
response
end
it_behaves_like 'not found' do
let(:id) { another_project.id.to_s }
let(:type) { 'Project' }
end
end
context 'not being allowed to see the parent project' do
let!(:parent_memberships) do
end
it 'has no path to the parent' do
expect(subject.body)
.to be_json_eql(nil.to_json)
.at_path('_links/parent/href')
end
end
context 'with the project being archived/inactive' do
let(:project_active) { false }
context 'with the user being admin' do
let(:current_user) { admin }
it 'responds with 200 OK' do
expect(subject.status).to eq(200)
end
it 'responds with the correct project' do
expect(subject.body).to include_json('Project'.to_json).at_path('_type')
expect(subject.body).to be_json_eql(project.identifier.to_json).at_path('identifier')
end
end
context 'with the user being no admin' do
it 'responds with 404' do
expect(subject.status).to eq(404)
end
end
end
end
10 years ago
context 'not logged in user' do
let(:current_user) { FactoryBot.create(:anonymous) }
10 years ago
before do
get get_path
end
it_behaves_like 'not found'
end
end
describe '#get /projects' do
let(:get_path) { api_v3_paths.projects }
let(:response) { last_response }
let(:projects) { [project, other_project] }
before do
projects
get get_path
end
it 'succeeds' do
expect(response.status)
.to eql(200)
end
it_behaves_like 'API V3 collection response', 1, 1, 'Project'
context 'filtering for project by ancestor' do
let(:projects) { [project, other_project, parent_project] }
let(:parent_project) do
parent_project = FactoryBot.create(:project, public: false)
project.update_attribute(:parent_id, parent_project.id)
parent_project.add_member! current_user, role
parent_project
end
let(:filter_query) do
[{ ancestor: { operator: '=', values: [parent_project.id.to_s] } }]
end
let(:get_path) do
"#{api_v3_paths.projects}?filters=#{CGI.escape(JSON.dump(filter_query))}"
end
it_behaves_like 'API V3 collection response', 1, 1, 'Project'
it 'returns the child project' do
expect(response.body)
.to be_json_eql(api_v3_paths.project(project.id).to_json)
.at_path('_embedded/elements/0/_links/self/href')
end
end
context 'filtering for principals (members)' do
let(:other_project) do
Role.non_member
FactoryBot.create(:public_project)
end
let(:projects) { [project, other_project] }
context 'if filtering for a value' do
let(:filter_query) do
[{ principal: { operator: '=', values: [current_user.id.to_s] } }]
end
let(:get_path) do
"#{api_v3_paths.projects}?filters=#{CGI.escape(JSON.dump(filter_query))}"
end
it 'returns the filtered for value' do
expect(response.body)
.to be_json_eql(project.id.to_json)
.at_path('_embedded/elements/0/id')
end
end
context 'if filtering for a negative value' do
let(:filter_query) do
[{ principal: { operator: '!', values: [current_user.id.to_s] } }]
end
let(:get_path) do
"#{api_v3_paths.projects}?filters=#{CGI.escape(JSON.dump(filter_query))}"
end
it 'returns the projects not matching the value' do
expect(last_response.body)
.to be_json_eql(other_project.id.to_json)
.at_path('_embedded/elements/0/id')
end
end
end
context 'with the project being archived/inactive' do
let(:project_active) { false }
let(:projects) { [project] }
context 'with the user being admin' do
let(:current_user) { admin }
it 'responds with 200 OK' do
expect(last_response.status).to eq(200)
end
it_behaves_like 'API V3 collection response', 1, 1, 'Project'
end
context 'with the user being no admin' do
it_behaves_like 'API V3 collection response', 0, 0, 'Project'
it 'responds with 200' do
expect(last_response.status).to eq(200)
end
end
end
end
describe '#post /projects' do
let(:current_user) do
FactoryBot.create(:user).tap do |u|
FactoryBot.create(:global_member,
principal: u,
roles: [global_role])
end
end
let(:global_role) do
FactoryBot.create(:global_role, permissions: permissions)
end
let(:permissions) { [:add_project] }
let(:path) { api_v3_paths.projects }
let(:body) do
{
identifier: 'new_project_identifier',
name: 'Project name'
}.to_json
end
before do
login_as current_user
post path, body
end
it 'responds with 201 CREATED' do
expect(last_response.status).to eq(201)
end
it 'creates a project' do
expect(Project.count)
.to eql(1)
end
it 'returns the created project' do
expect(last_response.body)
.to be_json_eql('Project'.to_json)
.at_path('_type')
expect(last_response.body)
.to be_json_eql('Project name'.to_json)
.at_path('name')
end
context 'with a status' do
let(:body) do
{
identifier: 'new_project_identifier',
name: 'Project name',
status: 'off track',
statusExplanation: { raw: "Some explanation." }
}.to_json
end
it 'sets the status' do
expect(last_response.body)
.to be_json_eql('off track'.to_json)
.at_path('status')
expect(last_response.body)
.to be_json_eql(
{
"format": "markdown",
Fix/update wysiwyg styles (#8844) This is a refactoring of the CSS classes in the WYSIWYG editor. The classes now use proper BEM and are almost completely independent of other CSS. It also includes small style refactorings, like a reduction of heading size in attribute fields, and an increase in heading size in all other instances. * Initial class definitions * Added more classes * Added Table of Contents basics * CkEditor applying custom CSS classes to p, h1, h2, h3, h4, h5, h6, li and blockquote * CKEditorInspector removed * op css class for headings * op css class for paragraphs * op css class for code/code block * adapt specs to altered markdown/html generation * adapt grid/budget representers to altered signature * op css class for lists * op css class for toc * op css class for links * Start working on typography css * op css class for tables * Fixing more typography, trying out larger headers * Applying custom classes to li, a, blockquote, figure, table, tr, td, th, image, codeblock, figcaption and macros * adapt specs to altered link classes * op css class for images * apply user content container class throughout application * CSS alignment custom classes applied to table * op css class for task list checkbox * Added task checkbox class * amend list checkbox class in backend * op css class for table thead element * adapt specs on image html generation * Updated table and typography styles * Update typography and figure styles * Figure overflow handling * Table alignment styles + ckEditor styles removed * rename wiki-anchor to op-uc-link_permalink * wrap table in div as well as figure * Updated code-block * Update permalinks * Fixed a lot about tables * Removed Description header from work-packages page * Fix frontend styles * Add placeholder styling, fix toc * Fixed figure print * working with table aligns * Custom class add to task lists * Custom classes applied to theads * op-uc-container custom class added to container * Codeblocks inside pre elements * Fix: single <code> and <a> tags * explicitly require overwritten gem class Apparently, the gem is not loaded yet when it is registered as a filter when in eager loading mode * adapt spec expectation to altered toc rendering * CkInspector removed * Latest ckeditor changes * remove highlight css class from wiki content * allow html pipleline to handle macros with additional classes * Fixed a lot of print css for tables * Add general print css back in * Update Table of Contents styling * Custom classes on ul, ol, li and task-lists * Revert "Custom classes on ul, ol, li and task-lists" This reverts commit 0d27d281378b324330ea2f25632de898269e2122. * Custom classes on ul, ol, li and task-lists * Custom classes on column's th * remove placeholder class when rendering * WOrking on task lists * Changing task-list classes, changed tests * Updated list styles * Remove unused todo list styles * remove checked in binstubs * Fix table of contents * adapt todo list handing in backend pipeline * adapt specs to altered css classes * Add numbers to table of contents * Better comments in table of contents * Fix: wrap single <table> with a <figure> * Fixes to todo list design * Updated todo list scss to fix nested lists * adapt selectors in table spec * Update table styles * Improve table borders more * Custom classes specs * Fix: no need to remove regular list classes when its type changes * Add modifier for inline headings * Update table editing styles * Remove break-word tests * wrap images just like tables * Update figure content styles * Fix: All tests passing (ul.op-uc-list_task-list) * div.op-uc-figure--content wrapping tables * Specs for figures wrappers div.op-uc-figure--content * Fix: add custom classes to links and codes again * Table wrapper div reverted + specs * Fix inline palceholders * Custom macro type classes * Add basic macro placeholder changes * Move heading permalink after text * Fix word-break spec * Sending figure styles to the backend (width) * extend test to take ckeditor placeholder into account * avoid adding bem classes multiple times * attempt to fix flickering spec * Removing image spinner when uploading finishes * adapt spec expectations Co-authored-by: Aleix Suau <info@macrofonoestudio.es> Co-authored-by: ulferts <jens.ulferts@googlemail.com>
4 years ago
"html": "<p class=\"op-uc-p\">Some explanation.</p>",
"raw": "Some explanation."
}.to_json
)
.at_path("statusExplanation")
end
it 'creates a project and a status' do
expect(Project.count)
.to eql(1)
expect(Projects::Status.count)
.to eql(1)
end
end
context 'with a custom field' do
let(:body) do
{
identifier: 'new_project_identifier',
name: 'Project name',
"customField#{custom_field.id}": {
"raw": "CF text"
}
}.to_json
end
it 'sets the cf value' do
expect(last_response.body)
.to be_json_eql("CF text".to_json)
.at_path("customField#{custom_field.id}/raw")
end
end
context 'without permission to create projects' do
let(:permissions) { [] }
it 'responds with 403' do
expect(last_response.status).to eq(403)
end
it 'creates no project' do
expect(Project.count)
.to eql(0)
end
end
context 'with missing name' do
let(:body) do
{
identifier: 'some_identifier'
}.to_json
end
it 'responds with 422' do
expect(last_response.status).to eq(422)
end
it 'creates no project' do
expect(Project.count)
.to eql(0)
end
it 'denotes the error' do
expect(last_response.body)
.to be_json_eql('Error'.to_json)
.at_path('_type')
expect(last_response.body)
.to be_json_eql("Name can't be blank.".to_json)
.at_path('message')
end
end
context 'with a faulty status' do
let(:body) do
{
identifier: 'new_project_identifier',
name: 'Project name',
status: 'faulty',
statusExplanation: "Some explanation."
}.to_json
end
it 'responds with 422' do
expect(last_response.status).to eq(422)
end
it 'creates no project' do
expect(Project.count)
.to eql(0)
end
it 'denotes the error' do
expect(last_response.body)
.to be_json_eql('Error'.to_json)
.at_path('_type')
expect(last_response.body)
.to be_json_eql("Status is not set to one of the allowed values.".to_json)
.at_path('message')
end
end
end
describe '#patch /projects/:id' do
let(:current_user) do
FactoryBot.create(:user,
member_in_project: project,
member_with_permissions: permissions)
end
let(:permissions) { [:edit_project] }
let(:path) { api_v3_paths.project(project.id) }
let(:body) do
{
identifier: 'new_project_identifier',
name: 'Project name'
}
end
before do
login_as current_user
patch path, body.to_json
end
it 'responds with 200 OK' do
expect(last_response.status).to eq(200)
end
it 'alters the project' do
project.reload
expect(project.name)
.to eql(body[:name])
expect(project.identifier)
.to eql(body[:identifier])
end
it 'returns the updated project' do
expect(last_response.body)
.to be_json_eql('Project'.to_json)
.at_path('_type')
expect(last_response.body)
.to be_json_eql(body[:name].to_json)
.at_path('name')
end
context 'with a custom field' do
let(:body) do
{
"customField#{custom_field.id}": {
"raw": "CF text"
}
}
end
it 'responds with 200 OK' do
expect(last_response.status).to eq(200)
end
it 'sets the cf value' do
expect(project.reload.send("custom_field_#{custom_field.id}"))
.to eql("CF text")
end
end
context 'without permission to patch projects' do
let(:permissions) { [] }
it 'responds with 403' do
expect(last_response.status).to eq(403)
end
it 'does not change the project' do
attributes_before = project.attributes
expect(project.reload.name)
.to eql(attributes_before['name'])
end
end
context 'with a nil status' do
let(:body) do
{
status: nil,
statusExplanation: {
raw: "Some explanation."
}
}
end
it 'alters the status' do
expect(last_response.body)
.to be_json_eql(nil.to_json)
.at_path('status')
status = project.status.reload
expect(status.code).to be_nil
expect(status.explanation).to eq 'Some explanation.'
expect(last_response.body)
.to be_json_eql(
{
"format": "markdown",
Fix/update wysiwyg styles (#8844) This is a refactoring of the CSS classes in the WYSIWYG editor. The classes now use proper BEM and are almost completely independent of other CSS. It also includes small style refactorings, like a reduction of heading size in attribute fields, and an increase in heading size in all other instances. * Initial class definitions * Added more classes * Added Table of Contents basics * CkEditor applying custom CSS classes to p, h1, h2, h3, h4, h5, h6, li and blockquote * CKEditorInspector removed * op css class for headings * op css class for paragraphs * op css class for code/code block * adapt specs to altered markdown/html generation * adapt grid/budget representers to altered signature * op css class for lists * op css class for toc * op css class for links * Start working on typography css * op css class for tables * Fixing more typography, trying out larger headers * Applying custom classes to li, a, blockquote, figure, table, tr, td, th, image, codeblock, figcaption and macros * adapt specs to altered link classes * op css class for images * apply user content container class throughout application * CSS alignment custom classes applied to table * op css class for task list checkbox * Added task checkbox class * amend list checkbox class in backend * op css class for table thead element * adapt specs on image html generation * Updated table and typography styles * Update typography and figure styles * Figure overflow handling * Table alignment styles + ckEditor styles removed * rename wiki-anchor to op-uc-link_permalink * wrap table in div as well as figure * Updated code-block * Update permalinks * Fixed a lot about tables * Removed Description header from work-packages page * Fix frontend styles * Add placeholder styling, fix toc * Fixed figure print * working with table aligns * Custom class add to task lists * Custom classes applied to theads * op-uc-container custom class added to container * Codeblocks inside pre elements * Fix: single <code> and <a> tags * explicitly require overwritten gem class Apparently, the gem is not loaded yet when it is registered as a filter when in eager loading mode * adapt spec expectation to altered toc rendering * CkInspector removed * Latest ckeditor changes * remove highlight css class from wiki content * allow html pipleline to handle macros with additional classes * Fixed a lot of print css for tables * Add general print css back in * Update Table of Contents styling * Custom classes on ul, ol, li and task-lists * Revert "Custom classes on ul, ol, li and task-lists" This reverts commit 0d27d281378b324330ea2f25632de898269e2122. * Custom classes on ul, ol, li and task-lists * Custom classes on column's th * remove placeholder class when rendering * WOrking on task lists * Changing task-list classes, changed tests * Updated list styles * Remove unused todo list styles * remove checked in binstubs * Fix table of contents * adapt todo list handing in backend pipeline * adapt specs to altered css classes * Add numbers to table of contents * Better comments in table of contents * Fix: wrap single <table> with a <figure> * Fixes to todo list design * Updated todo list scss to fix nested lists * adapt selectors in table spec * Update table styles * Improve table borders more * Custom classes specs * Fix: no need to remove regular list classes when its type changes * Add modifier for inline headings * Update table editing styles * Remove break-word tests * wrap images just like tables * Update figure content styles * Fix: All tests passing (ul.op-uc-list_task-list) * div.op-uc-figure--content wrapping tables * Specs for figures wrappers div.op-uc-figure--content * Fix: add custom classes to links and codes again * Table wrapper div reverted + specs * Fix inline palceholders * Custom macro type classes * Add basic macro placeholder changes * Move heading permalink after text * Fix word-break spec * Sending figure styles to the backend (width) * extend test to take ckeditor placeholder into account * avoid adding bem classes multiple times * attempt to fix flickering spec * Removing image spinner when uploading finishes * adapt spec expectations Co-authored-by: Aleix Suau <info@macrofonoestudio.es> Co-authored-by: ulferts <jens.ulferts@googlemail.com>
4 years ago
"html": "<p class=\"op-uc-p\">Some explanation.</p>",
"raw": "Some explanation."
}.to_json
)
.at_path("statusExplanation")
end
end
context 'with a status' do
let(:body) do
{
status: 'off track',
statusExplanation: {
raw: "Some explanation."
}
}
end
it 'alters the status' do
expect(last_response.body)
.to be_json_eql('off track'.to_json)
.at_path('status')
expect(last_response.body)
.to be_json_eql(
{
"format": "markdown",
Fix/update wysiwyg styles (#8844) This is a refactoring of the CSS classes in the WYSIWYG editor. The classes now use proper BEM and are almost completely independent of other CSS. It also includes small style refactorings, like a reduction of heading size in attribute fields, and an increase in heading size in all other instances. * Initial class definitions * Added more classes * Added Table of Contents basics * CkEditor applying custom CSS classes to p, h1, h2, h3, h4, h5, h6, li and blockquote * CKEditorInspector removed * op css class for headings * op css class for paragraphs * op css class for code/code block * adapt specs to altered markdown/html generation * adapt grid/budget representers to altered signature * op css class for lists * op css class for toc * op css class for links * Start working on typography css * op css class for tables * Fixing more typography, trying out larger headers * Applying custom classes to li, a, blockquote, figure, table, tr, td, th, image, codeblock, figcaption and macros * adapt specs to altered link classes * op css class for images * apply user content container class throughout application * CSS alignment custom classes applied to table * op css class for task list checkbox * Added task checkbox class * amend list checkbox class in backend * op css class for table thead element * adapt specs on image html generation * Updated table and typography styles * Update typography and figure styles * Figure overflow handling * Table alignment styles + ckEditor styles removed * rename wiki-anchor to op-uc-link_permalink * wrap table in div as well as figure * Updated code-block * Update permalinks * Fixed a lot about tables * Removed Description header from work-packages page * Fix frontend styles * Add placeholder styling, fix toc * Fixed figure print * working with table aligns * Custom class add to task lists * Custom classes applied to theads * op-uc-container custom class added to container * Codeblocks inside pre elements * Fix: single <code> and <a> tags * explicitly require overwritten gem class Apparently, the gem is not loaded yet when it is registered as a filter when in eager loading mode * adapt spec expectation to altered toc rendering * CkInspector removed * Latest ckeditor changes * remove highlight css class from wiki content * allow html pipleline to handle macros with additional classes * Fixed a lot of print css for tables * Add general print css back in * Update Table of Contents styling * Custom classes on ul, ol, li and task-lists * Revert "Custom classes on ul, ol, li and task-lists" This reverts commit 0d27d281378b324330ea2f25632de898269e2122. * Custom classes on ul, ol, li and task-lists * Custom classes on column's th * remove placeholder class when rendering * WOrking on task lists * Changing task-list classes, changed tests * Updated list styles * Remove unused todo list styles * remove checked in binstubs * Fix table of contents * adapt todo list handing in backend pipeline * adapt specs to altered css classes * Add numbers to table of contents * Better comments in table of contents * Fix: wrap single <table> with a <figure> * Fixes to todo list design * Updated todo list scss to fix nested lists * adapt selectors in table spec * Update table styles * Improve table borders more * Custom classes specs * Fix: no need to remove regular list classes when its type changes * Add modifier for inline headings * Update table editing styles * Remove break-word tests * wrap images just like tables * Update figure content styles * Fix: All tests passing (ul.op-uc-list_task-list) * div.op-uc-figure--content wrapping tables * Specs for figures wrappers div.op-uc-figure--content * Fix: add custom classes to links and codes again * Table wrapper div reverted + specs * Fix inline palceholders * Custom macro type classes * Add basic macro placeholder changes * Move heading permalink after text * Fix word-break spec * Sending figure styles to the backend (width) * extend test to take ckeditor placeholder into account * avoid adding bem classes multiple times * attempt to fix flickering spec * Removing image spinner when uploading finishes * adapt spec expectations Co-authored-by: Aleix Suau <info@macrofonoestudio.es> Co-authored-by: ulferts <jens.ulferts@googlemail.com>
4 years ago
"html": "<p class=\"op-uc-p\">Some explanation.</p>",
"raw": "Some explanation."
}.to_json
)
.at_path("statusExplanation")
end
it 'persists the altered status' do
project_status.reload
expect(project_status.code)
.to eql('off_track')
expect(project_status.explanation)
.to eql('Some explanation.')
end
end
context 'with faulty name' do
let(:body) do
{
name: nil
}
end
it 'responds with 422' do
expect(last_response.status).to eq(422)
end
it 'does not change the project' do
attributes_before = project.attributes
expect(project.reload.name)
.to eql(attributes_before['name'])
end
it 'denotes the error' do
expect(last_response.body)
.to be_json_eql('Error'.to_json)
.at_path('_type')
expect(last_response.body)
.to be_json_eql("Name can't be blank.".to_json)
.at_path('message')
end
end
context 'with a faulty status' do
let(:body) do
{
status: "bogus"
}
end
it 'responds with 422' do
expect(last_response.status).to eq(422)
end
it 'does not change the project status' do
code_before = project_status.code
expect(project_status.reload.code)
.to eql(code_before)
end
it 'denotes the error' do
expect(last_response.body)
.to be_json_eql('Error'.to_json)
.at_path('_type')
expect(last_response.body)
.to be_json_eql("Status is not set to one of the allowed values.".to_json)
.at_path('message')
end
end
context 'deactivating (archiving) the project' do
context 'for an admin' do
let(:current_user) do
FactoryBot.create(:admin)
end
let(:project) do
FactoryBot.create(:project).tap do |p|
p.children << child_project
end
end
let(:child_project) do
FactoryBot.create(:project)
end
let(:body) do
{
active: false
}
end
it 'responds with 200 OK' do
expect(last_response.status)
.to eql(200)
end
it 'archives the project' do
expect(project.reload.active)
.to be_falsey
end
it 'archives the child project' do
expect(child_project.reload.active)
.to be_falsey
end
end
context 'for a non admin' do
let(:body) do
{
active: false
}
end
it 'responds with 403' do
expect(last_response.status)
.to eql(403)
end
it 'does not alter the project' do
expect(project.reload.active)
.to be_truthy
end
end
end
end
describe '#delete /api/v3/projects/:id' do
let(:path) { api_v3_paths.project(project.id) }
let(:setup) {}
before do
login_as current_user
setup
delete path
# run the deletion job
perform_enqueued_jobs
end
subject { last_response }
context 'with required permissions (admin)' do
let(:current_user) { FactoryBot.create(:admin) }
it 'responds with HTTP No Content' do
expect(subject.status).to eq 204
end
it 'deletes the project' do
expect(Project.exists?(project.id)).to be_falsey
end
context 'for a project with work packages' do
let(:work_package) { FactoryBot.create(:work_package, project: project) }
let(:setup) { work_package }
it 'deletes the work packages' do
expect(WorkPackage.exists?(work_package.id)).to be_falsey
end
end
context 'for a project with members' do
let(:member) do
FactoryBot.create(:member,
project: project,
principal: current_user,
roles: [FactoryBot.create(:role)])
end
let(:member_role) { member.member_roles.first }
let(:setup) do
member
member_role
end
it 'deletes the member' do
expect(Member.exists?(member.id)).to be_falsey
end
it 'deletes the MemberRole' do
expect(MemberRole.exists?(member_role.id)).to be_falsey
end
end
context 'for a project with a forum' do
let(:forum) do
FactoryBot.create(:forum,
project: project)
end
let(:setup) do
forum
end
it 'deletes the forum' do
expect(Forum.exists?(forum.id)).to be_falsey
end
end
context 'for a non-existent project' do
let(:path) { api_v3_paths.project 0 }
it_behaves_like 'not found' do
let(:id) { 0 }
let(:type) { 'Project' }
end
end
context 'for a project which has a version foreign work packages refer to' do
let(:version) { FactoryBot.create(:version, project: project) }
let(:work_package) { FactoryBot.create(:work_package, version: version) }
let(:setup) { work_package }
it 'responds with 422' do
expect(subject.status).to eq 422
end
it 'explains the error' do
expect(subject.body)
.to be_json_eql(I18n.t(:'activerecord.errors.models.project.foreign_wps_reference_version').to_json)
.at_path('message')
end
end
end
context 'without required permissions' do
it 'responds with 403' do
expect(subject.status).to eq 403
end
end
end
end