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

908 lines
24 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 COPYRIGHT and LICENSE files 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(api_v3_paths.project_status(project_status.code).to_json)
.at_path("_links/status/href")
end
context 'requesting nonexistent project' do
let(:get_path) { api_v3_paths.project 9999 }
before do
response
end
it_behaves_like 'not found'
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'
end
context 'not being allowed to see the parent project' do
let!(:parent_memberships) do
end
it 'shows the `undisclosed` uri' do
expect(subject.body)
.to be_json_eql(API::V3::URN_UNDISCLOSED.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, members: { current_user => role })
project.update_attribute(:parent_id, parent_project.id)
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 'with filtering by capability action' do
let(:other_project) do
FactoryBot.create(:project, members: [current_user])
end
let(:projects) { [project, other_project] }
let(:role) { FactoryBot.create(:role, permissions: [:copy_projects]) }
let(:get_path) do
api_v3_paths.path_for :projects, filters: [{ "user_action": { "operator": "=", "values": ["projects/copy"] } }]
end
it_behaves_like 'API V3 collection response', 1, 1, 'Project'
it 'returns the project the current user has the capability in' 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
[26688] In-app notifications (#9399) * Add bell icon to icon font * Add in app notification in top menu * Add fullscreen modal * Add notification modal and items * Style items * Toggle details of item * Mark all read * Add no results box * wip specification for event api * Add events table, query and index * Send out events from WP notification mailer job There we have the recipients present * Add cleanup job for older events with a setting * Hide bell notification when not logged * Add specs for events API index/show * Fix setting yml key * remove pry in event creation * Fix before hook in events API to after_validation * Fix polymorphic association raising exception for aggregated journals * Fix typo in read_ian * Fix yml entry for mentioned * Add read/unread post actions to event API and add specs * Wire up API to frontend * Fix order on events * Switch to unread in notification * Add event query * rename WPEventService * route wp mail sending over events * rename spec methods * author becomes watcher * correct message call signature * rename events to notifications * renname parameter to reflect notification nature * create author watcher for existing work packages * Merge unreadCount from store * Take a stab at polymorphic representers * Fix link generation in polymorphic resources For journals, no title is being generated however * Fix frontend model for context * Use timer for polling * add notification_setting data layer * Fix show resource spec * Fix duplicate class in notification bell item * Add minimal feature spec for notification * API for notification settings * Persist notifications * adapt work package notification creation to notification settings * extract notified_on_all * consolidate wp#recipients * concentrate wp notification in journal service * simplify methods * Remove unused patch endpoint * Add specs for rendering and parsing notification settings * Contract spec * Update service spec * adapt specs * Angular notifications frontend commit e29dced64699eb5f2443b9307c78343c9a58d1ee Author: Wieland Lindenthal <w.lindenthal@forkmerge.com> Date: Mon Jun 21 17:34:50 2021 +0200 Create Akita store and query for notification settings commit 1a45c26c1a0c147d15393e49d2625aca4851a64d Author: Wieland Lindenthal <w.lindenthal@forkmerge.com> Date: Mon Jun 21 11:09:25 2021 +0200 Remove tabs from notificaition settings page commit 0ea21e90c13a197f8bf2cfba1b60ddcff4e5e827 Author: Oliver Günther <mail@oliverguenther.de> Date: Sun Jun 20 21:55:48 2021 +0200 WIP in app settings * migrate notification data * add project visible filter to project query * Add inline-create and table display grouped by project * Add notifications under admin/users * Remove notifications partial * Rename notififcations store to user preferences store * Add setting for self_notified and hook that up to the backend * Add aria-label to table checkboxes * Restyle table and toolbar * replace remains of mail_notifications attribute * initialize notification settings for new user * adapt my_preferences references * reenable no self notified for documents * adapt specs * Avoid has_many :notifcation_settings Rails magically autosaves the user's preferences when the user gets saved, which somehow also tries to save the notfifications even when unchanged. This breaks some specs such as the avatar upload spec. As we can't update the assocation through rails anyway, just delegate to the user for reading instead. * Restore update method of notification settings * Restore update spec * fix spec syntax * lint scss * linting * Fix content_tag for bell icon * Add feature specs for notification settings * Disable ContentTag cop * use visible filter to get projects for notification The visible filter will reduce the project list down to the set of projects visible to the user provided as a parameter. This includes public projects. * test for actual mail sending * adapt me resource path this.apiV3Service.users.me changed its type in 0d6c0b6bc7620de94e00e72b36d6cbc1ec4c8db4 * Implement changed migration * Linting * Add actor to notification representer * Fix factory creating a duplicate WP journal * Add work packages loading and journal details to notification entry component * IAN basic facets, keep and expanded states. * Fix notification bell spec * Render body separately and add auto updating relative time * Add fixedTime title * Add actor to notification entry * Fix clicking links on work package and project * Tiny styling changes on entry row * Disable count in notification if larger than 99 (wont fit) * Introduce virtual scrolling to entry table * allow delaying & prevent mail sending if ain read Introduces a setting to delay mail sending after a journal aggregation time has expired. That way, users can confirm a notification in app. If they do before the delay expires, no mail is sent out additionally for that user. * consolidate notifications (in&out) into shared admin menu Co-authored-by: ulferts <jens.ulferts@googlemail.com> Co-authored-by: Wieland Lindenthal <w.lindenthal@forkmerge.com>
3 years ago
context 'with filtering by visiblity' do
let(:public_project) do
# Otherwise, the public project is invisible
FactoryBot.create(:non_member)
FactoryBot.create(:public_project)
end
let(:member_project) do
FactoryBot.create(:project, members: { other_user => role })
end
let(:non_member_project) do
FactoryBot.create(:project)
end
let(:archived_member_project) do
FactoryBot.create(:project, members: { other_user => role }, active: false)
end
let(:projects) { [member_project, public_project, non_member_project, archived_member_project] }
let(:role) { FactoryBot.create(:role, permissions: []) }
let(:other_user) do
FactoryBot.create(:user)
end
let(:get_path) do
api_v3_paths.path_for :projects, filters: [{ "visible": { "operator": "=", "values": [other_user.id.to_s] } }]
end
current_user { admin }
it_behaves_like 'API V3 collection response', 2, 2, 'Project'
it 'contains the expected projects' do
expect(last_response.body)
.to be_json_eql(public_project.id.to_json)
.at_path('_embedded/elements/0/id')
expect(last_response.body)
.to be_json_eql(member_project.id.to_json)
.at_path('_embedded/elements/1/id')
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',
statusExplanation: { raw: "Some explanation." },
_links: {
status: {
href: api_v3_paths.project_status('off_track')
}
}
}.to_json
end
it 'sets the status' do
expect(last_response.body)
.to be_json_eql(api_v3_paths.project_status('off_track').to_json)
.at_path('_links/status/href')
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',
statusExplanation: "Some explanation.",
_links: {
status: {
href: api_v3_paths.project_status('faulty')
}
}
}.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
{
statusExplanation: {
raw: "Some explanation."
},
_links: {
status: {
href: nil
}
}
}
end
it 'alters the status' do
expect(last_response.body)
.to be_json_eql(nil.to_json)
.at_path('_links/status/href')
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
{
statusExplanation: {
raw: "Some explanation."
},
_links: {
status: {
href: api_v3_paths.project_status('off_track')
}
}
}
end
it 'alters the status' do
expect(last_response.body)
.to be_json_eql(api_v3_paths.project_status('off_track').to_json)
.at_path('_links/status/href')
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
{
_links: {
status: {
href: api_v3_paths.project_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'
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