diff options
Diffstat (limited to 'spec/controllers')
3 files changed, 192 insertions, 498 deletions
diff --git a/spec/controllers/projects/wiki_directories_controller_spec.rb b/spec/controllers/projects/wiki_directories_controller_spec.rb deleted file mode 100644 index b09e1bc2ca4..00000000000 --- a/spec/controllers/projects/wiki_directories_controller_spec.rb +++ /dev/null @@ -1,52 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -describe Projects::WikiDirectoriesController do - set(:project) { create(:project, :public, :repository) } - - let(:user) { project.owner } - let(:project_wiki) { ProjectWiki.new(project, user) } - let(:wiki) { project_wiki.wiki } - let(:dir_slug) { 'the-directory' } - let(:dir_contents) { [create(:wiki_page)] } - let(:the_dir) { WikiDirectory.new(dir_slug, dir_contents) } - - before do - allow(controller).to receive(:find_dir).and_return(the_dir) - - sign_in(user) - end - - describe 'GET #show' do - let(:show_params) do - { - namespace_id: project.namespace, - project_id: project, - id: dir_slug - } - end - - before do - get :show, params: show_params - end - - context 'the directory is empty' do - let(:the_dir) { nil } - - it { is_expected.to render_template('empty') } - end - - context 'the directory does exist' do - it { is_expected.to render_template('show') } - - it 'sets the wiki_dir attribute' do - expect(assigns(:wiki_dir)).to eq(the_dir) - end - - it 'assigns the wiki pages' do - expect(assigns(:wiki_pages)).to eq(dir_contents) - end - end - end -end diff --git a/spec/controllers/projects/wiki_pages_controller_spec.rb b/spec/controllers/projects/wiki_pages_controller_spec.rb deleted file mode 100644 index 01a84fbbf20..00000000000 --- a/spec/controllers/projects/wiki_pages_controller_spec.rb +++ /dev/null @@ -1,399 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -describe Projects::WikiPagesController do - set(:project) { create(:project, :public, :repository) } - let(:user) { project.owner } - let(:project_wiki) { ProjectWiki.new(project, user) } - let(:wiki) { project_wiki.wiki } - let(:wiki_title) { 'page-title-test' } - let(:parent_ids) { { namespace_id: project.namespace.path, project_id: project.name } } - let(:redirect_destination) { Rails.application.routes.recognize_path(response.redirect_url) } - - before do - create_page(wiki_title, 'hello world') - - sign_in(user) - end - - after do - destroy_page(wiki_title) - end - - def helper - Helper.instance - end - - class Helper - include Singleton - include ActionView::Helpers::UrlHelper - end - - describe 'GET #new' do - subject { get :new, params: parent_ids } - - it 'redirects to #show and appends a `random_title` param' do - subject - - expect(response).to have_http_status(302) - - expect(redirect_destination) - .to include(parent_ids.merge(controller: 'projects/wiki_pages', action: 'show')) - - expect(response.redirect_url).to match(/\?random_title=true\Z/) - end - end - - describe 'GET #show' do - render_views - let(:requested_wiki_page) { wiki_title } - let(:random_title) { nil } - - subject do - get :show, params: { - namespace_id: project.namespace, - project_id: project, - id: requested_wiki_page, - random_title: random_title - } - end - - context 'when the wiki repo cannot be created' do - before do - allow(controller).to receive(:load_wiki) { raise ProjectWiki::CouldNotCreateWikiError } - end - - it 'redirects to the project path' do - headers = { 'Location' => a_string_ending_with(Gitlab::Routing.url_helpers.project_path(project)) } - - subject - - expect(response).to be_redirect - expect(response.header.to_hash).to include(headers) - end - end - - context 'when the page exists' do - it 'limits the retrieved pages for the sidebar' do - expect(controller).to receive(:load_wiki).and_return(project_wiki) - - # Sidebar entries - expect(project_wiki).to receive(:list_pages).with(limit: 15).and_call_original - - subject - - expect(response).to have_http_status(:ok) - expect(response.body).to include(wiki_title) - end - - context 'when page content encoding is invalid' do - it 'sets flash error' do - allow(controller).to receive(:valid_encoding?).and_return(false) - - subject - - expect(response).to have_http_status(:ok) - expect(flash[:notice]).to eq 'The content of this page is not encoded in UTF-8. Edits can only be made via the Git repository.' - end - end - end - - context 'when the page does not exist' do - let(:requested_wiki_page) { 'this-page-does-not-yet-exist' } - - context 'the current user can create wiki pages' do - it { is_expected.to render_template('edit') } - - it 'makes a call to see if the wiki is empty' do - expect(controller).to receive(:load_wiki).and_return(project_wiki) - expect(project_wiki).to receive(:list_pages).once.with(limit: anything).and_call_original - expect(project_wiki).to receive(:list_pages).with(limit: 1).and_call_original - subject - end - - describe 'assigned title' do - shared_examples :wiki_page_with_correct_title do - it 'assigns the correct title' do - subject - - expect(assigns(:page)).to have_attributes(title: assigned_title) - end - end - - context 'random_title is absent' do - let(:random_title) { nil } - - it_behaves_like :wiki_page_with_correct_title do - let(:assigned_title) { WikiPage.unhyphenize(requested_wiki_page) } - end - end - - context 'random_title is present' do - let(:random_title) { true } - - it_behaves_like :wiki_page_with_correct_title do - let(:assigned_title) { be_empty } - end - end - end - end - - context 'the current user cannot create wiki pages' do - before do - forbid_controller_ability! :create_wiki - end - it { is_expected.to render_template('missing_page') } - end - end - - context 'when page is a file' do - include WikiHelpers - - let(:path) { upload_file_to_wiki(project, user, file_name) } - - before do - get :show, params: { namespace_id: project.namespace, project_id: project, id: path } - end - - context 'when file is an image' do - let(:file_name) { 'dk.png' } - - it 'delivers the image' do - expect(response.headers['Content-Disposition']).to match(/^inline/) - expect(response.headers[Gitlab::Workhorse::DETECT_HEADER]).to eq "true" - end - - context 'when file is a svg' do - let(:file_name) { 'unsanitized.svg' } - - it 'delivers the image' do - expect(response.headers['Content-Disposition']).to match(/^inline/) - expect(response.headers[Gitlab::Workhorse::DETECT_HEADER]).to eq "true" - end - end - end - - context 'when file is a pdf' do - let(:file_name) { 'git-cheat-sheet.pdf' } - - it 'sets the content type to sets the content response headers' do - expect(response.headers['Content-Disposition']).to match(/^inline/) - expect(response.headers[Gitlab::Workhorse::DETECT_HEADER]).to eq "true" - end - end - end - end - - describe 'POST #preview_markdown' do - let(:page_id) { 'page/path' } - let(:markdown_text) { '*Markdown* text' } - let(:wiki_page) { create(:wiki_page, wiki: project_wiki, attrs: { title: wiki_title }) } - let(:processed_md) { json_response.fetch('body') } - - let(:preview_params) do - { namespace_id: project.namespace, project_id: project, id: wiki_page.slug, text: markdown_text } - end - - before do - post :preview_markdown, params: preview_params - end - - it 'renders json in a correct format' do - expect(response).to have_http_status(:ok) - expect(json_response).to include('body' => String, 'references' => Hash) - end - - describe 'double brackets within backticks' do - let(:markdown_text) do - <<-HEREDOC - `[[do_not_linkify]]` - ``` - [[also_do_not_linkify]] - ``` - HEREDOC - end - - it "does not linkify double brackets inside code blocks as expected" do - expect(processed_md).to include('[[do_not_linkify]]', '[[also_do_not_linkify]]') - end - end - - describe 'link re-writing' do - let(:links) do - [ - { text: 'regular link', path: 'regular' }, - { text: 'relative link 1', path: '../relative' }, - { text: 'relative link 2', path: './relative' }, - { text: 'relative link 3', path: './e/f/relative' }, - { text: 'spaced link', path: 'title with spaces' } - ] - end - - shared_examples :wiki_link_rewriter do - let(:markdown_text) { links.map { |text:, path:| "[#{text}](#{path})" }.join("\n") } - let(:expected_links) do - links.zip(paths).map do |(link, path)| - helper.link_to(link[:text], "#{project_wiki.wiki_page_path}/#{path}") - end - end - - it 'processes the links correctly' do - expect(processed_md).to include(*expected_links) - end - end - - context 'the current page has spaces in its title' do - let(:wiki_title) { 'page a/page b/page c/page d' } - it_behaves_like :wiki_link_rewriter do - let(:paths) do - ['regular', - 'page-a/page-b/relative', - 'page-a/page-b/page-c/relative', - 'page-a/page-b/page-c/e/f/relative', - 'title%20with%20spaces'] - end - end - end - - context 'the current page has an unproblematic title' do - let(:wiki_title) { 'a/b/c/d' } - it_behaves_like :wiki_link_rewriter do - let(:paths) do - ['regular', 'a/b/relative', 'a/b/c/relative', 'a/b/c/e/f/relative', 'title%20with%20spaces'] - end - end - end - - context "when there are hyphens in the page name" do - let(:wiki_title) { 'page-a/page-b/page-c/page-d' } - it_behaves_like :wiki_link_rewriter do - let(:paths) do - ['regular', - 'page-a/page-b/relative', - 'page-a/page-b/page-c/relative', - 'page-a/page-b/page-c/e/f/relative', - 'title%20with%20spaces'] - end - end - end - end - end - - describe 'GET #edit' do - subject { get(:edit, params: { namespace_id: project.namespace, project_id: project, id: wiki_title }) } - - context 'when page content encoding is invalid' do - it 'redirects to show' do - allow(controller).to receive(:valid_encoding?).and_return(false) - - subject - - expect(response).to redirect_to(project_wiki_path(project, project_wiki.list_pages.first)) - end - end - - context 'when page content encoding is valid' do - render_views - - it 'shows the edit page' do - subject - - expect(response).to have_http_status(:ok) - expect(response.body).to include('Edit Page') - end - end - end - - describe 'PATCH #update' do - let(:new_title) { 'New title' } - let(:new_content) { 'New content' } - subject do - patch(:update, - params: { - namespace_id: project.namespace, - project_id: project, - id: wiki_title, - wiki_page: { title: new_title, content: new_content } - }) - end - - context 'when page content encoding is invalid' do - it 'redirects to show' do - allow(controller).to receive(:valid_encoding?).and_return(false) - - subject - expect(response).to redirect_to(project_wiki_path(project, project_wiki.list_pages.first)) - end - end - - context 'when page content encoding is valid' do - render_views - - it 'updates the page' do - subject - - wiki_page = project_wiki.list_pages(load_content: true).first - - expect(wiki_page.title).to eq new_title - expect(wiki_page.content).to eq new_content - end - end - end - - describe 'GET #history' do - before do - allow(controller) - .to receive(:can?) - .with(any_args) - .and_call_original - - # The :create_wiki permission is irrelevant to reading history. - expect(controller) - .not_to receive(:can?) - .with(anything, :create_wiki, any_args) - - allow(controller) - .to receive(:can?) - .with(anything, :read_wiki, any_args) - .and_return(allow_read_wiki) - end - - shared_examples 'fetching history' do |expected_status| - before do - get :history, params: { namespace_id: project.namespace, project_id: project, id: wiki_title } - end - - it "returns status #{expected_status}" do - expect(response).to have_http_status(expected_status) - end - end - - it_behaves_like 'fetching history', :ok do - let(:allow_read_wiki) { true } - - it 'assigns @page_versions' do - expect(assigns(:page_versions)).to be_present - end - end - - it_behaves_like 'fetching history', :not_found do - let(:allow_read_wiki) { false } - end - end - - private - - def create_page(name, content) - wiki.write_page(name, :markdown, content, commit_details(name)) - end - - def commit_details(name) - Gitlab::Git::Wiki::CommitDetails.new(user.id, user.username, user.name, user.email, "created page #{name}") - end - - def destroy_page(title, dir = '') - page = wiki.page(title: title, dir: dir) - project_wiki.delete_page(page, "test commit") - end -end diff --git a/spec/controllers/projects/wikis_controller_spec.rb b/spec/controllers/projects/wikis_controller_spec.rb index 7fbefa5787b..f46da908218 100644 --- a/spec/controllers/projects/wikis_controller_spec.rb +++ b/spec/controllers/projects/wikis_controller_spec.rb @@ -4,10 +4,10 @@ require 'spec_helper' describe Projects::WikisController do let_it_be(:project) { create(:project, :public, :repository) } - let_it_be(:user) { project.owner } - let_it_be(:project_wiki) { ProjectWiki.new(project, user) } - let_it_be(:wiki) { project_wiki.wiki } - let_it_be(:wiki_title) { 'page title test' } + let(:user) { project.owner } + let(:project_wiki) { ProjectWiki.new(project, user) } + let(:wiki) { project_wiki.wiki } + let(:wiki_title) { 'page title test' } before do create_page(wiki_title, 'hello world') @@ -19,86 +19,231 @@ describe Projects::WikisController do destroy_page(wiki_title) end - describe 'GET #pages' do - subject do - get :pages, params: { namespace_id: project.namespace, project_id: project, id: wiki_title }.merge(extra_params) + describe 'GET #new' do + subject { get :new, params: { namespace_id: project.namespace, project_id: project } } + + it 'redirects to #show and appends a `random_title` param' do + subject + + expect(response).to have_http_status(302) + expect(Rails.application.routes.recognize_path(response.redirect_url)).to include( + controller: 'projects/wikis', + action: 'show' + ) + expect(response.redirect_url).to match(/\?random_title=true\Z/) end + end - let(:extra_params) { {} } + describe 'GET #pages' do + subject { get :pages, params: { namespace_id: project.namespace, project_id: project, id: wiki_title } } it 'does not load the pages content' do expect(controller).to receive(:load_wiki).and_return(project_wiki) + expect(project_wiki).to receive(:list_pages).twice.and_call_original subject end + end - describe 'illegal params' do - shared_examples :a_bad_request do - it do - expect { subject }.to raise_error(ActionController::BadRequest) - end - end + describe 'GET #history' do + before do + allow(controller) + .to receive(:can?) + .with(any_args) + .and_call_original - describe ':sort' do - let(:extra_params) { { sort: 'wibble' } } + # The :create_wiki permission is irrelevant to reading history. + expect(controller) + .not_to receive(:can?) + .with(anything, :create_wiki, any_args) - it_behaves_like :a_bad_request - end + allow(controller) + .to receive(:can?) + .with(anything, :read_wiki, any_args) + .and_return(allow_read_wiki) + end - describe ':direction' do - let(:extra_params) { { direction: 'wibble' } } + shared_examples 'fetching history' do |expected_status| + before do + get :history, params: { namespace_id: project.namespace, project_id: project, id: wiki_title } + end - it_behaves_like :a_bad_request + it "returns status #{expected_status}" do + expect(response).to have_http_status(expected_status) end + end - describe ':show_children' do - let(:extra_params) { { show_children: 'wibble' } } + it_behaves_like 'fetching history', :ok do + let(:allow_read_wiki) { true } - it_behaves_like :a_bad_request + it 'assigns @page_versions' do + expect(assigns(:page_versions)).to be_present end end - shared_examples 'sorting-and-nesting' do |sort_key, default_nesting| - context "the user is sorting by #{sort_key}" do - let(:extra_params) { sort_params.merge(nesting_params) } - let(:sort_params) { { sort: sort_key } } - let(:nesting_params) { {} } + it_behaves_like 'fetching history', :not_found do + let(:allow_read_wiki) { false } + end + end + + describe 'GET #show' do + render_views + + let(:random_title) { nil } + + subject { get :show, params: { namespace_id: project.namespace, project_id: project, id: id, random_title: random_title } } + + context 'when page exists' do + let(:id) { wiki_title } + + it 'limits the retrieved pages for the sidebar' do + expect(controller).to receive(:load_wiki).and_return(project_wiki) + expect(project_wiki).to receive(:list_pages).with(limit: 15).and_call_original + + subject + + expect(response).to have_http_status(:ok) + expect(assigns(:page).title).to eq(wiki_title) + end + + context 'when page content encoding is invalid' do + it 'sets flash error' do + allow(controller).to receive(:valid_encoding?).and_return(false) - before do subject + + expect(response).to have_http_status(:ok) + expect(flash[:notice]).to eq('The content of this page is not encoded in UTF-8. Edits can only be made via the Git repository.') end + end + end + + context 'when the page does not exist' do + let(:id) { 'does not exist' } - it "sets nesting to #{default_nesting} by default" do - expect(assigns :nesting).to eq default_nesting + before do + subject + end + + it 'builds a new wiki page with the id as the title' do + expect(assigns(:page).title).to eq(id) + end + + context 'when a random_title param is present' do + let(:random_title) { true } + + it 'builds a new wiki page with no title' do + expect(assigns(:page).title).to be_empty end + end + end - it 'hides children if the default requires it' do - expect(assigns :show_children).to be(default_nesting != ProjectWiki::NESTING_CLOSED) + context 'when page is a file' do + include WikiHelpers + + let(:id) { upload_file_to_wiki(project, user, file_name) } + + before do + subject + end + + context 'when file is an image' do + let(:file_name) { 'dk.png' } + + it 'delivers the image' do + expect(response.headers['Content-Disposition']).to match(/^inline/) + expect(response.headers[Gitlab::Workhorse::DETECT_HEADER]).to eq "true" end - ProjectWiki::NESTINGS.each do |nesting| - context "the user explicitly passes show_children = #{nesting}" do - let(:nesting_params) { { show_children: nesting } } + context 'when file is a svg' do + let(:file_name) { 'unsanitized.svg' } - it 'sets nesting to the provided value' do - expect(assigns :nesting).to eq nesting - end + it 'delivers the image' do + expect(response.headers['Content-Disposition']).to match(/^inline/) + expect(response.headers[Gitlab::Workhorse::DETECT_HEADER]).to eq "true" end end + end - context 'the user wants children hidden' do - let(:nesting_params) { { show_children: 'hidden' } } + context 'when file is a pdf' do + let(:file_name) { 'git-cheat-sheet.pdf' } - it 'hides children' do - expect(assigns :show_children).to be false - end + it 'sets the content type to sets the content response headers' do + expect(response.headers['Content-Disposition']).to match(/^inline/) + expect(response.headers[Gitlab::Workhorse::DETECT_HEADER]).to eq "true" end end end + end + + describe 'POST #preview_markdown' do + it 'renders json in a correct format' do + post :preview_markdown, params: { namespace_id: project.namespace, project_id: project, id: 'page/path', text: '*Markdown* text' } + + expect(json_response.keys).to match_array(%w(body references)) + end + end + + describe 'GET #edit' do + subject { get(:edit, params: { namespace_id: project.namespace, project_id: project, id: wiki_title }) } + + context 'when page content encoding is invalid' do + it 'redirects to show' do + allow(controller).to receive(:valid_encoding?).and_return(false) + + subject + + expect(response).to redirect_to(project_wiki_path(project, project_wiki.list_pages.first)) + end + end - include_examples 'sorting-and-nesting', ProjectWiki::CREATED_AT_ORDER, ProjectWiki::NESTING_FLAT - include_examples 'sorting-and-nesting', ProjectWiki::TITLE_ORDER, ProjectWiki::NESTING_CLOSED + context 'when page content encoding is valid' do + render_views + + it 'shows the edit page' do + subject + + expect(response).to have_http_status(:ok) + expect(response.body).to include('Edit Page') + end + end + end + + describe 'PATCH #update' do + let(:new_title) { 'New title' } + let(:new_content) { 'New content' } + subject do + patch(:update, + params: { + namespace_id: project.namespace, + project_id: project, + id: wiki_title, + wiki: { title: new_title, content: new_content } + }) + end + + context 'when page content encoding is invalid' do + it 'redirects to show' do + allow(controller).to receive(:valid_encoding?).and_return(false) + + subject + expect(response).to redirect_to(project_wiki_path(project, project_wiki.list_pages.first)) + end + end + + context 'when page content encoding is valid' do + render_views + + it 'updates the page' do + subject + + wiki_page = project_wiki.list_pages(load_content: true).first + + expect(wiki_page.title).to eq new_title + expect(wiki_page.content).to eq new_content + end + end end def create_page(name, content) |