kanbanworkflowstimelinescrumrubyroadmapproject-planningproject-managementopenprojectangularissue-trackerifcgantt-chartganttbug-trackerboardsbcf
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.
536 lines
19 KiB
536 lines
19 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'
|
|
|
|
describe WikiController, type: :controller do
|
|
using_shared_fixtures :admin
|
|
|
|
describe 'actions' do
|
|
before do
|
|
allow(@controller).to receive(:set_localization)
|
|
|
|
@role = FactoryBot.create(:non_member)
|
|
login_as admin
|
|
|
|
@project = FactoryBot.create(:project)
|
|
@project.reload # to get the wiki into the proxy
|
|
|
|
# creating pages
|
|
@existing_page = FactoryBot.create(:wiki_page, wiki_id: @project.wiki.id,
|
|
title: 'ExistingPage')
|
|
|
|
# creating page contents
|
|
FactoryBot.create(:wiki_content, page_id: @existing_page.id,
|
|
author_id: admin.id)
|
|
end
|
|
|
|
shared_examples_for "a 'new' action" do
|
|
it 'assigns @project to the current project' do
|
|
get_page
|
|
|
|
expect(assigns[:project]).to eq(@project)
|
|
end
|
|
|
|
it 'assigns @page to a newly created wiki page' do
|
|
get_page
|
|
|
|
expect(assigns[:page]).to be_new_record
|
|
expect(assigns[:page]).to be_kind_of WikiPage
|
|
expect(assigns[:page].wiki).to eq(@project.wiki)
|
|
end
|
|
|
|
it 'assigns @content to a newly created wiki content' do
|
|
get_page
|
|
|
|
expect(assigns[:content]).to be_new_record
|
|
expect(assigns[:content]).to be_kind_of WikiContent
|
|
expect(assigns[:content].page).to eq(assigns[:page])
|
|
end
|
|
|
|
it 'renders the new action' do
|
|
get_page
|
|
|
|
expect(response).to render_template 'new'
|
|
end
|
|
end
|
|
|
|
describe 'new' do
|
|
let(:get_page) { get 'new', params: { project_id: @project } }
|
|
|
|
it_should_behave_like "a 'new' action"
|
|
end
|
|
|
|
describe 'new_child' do
|
|
let(:get_page) { get 'new_child', params: { project_id: @project, id: @existing_page.title } }
|
|
|
|
it_should_behave_like "a 'new' action"
|
|
|
|
it 'sets the parent page for the new page' do
|
|
get_page
|
|
|
|
expect(assigns[:page].parent).to eq(@existing_page)
|
|
end
|
|
|
|
it 'renders 404 if used with an unknown page title' do
|
|
get 'new_child', params: { project_id: @project, id: 'foobar' }
|
|
|
|
expect(response.status).to eq(404) # not found
|
|
end
|
|
end
|
|
|
|
describe 'show' do
|
|
let(:get_page) { get :show, params: { project_id: @project, id: 'wiki' } }
|
|
|
|
describe 'with an empty wiki and no permission to edit' do
|
|
let(:view_role) { FactoryBot.create :role, permissions: %w[view_wiki_pages] }
|
|
let(:user) { FactoryBot.create(:user, member_in_project: @project, member_through_role: view_role) }
|
|
|
|
it 'visiting the start page redirects to index' do
|
|
login_as user
|
|
get_page
|
|
expect(response).to redirect_to action: :index
|
|
expect(flash[:info]).to include I18n.t('wiki.page_not_editable_index')
|
|
end
|
|
end
|
|
end
|
|
|
|
describe 'edit' do
|
|
it 'will link to a parent page if it was set' do
|
|
get 'edit', params: { project_id: @project, id: 'foobar' }, flash: { _related_wiki_page_id: 1234 }
|
|
|
|
page = assigns[:page]
|
|
expect(page.parent_id).to eq 1234
|
|
end
|
|
end
|
|
|
|
describe 'create' do
|
|
describe 'successful action' do
|
|
it 'redirects to the show action' do
|
|
post 'create',
|
|
params: {
|
|
project_id: @project,
|
|
content: { text: 'h1. abc', page: { title: 'abc' } }
|
|
}
|
|
|
|
expect(response).to redirect_to action: 'show', project_id: @project, id: 'abc'
|
|
end
|
|
|
|
it 'saves a new WikiPage with proper content' do
|
|
post 'create',
|
|
params: {
|
|
project_id: @project,
|
|
content: { text: 'h1. abc', page: { title: 'abc' } }
|
|
}
|
|
|
|
page = @project.wiki.pages.find_by title: 'abc'
|
|
expect(page).not_to be_nil
|
|
expect(page.content.text).to eq('h1. abc')
|
|
end
|
|
end
|
|
|
|
describe 'unsuccessful action' do
|
|
it 'renders "wiki/new"' do
|
|
post 'create',
|
|
params: {
|
|
project_id: @project,
|
|
content: { text: 'h1. abc', page: { title: '' } }
|
|
}
|
|
|
|
expect(response).to render_template('new')
|
|
end
|
|
|
|
it 'assigns project to work with new template' do
|
|
post 'create',
|
|
params: {
|
|
project_id: @project,
|
|
content: { text: 'h1. abc', page: { title: '' } }
|
|
}
|
|
|
|
expect(assigns[:project]).to eq(@project)
|
|
end
|
|
|
|
it 'assigns wiki to work with new template' do
|
|
post 'create',
|
|
params: {
|
|
project_id: @project,
|
|
content: { text: 'h1. abc', page: { title: '' } }
|
|
}
|
|
|
|
expect(assigns[:wiki]).to eq(@project.wiki)
|
|
expect(assigns[:wiki]).not_to be_new_record
|
|
end
|
|
|
|
it 'assigns page to work with new template' do
|
|
post 'create',
|
|
params: {
|
|
project_id: @project,
|
|
content: { text: 'h1. abc', page: { title: '' } }
|
|
}
|
|
|
|
expect(assigns[:page]).to be_new_record
|
|
expect(assigns[:page].wiki.project).to eq(@project)
|
|
expect(assigns[:page].title).to eq('')
|
|
expect(assigns[:page]).not_to be_valid
|
|
end
|
|
|
|
it 'assigns content to work with new template' do
|
|
post 'create',
|
|
params: {
|
|
project_id: @project,
|
|
content: { text: 'h1. abc', page: { title: '' } }
|
|
}
|
|
|
|
expect(assigns[:content]).to be_new_record
|
|
expect(assigns[:content].page.wiki.project).to eq(@project)
|
|
expect(assigns[:content].text).to eq('h1. abc')
|
|
end
|
|
end
|
|
end
|
|
|
|
describe 'destroy' do
|
|
describe 'successful action' do
|
|
context 'when it is not the only wiki page' do
|
|
let(:wiki) { @project.wiki }
|
|
let(:redirect_page_after_destroy) { wiki.find_page(wiki.start_page) || wiki.pages.first }
|
|
|
|
before do
|
|
FactoryBot.create :wiki_page, wiki: wiki
|
|
end
|
|
|
|
it 'redirects to wiki#index' do
|
|
delete :destroy, params: { project_id: @project, id: @existing_page }
|
|
expect(response).to redirect_to action: 'index', project_id: @project, id: redirect_page_after_destroy
|
|
end
|
|
end
|
|
|
|
context 'when it is the only wiki page' do
|
|
it 'redirects to projects#show' do
|
|
delete :destroy, params: { project_id: @project, id: @existing_page }
|
|
expect(response).to redirect_to project_path(@project)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end # describe 'actions'
|
|
|
|
describe 'view related stuff' do
|
|
render_views
|
|
|
|
before :each do
|
|
allow(@controller).to receive(:set_localization)
|
|
allow(Setting).to receive(:login_required?).and_return(false)
|
|
|
|
@role = FactoryBot.create(:non_member)
|
|
|
|
@anon = User.anonymous.nil? ? FactoryBot.create(:anonymous) : User.anonymous
|
|
|
|
Role.anonymous.update name: I18n.t(:default_role_anonymous),
|
|
permissions: [:view_wiki_pages]
|
|
|
|
allow(User).to receive(:current).and_return admin
|
|
|
|
@project = FactoryBot.create(:public_project)
|
|
@project.reload # to get the wiki into the proxy
|
|
|
|
# creating pages
|
|
@page_default = FactoryBot.create(:wiki_page,
|
|
wiki_id: @project.wiki.id,
|
|
title: 'Wiki')
|
|
@page_with_content = FactoryBot.create(:wiki_page,
|
|
wiki_id: @project.wiki.id,
|
|
title: 'PagewithContent')
|
|
@page_without_content = FactoryBot.create(:wiki_page,
|
|
wiki_id: @project.wiki.id,
|
|
title: 'PagewithoutContent')
|
|
@unrelated_page = FactoryBot.create(:wiki_page,
|
|
wiki_id: @project.wiki.id,
|
|
title: 'UnrelatedPage')
|
|
|
|
# creating page contents
|
|
FactoryBot.create(:wiki_content, page_id: @page_default.id,
|
|
author_id: admin.id)
|
|
FactoryBot.create(:wiki_content, page_id: @page_with_content.id,
|
|
author_id: admin.id)
|
|
FactoryBot.create(:wiki_content, page_id: @unrelated_page.id,
|
|
author_id: admin.id)
|
|
|
|
# creating some child pages
|
|
@children = {}
|
|
[@page_with_content].each do |page|
|
|
child_page = FactoryBot.create(:wiki_page, wiki_id: @project.wiki.id,
|
|
parent_id: page.id,
|
|
title: page.title + ' child')
|
|
FactoryBot.create(:wiki_content, page_id: child_page.id,
|
|
author_id: admin.id)
|
|
|
|
@children[page] = child_page
|
|
end
|
|
end
|
|
|
|
describe '- main menu links' do
|
|
before do
|
|
@main_menu_item_for_page_with_content = FactoryBot.create(:wiki_menu_item,
|
|
navigatable_id: @project.wiki.id,
|
|
title: 'Item for Page with Content',
|
|
name: @page_with_content.slug)
|
|
|
|
@main_menu_item_for_new_wiki_page = FactoryBot.create(:wiki_menu_item,
|
|
navigatable_id: @project.wiki.id,
|
|
title: 'Item for new WikiPage',
|
|
name: 'new-wiki-page')
|
|
|
|
@other_menu_item = FactoryBot.create(:wiki_menu_item,
|
|
navigatable_id: @project.wiki.id,
|
|
title: 'Item for other page',
|
|
name: @unrelated_page.slug)
|
|
end
|
|
|
|
shared_examples_for 'all wiki menu items' do
|
|
it 'is inactive, when an unrelated page is shown' do
|
|
get 'show', params: { id: @unrelated_page.slug, project_id: @project.id }
|
|
|
|
expect(response).to be_successful
|
|
|
|
assert_select "#main-menu a.#{@wiki_menu_item.menu_identifier}-menu-item"
|
|
assert_select "#main-menu a.#{@wiki_menu_item.menu_identifier}-menu-item.selected", false
|
|
end
|
|
|
|
it "is inactive, when another wiki menu item's page is shown" do
|
|
get 'show', params: { id: @other_wiki_menu_item.name, project_id: @project.id }
|
|
|
|
expect(response).to be_successful
|
|
expect(response.body).to have_selector('.main-menu--children a.selected', count: 0)
|
|
|
|
assert_select "#main-menu a.#{@wiki_menu_item.menu_identifier}-menu-item"
|
|
assert_select "#main-menu a.#{@wiki_menu_item.menu_identifier}-menu-item.selected", false
|
|
end
|
|
|
|
it 'is active, when the given wiki menu item is shown' do
|
|
get 'show', params: { id: @wiki_menu_item.name, project_id: @project.id }
|
|
|
|
expect(response).to be_successful
|
|
|
|
assert_select "#main-menu a.#{@wiki_menu_item.menu_identifier}-menu-item.selected"
|
|
end
|
|
end
|
|
|
|
shared_examples_for 'all existing wiki menu items' do
|
|
# TODO: Add tests for new and toc options within menu item
|
|
it 'is active on parents item, when new page is shown' do
|
|
get 'new_child', params: { id: @wiki_menu_item.name, project_id: @project.identifier }
|
|
|
|
expect(response).to be_successful
|
|
|
|
assert_select "#main-menu a.#{@wiki_menu_item.menu_identifier}-menu-item.selected"
|
|
end
|
|
|
|
it 'is active, when a toc page is shown' do
|
|
get 'index', params: { id: @wiki_menu_item.name, project_id: @project.id }
|
|
|
|
expect(response).to be_successful
|
|
assert_select '#content h2', text: 'Table of Contents'
|
|
assert_select "#main-menu a.#{@wiki_menu_item.menu_identifier}-menu-item.selected"
|
|
end
|
|
end
|
|
|
|
shared_examples_for 'all wiki menu items with child pages' do
|
|
it 'is active, when the given wiki menu item is an ancestor of the shown page' do
|
|
get 'show', params: { id: @child_page.slug, project_id: @project.id }
|
|
|
|
expect(response).to be_successful
|
|
expect(response.body).to have_selector('#main-menu a.selected', count: 1)
|
|
|
|
assert_select "#main-menu a.#{@wiki_menu_item.menu_identifier}-menu-item.selected"
|
|
end
|
|
end
|
|
|
|
describe '- wiki menu item pointing to a saved wiki page' do
|
|
before do
|
|
@wiki_menu_item = @main_menu_item_for_page_with_content
|
|
@other_wiki_menu_item = @other_menu_item
|
|
@child_page = @children[@page_with_content]
|
|
end
|
|
|
|
it_should_behave_like 'all wiki menu items'
|
|
it_should_behave_like 'all existing wiki menu items'
|
|
it_should_behave_like 'all wiki menu items with child pages'
|
|
end
|
|
|
|
describe '- wiki menu item pointing to a new wiki page' do
|
|
before do
|
|
@wiki_menu_item = @main_menu_item_for_new_wiki_page
|
|
@other_wiki_menu_item = @other_menu_item
|
|
end
|
|
|
|
it_should_behave_like 'all wiki menu items'
|
|
end
|
|
|
|
describe '- wiki_menu_item containing special chars only' do
|
|
before do
|
|
@wiki_menu_item = FactoryBot.create(:wiki_menu_item,
|
|
navigatable_id: @project.wiki.id,
|
|
title: '?',
|
|
name: 'help')
|
|
@other_wiki_menu_item = @other_menu_item
|
|
end
|
|
|
|
it_should_behave_like 'all wiki menu items'
|
|
end
|
|
end
|
|
|
|
describe '- wiki sidebar' do
|
|
describe 'configure menu items link' do
|
|
describe 'on a show page' do
|
|
describe 'being authorized to configure menu items' do
|
|
it 'is visible' do
|
|
get 'show', params: { project_id: @project.id }
|
|
|
|
expect(response).to be_successful
|
|
|
|
assert_select '#content a', 'Configure menu item'
|
|
end
|
|
end
|
|
|
|
describe 'being unauthorized to configure menu items' do
|
|
before do
|
|
allow(User).to receive(:current).and_return @anon
|
|
end
|
|
|
|
it 'is invisible' do
|
|
get 'show', params: { project_id: @project.id }
|
|
|
|
expect(response).to be_successful
|
|
|
|
assert_select '#content a', text: 'Configure menu item', count: 0
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
describe 'new child page link' do
|
|
describe 'on an index page' do
|
|
describe 'being authorized to edit wiki pages' do
|
|
it 'is invisible' do
|
|
get 'index', params: { project_id: @project.id }
|
|
|
|
expect(response).to be_successful
|
|
|
|
assert_select '#content a', text: 'Wiki page', count: 0
|
|
end
|
|
end
|
|
|
|
describe 'being unauthorized to edit wiki pages' do
|
|
before do
|
|
allow(User).to receive(:current).and_return @anon
|
|
end
|
|
|
|
it 'is invisible' do
|
|
get 'index', params: { project_id: @project.id }
|
|
|
|
expect(response).to be_successful
|
|
|
|
assert_select '#content a', text: 'Wiki page', count: 0
|
|
end
|
|
end
|
|
end
|
|
|
|
describe 'on a wiki page' do
|
|
describe 'being authorized to edit wiki pages' do
|
|
describe 'with a wiki page present' do
|
|
it 'is visible' do
|
|
get 'show',
|
|
params: { id: @page_with_content.title, project_id: @project.identifier }
|
|
|
|
expect(response).to be_successful
|
|
|
|
# Expect to set back ref id
|
|
expect(flash[:_related_wiki_page_id]).to eq @page_with_content.id
|
|
|
|
assert_select "#content a[href='#{new_child_project_wiki_path(project_id: @project, id: @page_with_content.slug)}']", 'Wiki page'
|
|
end
|
|
end
|
|
|
|
describe 'with no wiki page present' do
|
|
it 'is invisible' do
|
|
get 'show', params: { id: 'i-am-a-ghostpage', project_id: @project.identifier }
|
|
|
|
expect(response).to be_successful
|
|
|
|
assert_select "#content a[href='#{new_child_project_wiki_path(project_id: @project, id: 'i-am-a-ghostpage')}']",
|
|
text: 'Wiki page', count: 0
|
|
end
|
|
end
|
|
end
|
|
|
|
describe 'being unauthorized to edit wiki pages' do
|
|
before do
|
|
allow(User).to receive(:current).and_return @anon
|
|
end
|
|
|
|
it 'is invisible' do
|
|
get 'show', params: { id: @page_with_content.title, project_id: @project.identifier }
|
|
|
|
expect(response).to be_successful
|
|
|
|
assert_select '#content a', text: 'Wiki page', count: 0
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
describe 'new page link' do
|
|
describe 'on a show page' do
|
|
describe 'being authorized to edit wiki pages' do
|
|
it 'is visible' do
|
|
get 'show', params: { project_id: @project.id }
|
|
|
|
expect(response).to be_successful
|
|
|
|
assert_select ".toolbar-items a[href='#{new_child_project_wiki_path(project_id: @project, id: 'wiki')}']", 'Wiki page'
|
|
end
|
|
end
|
|
|
|
describe 'being unauthorized to edit wiki pages' do
|
|
before do
|
|
allow(User).to receive(:current).and_return @anon
|
|
end
|
|
|
|
it 'is invisible' do
|
|
get 'show', params: { project_id: @project.id }
|
|
|
|
expect(response).to be_successful
|
|
|
|
assert_select '.toolbar-items a', text: 'Wiki page', count: 0
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|