diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2019-10-31 21:06:28 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2019-10-31 21:06:28 +0000 |
commit | 8f210aebe1d740e8ee194f171f1f33a6e1fba313 (patch) | |
tree | f43c545801bb96fd0737f18493fb30ab92972627 /spec | |
parent | 996f700997805b3590da8d8afdd19d193989078a (diff) | |
download | gitlab-ce-8f210aebe1d740e8ee194f171f1f33a6e1fba313.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
35 files changed, 907 insertions, 1457 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) diff --git a/spec/factories/wiki_pages.rb b/spec/factories/wiki_pages.rb index 3ac8fe4ae43..761ba58edb2 100644 --- a/spec/factories/wiki_pages.rb +++ b/spec/factories/wiki_pages.rb @@ -18,12 +18,12 @@ FactoryBot.define do association :wiki, factory: :project_wiki, strategy: :build initialize_with { new(wiki, page, true) } - before(:create) do |wiki_page, evaluator| - wiki_page.attributes = evaluator.attrs.with_indifferent_access + before(:create) do |page, evaluator| + page.attributes = evaluator.attrs end - to_create do |wiki_page| - wiki_page.create + to_create do |page| + page.create end end end diff --git a/spec/features/projects/features_visibility_spec.rb b/spec/features/projects/features_visibility_spec.rb index 8b7fef84dd7..9ec61743a11 100644 --- a/spec/features/projects/features_visibility_spec.rb +++ b/spec/features/projects/features_visibility_spec.rb @@ -3,9 +3,8 @@ require 'spec_helper' describe 'Edit Project Settings' do - set(:project) { create(:project, :public, :repository) } - let(:member) { create(:user) } + let!(:project) { create(:project, :public, :repository) } let!(:issue) { create(:issue, project: project) } let(:non_member) { create(:user) } @@ -82,88 +81,85 @@ describe 'Edit Project Settings' do end describe 'project features visibility pages' do - set(:pipeline) { create(:ci_empty_pipeline, project: project) } - set(:job) { create(:ci_build, pipeline: pipeline) } - - where(:method_name, :build_url) do - [ - [:builds, -> { project_job_path(project, job) }], - [:issues, -> { project_issues_path(project) }], - [:wiki, -> { project_wiki_path(project, :home) }], - [:snippets, -> { project_snippets_path(project) }], - [:merge_requests, -> { project_merge_requests_path(project) }] - ] + let(:pipeline) { create(:ci_empty_pipeline, project: project) } + let(:job) { create(:ci_build, pipeline: pipeline) } + + let(:tools) do + { + builds: project_job_path(project, job), + issues: project_issues_path(project), + wiki: project_wiki_path(project, :home), + snippets: project_snippets_path(project), + merge_requests: project_merge_requests_path(project) + } end - with_them do - let(:url) { build_url.call } - let(:attr_name) { "#{method_name}_access_level" } - - context 'normal user' do - before do - project.team.truncate - sign_in(member) - end - - it 'renders 200 if tool is enabled' do - project.project_feature.update_attribute(attr_name, ProjectFeature::ENABLED) + context 'normal user' do + before do + sign_in(member) + end + it 'renders 200 if tool is enabled' do + tools.each do |method_name, url| + project.project_feature.update_attribute("#{method_name}_access_level", ProjectFeature::ENABLED) visit url - expect(page.status_code).to eq(200) end + end - it 'renders 404 if feature is disabled' do - project.project_feature.update_attribute(attr_name, ProjectFeature::DISABLED) - + it 'renders 404 if feature is disabled' do + tools.each do |method_name, url| + project.project_feature.update_attribute("#{method_name}_access_level", ProjectFeature::DISABLED) visit url - expect(page.status_code).to eq(404) end + end - it 'renders 404 if feature is enabled only for team members' do - project.project_feature.update_attribute(attr_name, ProjectFeature::PRIVATE) + it 'renders 404 if feature is enabled only for team members' do + project.team.truncate + tools.each do |method_name, url| + project.project_feature.update_attribute("#{method_name}_access_level", ProjectFeature::PRIVATE) visit url - expect(page.status_code).to eq(404) end + end - it 'renders 200 if user is member of group' do - group = create(:group) - project.group = group - project.save - - group.add_owner(member) + it 'renders 200 if user is member of group' do + group = create(:group) + project.group = group + project.save - project.project_feature.update_attribute(attr_name, ProjectFeature::PRIVATE) + group.add_owner(member) + tools.each do |method_name, url| + project.project_feature.update_attribute("#{method_name}_access_level", ProjectFeature::PRIVATE) visit url - expect(page.status_code).to eq(200) end end + end - context 'admin user' do - before do - non_member.update_attribute(:admin, true) - project.team.truncate - sign_in(non_member) - end + context 'admin user' do + before do + non_member.update_attribute(:admin, true) + sign_in(non_member) + end - it 'renders 404 if feature is disabled' do + it 'renders 404 if feature is disabled' do + tools.each do |method_name, url| project.project_feature.update_attribute("#{method_name}_access_level", ProjectFeature::DISABLED) - visit url - expect(page.status_code).to eq(404) end + end - it 'renders 200 if feature is enabled only for team members' do - project.project_feature.update_attribute("#{method_name}_access_level", ProjectFeature::PRIVATE) + it 'renders 200 if feature is enabled only for team members' do + project.team.truncate + tools.each do |method_name, url| + project.project_feature.update_attribute("#{method_name}_access_level", ProjectFeature::PRIVATE) visit url - expect(page.status_code).to eq(200) end end diff --git a/spec/features/projects/wiki/markdown_preview_spec.rb b/spec/features/projects/wiki/markdown_preview_spec.rb index a56b3e4955a..5c6b04a7141 100644 --- a/spec/features/projects/wiki/markdown_preview_spec.rb +++ b/spec/features/projects/wiki/markdown_preview_spec.rb @@ -4,54 +4,164 @@ require 'spec_helper' describe 'Projects > Wiki > User previews markdown changes', :js do set(:user) { create(:user) } - set(:project) { create(:project, :wiki_repo, namespace: user.namespace) } - let(:project_wiki) { ProjectWiki.new(project, user) } + let(:project) { create(:project, :wiki_repo, namespace: user.namespace) } + let(:wiki_page) { create(:wiki_page, wiki: project.wiki, attrs: { title: 'home', content: '[some link](other-page)' }) } + let(:wiki_content) do + <<-HEREDOC +[regular link](regular) +[relative link 1](../relative) +[relative link 2](./relative) +[relative link 3](./e/f/relative) +[spaced link](title with spaces) + HEREDOC + end before do project.add_maintainer(user) + sign_in(user) - init_home! end - def init_home! - create(:wiki_page, wiki: project.wiki, attrs: { title: 'home', content: '[some link](other-page)' }) - end + context "while creating a new wiki page" do + context "when there are no spaces or hyphens in the page name" do + it "rewrites relative links as expected" do + create_wiki_page('a/b/c/d', content: wiki_content) - def fill_in_content! - page.within '.wiki-form' do - fill_in :wiki_page_content, with: wiki_content + expect(page).to have_content("regular link") + + expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/regular\">regular link</a>") + expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a/b/relative\">relative link 1</a>") + expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a/b/c/relative\">relative link 2</a>") + expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a/b/c/e/f/relative\">relative link 3</a>") + expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/title%20with%20spaces\">spaced link</a>") + end end - end - def show_preview! - page.within '.wiki-form' do - click_on 'Preview' + context "when there are spaces in the page name" do + it "rewrites relative links as expected" do + create_wiki_page('a page/b page/c page/d page', content: wiki_content) + + expect(page).to have_content("regular link") + + expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/regular\">regular link</a>") + expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a-page/b-page/relative\">relative link 1</a>") + expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a-page/b-page/c-page/relative\">relative link 2</a>") + expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a-page/b-page/c-page/e/f/relative\">relative link 3</a>") + expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/title%20with%20spaces\">spaced link</a>") + end end - end - context 'when writing a new page' do - let(:new_wiki_path) { 'a/b/c/d' } - let(:wiki_content) { 'Some [awesome wiki](content)' } + context "when there are hyphens in the page name" do + it "rewrites relative links as expected" do + create_wiki_page('a-page/b-page/c-page/d-page', content: wiki_content) - it 'can show a preview of markdown content' do - visit project_wiki_pages_new_path(project, id: new_wiki_path) - fill_in_content! - show_preview! + expect(page).to have_content("regular link") - expect(page).to have_link('awesome wiki') + expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/regular\">regular link</a>") + expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a-page/b-page/relative\">relative link 1</a>") + expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a-page/b-page/c-page/relative\">relative link 2</a>") + expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a-page/b-page/c-page/e/f/relative\">relative link 3</a>") + expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/title%20with%20spaces\">spaced link</a>") + end end end - context 'when editing an existing page' do - let(:wiki_content) { 'Some [bemusing](content)' } - let(:wiki_page) { create(:wiki_page, wiki: project_wiki) } + context "while editing a wiki page" do + context "when there are no spaces or hyphens in the page name" do + it "rewrites relative links as expected" do + create_wiki_page('a/b/c/d') + click_link 'Edit' + + fill_in :wiki_content, with: wiki_content + click_on "Preview" + + expect(page).to have_content("regular link") + + expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/regular\">regular link</a>") + expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a/b/relative\">relative link 1</a>") + expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a/b/c/relative\">relative link 2</a>") + expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a/b/c/e/f/relative\">relative link 3</a>") + expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/title%20with%20spaces\">spaced link</a>") + end + end + + context "when there are spaces in the page name" do + it "rewrites relative links as expected" do + create_wiki_page('a page/b page/c page/d page') + click_link 'Edit' + + fill_in :wiki_content, with: wiki_content + click_on "Preview" + + expect(page).to have_content("regular link") + + expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/regular\">regular link</a>") + expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a-page/b-page/relative\">relative link 1</a>") + expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a-page/b-page/c-page/relative\">relative link 2</a>") + expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a-page/b-page/c-page/e/f/relative\">relative link 3</a>") + expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/title%20with%20spaces\">spaced link</a>") + end + end + + context "when there are hyphens in the page name" do + it "rewrites relative links as expected" do + create_wiki_page('a-page/b-page/c-page/d-page') + click_link 'Edit' + + fill_in :wiki_content, with: wiki_content + click_on "Preview" - it 'can show a preview of markdown content, when writing' do - visit project_wiki_edit_path(project, wiki_page) - fill_in_content! - show_preview! + expect(page).to have_content("regular link") - expect(page).to have_link('bemusing') + expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/regular\">regular link</a>") + expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a-page/b-page/relative\">relative link 1</a>") + expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a-page/b-page/c-page/relative\">relative link 2</a>") + expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/a-page/b-page/c-page/e/f/relative\">relative link 3</a>") + expect(page.html).to include("<a href=\"/#{project.full_path}/wikis/title%20with%20spaces\">spaced link</a>") + end end + + context 'when rendering the preview' do + it 'renders content with CommonMark' do + create_wiki_page('a-page/b-page/c-page/common-mark') + click_link 'Edit' + + fill_in :wiki_content, with: "1. one\n - sublist\n" + click_on "Preview" + + # the above generates two separate lists (not embedded) in CommonMark + expect(page).to have_content("sublist") + expect(page).not_to have_xpath("//ol//li//ul") + end + end + end + + it "does not linkify double brackets inside code blocks as expected" do + wiki_content = <<-HEREDOC + `[[do_not_linkify]]` + ``` + [[also_do_not_linkify]] + ``` + HEREDOC + + create_wiki_page('linkify_test', wiki_content) + + expect(page).to have_content("do_not_linkify") + + expect(page.html).to include('[[do_not_linkify]]') + expect(page.html).to include('[[also_do_not_linkify]]') + end + + private + + def create_wiki_page(path, content = 'content') + visit project_wiki_path(project, wiki_page) + + click_link 'New page' + + fill_in :wiki_title, with: path + fill_in :wiki_content, with: content + + click_button 'Create page' end end diff --git a/spec/features/projects/wiki/user_creates_wiki_page_spec.rb b/spec/features/projects/wiki/user_creates_wiki_page_spec.rb index 6b651ccb67a..56d0518015d 100644 --- a/spec/features/projects/wiki/user_creates_wiki_page_spec.rb +++ b/spec/features/projects/wiki/user_creates_wiki_page_spec.rb @@ -3,15 +3,9 @@ require "spec_helper" describe "User creates wiki page" do - include CapybaraHelpers - include WikiHelpers - - set(:user) { create(:user) } - - let(:project) { create(:project) } + let(:user) { create(:user) } let(:wiki) { ProjectWiki.new(project, user) } - let(:new_page) { WikiPage.new(wiki) } - let(:message_field) { form_field_name(new_page, :message) } + let(:project) { create(:project) } before do project.add_maintainer(user) @@ -19,76 +13,36 @@ describe "User creates wiki page" do sign_in(user) end - def start_writing(page_path) - click_link("New page") - fill_in(:wiki_page_title, with: page_path) - end - - def create_page(attrs = {}) - page.within(".wiki-form") do - attrs.each do |k, v| - fill_in("wiki_page_#{k}".to_sym, with: v) - end - end - click_on("Create page") - end - - shared_examples 'updates commit message' do - describe 'commit message', :js do - it "has `Create home` as a commit message" do - wait_for_requests - - expect(page).to have_field(message_field, with: "Create home") - end - end - end - context "when wiki is empty" do before do visit(project_wikis_path(project)) click_link "Create your first page" - find('.wiki-form') end context "in a user namespace" do let(:project) { create(:project, :wiki_repo, namespace: user.namespace) } - let(:wiki_page_content) { '' } it "shows validation error message" do - create_page - - expect(page) - .to have_content("The form contains the following error:") - .and have_content("Content can't be blank") - .and have_css('.wiki-form') - .and have_css('.qa-create-page-button') - end - - it 'offers to create pages that do not yet exist' do - create_page(content: "[link test](test)") + page.within(".wiki-form") do + fill_in(:wiki_content, with: "") - expect(page) - .to have_content("Home") - .and have_content("link test") + click_on("Create page") + end - click_link("link test") + expect(page).to have_content("The form contains the following error:").and have_content("Content can't be blank") - expect(page).to have_content("Create New Page") - end + page.within(".wiki-form") do + fill_in(:wiki_content, with: "[link test](test)") - it "has a link to the parent directory in the pages sidebar" do - wiki_full_path = "one/two/three-test" - create_page(title: wiki_full_path, content: 'wiki content') + click_on("Create page") + end - wiki_page = wiki.find_page(wiki_full_path) - expect(wiki_page).to be_present - dir = wiki.find_dir(wiki_page.directory) - expect(dir).to be_present + expect(page).to have_content("Home").and have_content("link test") - expect(current_path).to include(wiki_full_path) + click_link("link test") - expect(page).to have_link(dir.slug, href: project_wiki_dir_path(project, dir)) + expect(page).to have_content("Create New Page") end it "shows non-escaped link in the pages list", :quarantine do @@ -104,17 +58,19 @@ describe "User creates wiki page" do expect(page).to have_xpath("//a[@href='/#{project.full_path}/wikis/one/two/three-test']") end - it_behaves_like 'updates commit message' + it "has `Create home` as a commit message", :js do + wait_for_requests + + expect(page).to have_field("wiki[message]", with: "Create home") + end it "creates a page from the home page" do - page_content = <<~WIKI_CONTENT - [test](test) - [GitLab API doc](api) - [Rake tasks](raketasks) - # Wiki header - WIKI_CONTENT + fill_in(:wiki_content, with: "[test](test)\n[GitLab API doc](api)\n[Rake tasks](raketasks)\n# Wiki header\n") + fill_in(:wiki_message, with: "Adding links to wiki") - create_page(content: page_content, message: "Adding links to wiki") + page.within(".wiki-form") do + click_button("Create page") + end expect(current_path).to eq(project_wiki_path(project, "home")) expect(page).to have_content("test GitLab API doc Rake tasks Wiki header") @@ -155,7 +111,7 @@ describe "User creates wiki page" do end end - it "creates ASCIIdoc wiki with LaTeX blocks", :js do + it "creates ASCII wiki with LaTeX blocks", :js do stub_application_setting(plantuml_url: "http://localhost", plantuml_enabled: true) ascii_content = <<~MD @@ -176,25 +132,37 @@ describe "User creates wiki page" do stem:[2+2] is 4 MD - find("#wiki_page_format option[value=asciidoc]").select_option + find("#wiki_format option[value=asciidoc]").select_option + + fill_in(:wiki_content, with: ascii_content) - create_page(content: ascii_content) + page.within(".wiki-form") do + click_button("Create page") + end page.within ".md" do expect(page).to have_selector(".katex", count: 3).and have_content("2+2 is 4") end end - it_behaves_like 'wiki file attachments' + it_behaves_like 'wiki file attachments', :quarantine end - context "in a group namespace" do + context "in a group namespace", :js do let(:project) { create(:project, :wiki_repo, namespace: create(:group, :public)) } - it_behaves_like 'updates commit message' + it "has `Create home` as a commit message" do + wait_for_requests - it "creates a page from the home page" do - create_page(content: "My awesome wiki!") + expect(page).to have_field("wiki[message]", with: "Create home") + end + + it "creates a page from the home page", :quarantine do + page.within(".wiki-form") do + fill_in(:wiki_content, with: "My awesome wiki!") + + click_button("Create page") + end expect(page).to have_content("Home") .and have_content("Last edited by #{user.name}") @@ -210,37 +178,76 @@ describe "User creates wiki page" do visit(project_wikis_path(project)) end - shared_examples 'creates page by slug' do |slug, unslug| - it "creates #{slug}" do - start_writing(slug) + context "in a user namespace" do + let(:project) { create(:project, :wiki_repo, namespace: user.namespace) } - # Commit message field should have correct value. - expect(page).to have_field(message_field, with: "Create #{unslug}") + context "via the `new wiki page` page" do + it "creates a page with a single word" do + click_link("New page") - create_page(content: "My awesome wiki!") + page.within(".wiki-form") do + fill_in(:wiki_title, with: "foo") + fill_in(:wiki_content, with: "My awesome wiki!") + end - expect(page).to have_content(unslug) - .and have_content("Last edited by #{user.name}") - .and have_content("My awesome wiki!") - end - end + # Commit message field should have correct value. + expect(page).to have_field("wiki[message]", with: "Create foo") - context "in a user namespace" do - let(:project) { create(:project, :wiki_repo, namespace: user.namespace) } + click_button("Create page") - context "via the `new wiki page` page" do - include_examples 'creates page by slug', 'foo', 'foo' - include_examples 'creates page by slug', 'Spaces in the name', 'Spaces in the name' - include_examples 'creates page by slug', 'Hyphens-in-the-name', 'Hyphens in the name' + expect(page).to have_content("foo") + .and have_content("Last edited by #{user.name}") + .and have_content("My awesome wiki!") + end + + it "creates a page with spaces in the name" do + click_link("New page") + + page.within(".wiki-form") do + fill_in(:wiki_title, with: "Spaces in the name") + fill_in(:wiki_content, with: "My awesome wiki!") + end + + # Commit message field should have correct value. + expect(page).to have_field("wiki[message]", with: "Create Spaces in the name") + + click_button("Create page") + + expect(page).to have_content("Spaces in the name") + .and have_content("Last edited by #{user.name}") + .and have_content("My awesome wiki!") + end + + it "creates a page with hyphens in the name" do + click_link("New page") + + page.within(".wiki-form") do + fill_in(:wiki_title, with: "hyphens-in-the-name") + fill_in(:wiki_content, with: "My awesome wiki!") + end + + # Commit message field should have correct value. + expect(page).to have_field("wiki[message]", with: "Create hyphens in the name") + + page.within(".wiki-form") do + fill_in(:wiki_content, with: "My awesome wiki!") + + click_button("Create page") + end + + expect(page).to have_content("hyphens in the name") + .and have_content("Last edited by #{user.name}") + .and have_content("My awesome wiki!") + end end it "shows the emoji autocompletion dropdown" do - start_writing('text-autocomplete') + click_link("New page") page.within(".wiki-form") do - find("#wiki_page_content").native.send_keys("") + find("#wiki_content").native.send_keys("") - fill_in(:wiki_page_content, with: ":") + fill_in(:wiki_content, with: ":") end expect(page).to have_selector(".atwho-view") @@ -251,9 +258,23 @@ describe "User creates wiki page" do let(:project) { create(:project, :wiki_repo, namespace: create(:group, :public)) } context "via the `new wiki page` page" do - include_examples 'creates page by slug', 'foo', 'foo' - include_examples 'creates page by slug', 'Spaces in the name', 'Spaces in the name' - include_examples 'creates page by slug', 'Hyphens-in-the-name', 'Hyphens in the name' + it "creates a page" do + click_link("New page") + + page.within(".wiki-form") do + fill_in(:wiki_title, with: "foo") + fill_in(:wiki_content, with: "My awesome wiki!") + end + + # Commit message field should have correct value. + expect(page).to have_field("wiki[message]", with: "Create foo") + + click_button("Create page") + + expect(page).to have_content("foo") + .and have_content("Last edited by #{user.name}") + .and have_content("My awesome wiki!") + end end end end diff --git a/spec/features/projects/wiki/user_deletes_wiki_page_spec.rb b/spec/features/projects/wiki/user_deletes_wiki_page_spec.rb index 9b9d3100bf5..38e5e292064 100644 --- a/spec/features/projects/wiki/user_deletes_wiki_page_spec.rb +++ b/spec/features/projects/wiki/user_deletes_wiki_page_spec.rb @@ -6,7 +6,6 @@ describe 'User deletes wiki page', :js do let(:user) { create(:user) } let(:project) { create(:project, :wiki_repo, namespace: user.namespace) } let(:wiki_page) { create(:wiki_page, wiki: project.wiki) } - let(:project_wiki) { ProjectWiki.new(project, user) } before do sign_in(user) @@ -19,6 +18,5 @@ describe 'User deletes wiki page', :js do find('.modal-footer .btn-danger').click expect(page).to have_content('Page was successfully deleted') - expect(project_wiki.find_page(wiki_page.slug)).to be nil end end diff --git a/spec/features/projects/wiki/user_updates_wiki_page_spec.rb b/spec/features/projects/wiki/user_updates_wiki_page_spec.rb index 5ab44e83f73..3f3711f9eb8 100644 --- a/spec/features/projects/wiki/user_updates_wiki_page_spec.rb +++ b/spec/features/projects/wiki/user_updates_wiki_page_spec.rb @@ -10,13 +10,6 @@ describe 'User updates wiki page' do sign_in(user) end - def create_page(attrs = {}) - page.within('.wiki-form') do - attrs.each { |k, v| fill_in("wiki_page_#{k}".to_sym, with: v) } - click_on('Create page') - end - end - context 'when wiki is empty' do before do visit(project_wikis_path(project)) @@ -35,7 +28,12 @@ describe 'User updates wiki page' do end it 'updates a page that has a path', :js do - create_page(title: 'one/two/three-test', content: 'wiki content') + fill_in(:wiki_title, with: 'one/two/three-test') + + page.within '.wiki-form' do + fill_in(:wiki_content, with: 'wiki content') + click_on('Create page') + end expect(current_path).to include('one/two/three-test') expect(find('.wiki-pages')).to have_content('three') @@ -74,9 +72,9 @@ describe 'User updates wiki page' do it 'updates a page', :js do # Commit message field should have correct value. - expect(page).to have_field('wiki_page[message]', with: 'Update home') + expect(page).to have_field('wiki[message]', with: 'Update home') - fill_in(:wiki_page_content, with: 'My awesome wiki!') + fill_in(:wiki_content, with: 'My awesome wiki!') click_button('Save changes') expect(page).to have_content('Home') @@ -85,31 +83,31 @@ describe 'User updates wiki page' do end it 'updates the commit message as the title is changed', :js do - fill_in(:wiki_page_title, with: 'Wiki title') + fill_in(:wiki_title, with: 'Wiki title') - expect(page).to have_field('wiki_page[message]', with: 'Update Wiki title') + expect(page).to have_field('wiki[message]', with: 'Update Wiki title') end it 'does not allow XSS', :js do - fill_in(:wiki_page_title, with: '<script>') + fill_in(:wiki_title, with: '<script>') - expect(page).to have_field('wiki_page[message]', with: 'Update <script>') + expect(page).to have_field('wiki[message]', with: 'Update <script>') end it 'shows a validation error message' do - fill_in(:wiki_page_content, with: '') + fill_in(:wiki_content, with: '') click_button('Save changes') expect(page).to have_selector('.wiki-form') expect(page).to have_content('Edit Page') expect(page).to have_content('The form contains the following error:') expect(page).to have_content("Content can't be blank") - expect(find('textarea#wiki_page_content').value).to eq('') + expect(find('textarea#wiki_content').value).to eq('') end it 'shows the emoji autocompletion dropdown', :js do - find('#wiki_page_content').native.send_keys('') - fill_in(:wiki_page_content, with: ':') + find('#wiki_content').native.send_keys('') + fill_in(:wiki_content, with: ':') expect(page).to have_selector('.atwho-view') end @@ -145,9 +143,9 @@ describe 'User updates wiki page' do it 'updates a page', :js do # Commit message field should have correct value. - expect(page).to have_field('wiki_page[message]', with: 'Update home') + expect(page).to have_field('wiki[message]', with: 'Update home') - fill_in(:wiki_page_content, with: 'My awesome wiki!') + fill_in(:wiki_content, with: 'My awesome wiki!') click_button('Save changes') @@ -171,43 +169,50 @@ describe 'User updates wiki page' do visit(project_wiki_edit_path(project, wiki_page)) end - def edit_title!(title) - fill_in(:wiki_page_title, with: title) + it 'moves the page to the root folder' do + fill_in(:wiki_title, with: "/#{page_name}") click_button('Save changes') - end - - it 'moves the page to the root folder' do - edit_title!("/#{page_name}") expect(current_path).to eq(project_wiki_path(project, page_name)) end it 'moves the page to other dir' do - new_page_path = "baz/quux/#{page_name}" - edit_title!(new_page_path) + new_page_dir = "foo1/bar1/#{page_name}" + + fill_in(:wiki_title, with: new_page_dir) + + click_button('Save changes') - expect(current_path).to eq(project_wiki_path(project, new_page_path)) + expect(current_path).to eq(project_wiki_path(project, new_page_dir)) end it 'remains in the same place if title has not changed' do original_path = project_wiki_path(project, wiki_page) - edit_title!(page_name) + + fill_in(:wiki_title, with: page_name) + + click_button('Save changes') expect(current_path).to eq(original_path) end it 'can be moved to a different dir with a different name' do - new_page_path = "quux/baz/new_page_name" - edit_title!(new_page_path) + new_page_dir = "foo1/bar1/new_page_name" + + fill_in(:wiki_title, with: new_page_dir) - expect(current_path).to eq(project_wiki_path(project, new_page_path)) + click_button('Save changes') + + expect(current_path).to eq(project_wiki_path(project, new_page_dir)) end it 'can be renamed and moved to the root folder' do new_name = 'new_page_name' - edit_title!("/#{new_name}") + fill_in(:wiki_title, with: "/#{new_name}") + + click_button('Save changes') expect(current_path).to eq(project_wiki_path(project, new_name)) end @@ -215,7 +220,9 @@ describe 'User updates wiki page' do it 'squishes the title before creating the page' do new_page_dir = " foo1 / bar1 / #{page_name} " - edit_title!(new_page_dir) + fill_in(:wiki_title, with: new_page_dir) + + click_button('Save changes') expect(current_path).to eq(project_wiki_path(project, "foo1/bar1/#{page_name}")) end diff --git a/spec/features/projects/wiki/user_views_wiki_page_spec.rb b/spec/features/projects/wiki/user_views_wiki_page_spec.rb index af8f86106d9..77e725e7f11 100644 --- a/spec/features/projects/wiki/user_views_wiki_page_spec.rb +++ b/spec/features/projects/wiki/user_views_wiki_page_spec.rb @@ -8,11 +8,10 @@ describe 'User views a wiki page' do let(:user) { create(:user) } let(:project) { create(:project, :wiki_repo, namespace: user.namespace) } let(:path) { 'image.png' } - let(:wiki_content) { "Look at this [image](#{path})\n\n ![alt text](#{path})" } let(:wiki_page) do create(:wiki_page, wiki: project.wiki, - attrs: { title: 'home', content: wiki_content }) + attrs: { title: 'home', content: "Look at this [image](#{path})\n\n ![alt text](#{path})" }) end before do @@ -20,18 +19,17 @@ describe 'User views a wiki page' do sign_in(user) end - def create_page(attrs = {}) - page.within('.wiki-form') do - attrs.each { |k, v| fill_in("wiki_page_#{k}".to_sym, with: v) } - click_on('Create page') - end - end - context 'when wiki is empty' do before do visit(project_wikis_path(project)) click_link "Create your first page" - create_page(title: 'one/two/three-test', content: 'wiki content') + + fill_in(:wiki_title, with: 'one/two/three-test') + + page.within('.wiki-form') do + fill_in(:wiki_content, with: 'wiki content') + click_on('Create page') + end end it 'shows the history of a page that has a path', :js do @@ -85,27 +83,24 @@ describe 'User views a wiki page' do context 'shows a file stored in a page' do let(:path) { upload_file_to_wiki(project, user, 'dk.png') } - let(:image_path) { project_wiki_path(project, path) } it do - expect(page).to have_xpath("//img[@data-src='#{image_path}']") - expect(page).to have_link('image', href: "#{image_path}") + expect(page).to have_xpath("//img[@data-src='#{project.wiki.wiki_base_path}/#{path}']") + expect(page).to have_link('image', href: "#{project.wiki.wiki_base_path}/#{path}") click_on('image') - expect(current_path).to match(path) + expect(current_path).to match("wikis/#{path}") expect(page).not_to have_xpath('/html') # Page should render the image which means there is no html involved end end it 'shows the creation page if file does not exist' do - href = project_wiki_path(project, path) - - expect(page).to have_link('image', href: href) + expect(page).to have_link('image', href: "#{project.wiki.wiki_base_path}/#{path}") click_on('image') - expect(current_path).to match(href) + expect(current_path).to match("wikis/#{path}") expect(page).to have_content('Create New Page') end end diff --git a/spec/features/projects/wiki/user_views_wiki_pages_spec.rb b/spec/features/projects/wiki/user_views_wiki_pages_spec.rb index adb59c891c6..6740df1d4ed 100644 --- a/spec/features/projects/wiki/user_views_wiki_pages_spec.rb +++ b/spec/features/projects/wiki/user_views_wiki_pages_spec.rb @@ -7,7 +7,6 @@ describe 'User views wiki pages' do let(:user) { create(:user) } let(:project) { create(:project, :wiki_repo, namespace: user.namespace) } - let(:project_wiki) { ProjectWiki.new(project, user) } let!(:wiki_page1) do create(:wiki_page, wiki: project.wiki, attrs: { title: '3 home', content: '3' }) @@ -18,182 +17,73 @@ describe 'User views wiki pages' do let!(:wiki_page3) do create(:wiki_page, wiki: project.wiki, attrs: { title: '2 home', content: '2' }) end - let!(:wiki_page4) do - create(:wiki_page, wiki: project.wiki, attrs: { title: 'sub-folder/0', content: 'a' }) - end - let!(:wiki_page5) do - create(:wiki_page, wiki: project.wiki, attrs: { title: 'sub-folder/b', content: 'b' }) - end - - let(:page_link_selector) { 'a' } let(:pages) do - page.all(".wiki-pages-list li #{page_link_selector}") + page.find('.wiki-pages-list').all('li').map { |li| li.find('a') } end - let(:wikis_allow_change_nesting) { false } before do - stub_feature_flags(wikis_allow_change_nesting: wikis_allow_change_nesting) project.add_maintainer(user) sign_in(user) visit(project_wikis_pages_path(project)) end - def sort_desc! - page.within('.wiki-sort-dropdown') do - page.find('.qa-reverse-sort').click - end - end - - def sort_by_created_at! - page.within('.wiki-sort-dropdown') do - click_button('Title') - click_link('Created date') - end - end - - shared_examples 'correctly_sorted_pages' do - it 'has pages displayed in correct order' do - displayed_texts = pages.map(&:text) - expect(displayed_texts).to eq expected_sequence.map(&:title) - end - end - context 'ordered by title' do - let(:sub_folder) { project_wiki.find_dir('sub-folder') } + let(:pages_ordered_by_title) { [wiki_page2, wiki_page3, wiki_page1] } - context 'default display settings' do - context 'asc' do - let(:expected_sequence) { [wiki_page2, wiki_page3, wiki_page1, sub_folder] } - - it_behaves_like 'correctly_sorted_pages' - end - - context 'desc' do - before do - sort_desc! + context 'asc' do + it 'pages are displayed in direct order' do + pages.each.with_index do |page_title, index| + expect(page_title.text).to eq(pages_ordered_by_title[index].title) end - - let(:expected_sequence) { [sub_folder, wiki_page1, wiki_page3, wiki_page2] } - - it_behaves_like 'correctly_sorted_pages' - end - end - - context 'changing nesting is disabled' do - let(:wikis_allow_change_nesting) { false } - - it 'does not display a nesting controller' do - expect(page).not_to have_css('.wiki-nesting-dropdown') end end - context 'changing nesting is enabled' do - let(:wikis_allow_change_nesting) { true } - - it 'displays a nesting controller' do - expect(page).to have_css('.wiki-nesting-dropdown') - end - - context 'tree' do - before do - page.within('.wiki-nesting-dropdown') do - click_link 'Show folder contents' - end - end - - context 'asc' do - let(:expected_sequence) { [wiki_page2, wiki_page3, wiki_page1, sub_folder, wiki_page4, wiki_page5] } - - it_behaves_like 'correctly_sorted_pages' - end - - context 'desc' do - before do - sort_desc! - end - - let(:expected_sequence) { [sub_folder, wiki_page5, wiki_page4, wiki_page1, wiki_page3, wiki_page2] } - - it_behaves_like 'correctly_sorted_pages' - end - end - - context 'nested' do - before do - page.within('.wiki-nesting-dropdown') do - click_link 'Hide folder contents' - end - end - - context 'asc' do - let(:expected_sequence) { [wiki_page2, wiki_page3, wiki_page1, sub_folder] } - - it_behaves_like 'correctly_sorted_pages' - end - - context 'desc' do - before do - sort_desc! - end - - let(:expected_sequence) { [sub_folder, wiki_page1, wiki_page3, wiki_page2] } - - it_behaves_like 'correctly_sorted_pages' + context 'desc' do + before do + page.within('.wiki-sort-dropdown') do + page.find('.rspec-reverse-sort').click end end - context 'flat' do - before do - page.within('.wiki-nesting-dropdown') do - click_link 'Show files separately' - end - end - - let(:page_link_selector) { 'a.wiki-page-title' } - - context 'asc' do - let(:expected_sequence) { [wiki_page2, wiki_page3, wiki_page1, wiki_page4, wiki_page5] } - - it_behaves_like 'correctly_sorted_pages' - end - - context 'desc' do - before do - sort_desc! - end - - let(:expected_sequence) { [wiki_page5, wiki_page4, wiki_page1, wiki_page3, wiki_page2] } - - it_behaves_like 'correctly_sorted_pages' + it 'pages are displayed in reversed order' do + pages.reverse_each.with_index do |page_title, index| + expect(page_title.text).to eq(pages_ordered_by_title[index].title) end end end end context 'ordered by created_at' do - let(:pages_ordered_by_created_at) { [wiki_page1, wiki_page2, wiki_page3, wiki_page4, wiki_page5] } + let(:pages_ordered_by_created_at) { [wiki_page1, wiki_page2, wiki_page3] } before do - sort_by_created_at! + page.within('.wiki-sort-dropdown') do + click_button('Title') + click_link('Created date') + end end - let(:page_link_selector) { 'a.wiki-page-title' } - context 'asc' do - let(:expected_sequence) { [wiki_page1, wiki_page2, wiki_page3, wiki_page4, wiki_page5] } - - it_behaves_like 'correctly_sorted_pages' + it 'pages are displayed in direct order' do + pages.each.with_index do |page_title, index| + expect(page_title.text).to eq(pages_ordered_by_created_at[index].title) + end + end end context 'desc' do before do - sort_desc! + page.within('.wiki-sort-dropdown') do + page.find('.rspec-reverse-sort').click + end end - let(:expected_sequence) { [wiki_page5, wiki_page4, wiki_page3, wiki_page2, wiki_page1] } - - it_behaves_like 'correctly_sorted_pages' + it 'pages are displayed in reversed order' do + pages.reverse_each.with_index do |page_title, index| + expect(page_title.text).to eq(pages_ordered_by_created_at[index].title) + end + end end end end diff --git a/spec/frontend/wikis_spec.js b/spec/frontend/wikis_spec.js index a2b68bf866e..b2475488d97 100644 --- a/spec/frontend/wikis_spec.js +++ b/spec/frontend/wikis_spec.js @@ -3,27 +3,27 @@ import { setHTMLFixture } from './helpers/fixtures'; describe('Wikis', () => { describe('setting the commit message when the title changes', () => { + const editFormHtmlFixture = args => `<form class="wiki-form ${ + args.newPage ? 'js-new-wiki-page' : '' + }"> + <input type="text" id="wiki_title" value="My title" /> + <input type="text" id="wiki_message" /> + </form>`; + let wikis; let titleInput; let messageInput; - const CREATE = true; - const UPDATE = false; - const editFormHtmlFixture = newPage => - `<form class="wiki-form ${newPage ? 'js-new-wiki-page' : ''}"> - <input type="text" id="wiki_page_title" value="My title" /> - <input type="text" id="wiki_page_message" /> - </form>`; + describe('when the wiki page is being created', () => { + const formHtmlFixture = editFormHtmlFixture({ newPage: true }); - const init = newPage => { - setHTMLFixture(editFormHtmlFixture(newPage)); - titleInput = document.getElementById('wiki_page_title'); - messageInput = document.getElementById('wiki_page_message'); - wikis = new Wikis(); - }; + beforeEach(() => { + setHTMLFixture(formHtmlFixture); - describe('when the wiki page is being created', () => { - beforeEach(() => init(CREATE)); + titleInput = document.getElementById('wiki_title'); + messageInput = document.getElementById('wiki_message'); + wikis = new Wikis(); + }); it('binds an event listener to the title input', () => { wikis.handleWikiTitleChange = jest.fn(); @@ -51,7 +51,15 @@ describe('Wikis', () => { }); describe('when the wiki page is being updated', () => { - beforeEach(() => init(UPDATE)); + const formHtmlFixture = editFormHtmlFixture({ newPage: false }); + + beforeEach(() => { + setHTMLFixture(formHtmlFixture); + + titleInput = document.getElementById('wiki_title'); + messageInput = document.getElementById('wiki_message'); + wikis = new Wikis(); + }); it('sets the commit message when title changes, prefixing with "Update"', () => { titleInput.value = 'My title'; diff --git a/spec/helpers/wiki_helper_spec.rb b/spec/helpers/wiki_helper_spec.rb index 4310e4bd22c..bcc2bd71da1 100644 --- a/spec/helpers/wiki_helper_spec.rb +++ b/spec/helpers/wiki_helper_spec.rb @@ -23,13 +23,8 @@ describe WikiHelper do describe '#wiki_sort_controls' do let(:project) { create(:project) } - let(:classes) { described_class::WIKI_SORT_CSS_CLASSES } - - subject(:wiki_link) do - helper.wiki_sort_controls(sort: sort, direction: direction) do |opts| - project_wikis_pages_path(project, opts) - end - end + let(:wiki_link) { helper.wiki_sort_controls(project, sort, direction) } + let(:classes) { "btn btn-default has-tooltip reverse-sort-btn qa-reverse-sort rspec-reverse-sort" } def expected_link(sort, direction, icon_class) path = "/#{project.full_path}/wikis/pages?direction=#{direction}&sort=#{sort}" @@ -67,18 +62,6 @@ describe WikiHelper do end end - describe '#wiki_show_children_icon' do - ProjectWiki::NESTINGS.each do |nesting| - context "When the nesting parameter is `#{nesting}`" do - let(:element) { helper.wiki_show_children_icon(nesting) } - - it 'produces something that contains an SVG' do - expect(element).to match(/svg/) - end - end - end - end - describe '#wiki_sort_title' do it 'returns a title corresponding to a key' do expect(helper.wiki_sort_title('created_at')).to eq('Created date') diff --git a/spec/lib/banzai/filter/wiki_link_filter_spec.rb b/spec/lib/banzai/filter/wiki_link_filter_spec.rb index 7a83dc3ec1d..4587bd85939 100644 --- a/spec/lib/banzai/filter/wiki_link_filter_spec.rb +++ b/spec/lib/banzai/filter/wiki_link_filter_spec.rb @@ -11,10 +11,6 @@ describe Banzai::Filter::WikiLinkFilter do let(:wiki) { ProjectWiki.new(project, user) } let(:repository_upload_folder) { Wikis::CreateAttachmentService::ATTACHMENT_PATH } - def upload_href(file_name) - ::File.join(wiki.wiki_page_path, repository_upload_folder, file_name) - end - it "doesn't rewrite absolute links" do filtered_link = filter("<a href='http://example.com:8000/'>Link</a>", project_wiki: wiki).children[0] @@ -32,12 +28,12 @@ describe Banzai::Filter::WikiLinkFilter do it 'rewrites links' do filtered_link = filter("<a href='#{repository_upload_folder}/a.test'>Link</a>", project_wiki: wiki).children[0] - expect(filtered_link.attribute('href').value).to eq(upload_href "a.test") + expect(filtered_link.attribute('href').value).to eq("#{wiki.wiki_base_path}/#{repository_upload_folder}/a.test") end end context 'with "img" html tag' do - let(:path) { upload_href "a.jpg" } + let(:path) { "#{wiki.wiki_base_path}/#{repository_upload_folder}/a.jpg" } context 'inside an "a" html tag' do it 'rewrites links' do @@ -61,7 +57,7 @@ describe Banzai::Filter::WikiLinkFilter do it 'rewrites links' do filtered_link = filter("<video src='#{repository_upload_folder}/a.mp4'></video>", project_wiki: wiki).children[0] - expect(filtered_link.attribute('src').value).to eq(upload_href "a.mp4") + expect(filtered_link.attribute('src').value).to eq("#{wiki.wiki_base_path}/#{repository_upload_folder}/a.mp4") end end @@ -69,8 +65,7 @@ describe Banzai::Filter::WikiLinkFilter do it 'rewrites links' do filtered_link = filter("<audio src='#{repository_upload_folder}/a.wav'></audio>", project_wiki: wiki).children[0] - # expect(filtered_link.attribute('src').value).to eq("#{wiki.wiki_base_path}/#{repository_upload_folder}/a.wav") - expect(filtered_link.attribute('src').value).to eq(upload_href "a.wav") + expect(filtered_link.attribute('src').value).to eq("#{wiki.wiki_base_path}/#{repository_upload_folder}/a.wav") end end end diff --git a/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb b/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb index 7f60106cdca..26f2b0b0acf 100644 --- a/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb +++ b/spec/lib/banzai/pipeline/wiki_pipeline_spec.rb @@ -3,12 +3,6 @@ require 'spec_helper' describe Banzai::Pipeline::WikiPipeline do - let_it_be(:namespace) { create(:namespace, name: "wiki_link_ns") } - let_it_be(:project) { create(:project, :public, name: "wiki_link_project", namespace: namespace) } - let_it_be(:project_wiki) { ProjectWiki.new(project, double(:user)) } - let_it_be(:page) { build(:wiki_page, wiki: project_wiki, page: OpenStruct.new(url_path: 'nested/twice/start-page')) } - let(:prefix) { project_wiki.wiki_page_path } - describe 'TableOfContents' do it 'replaces the tag with the TableOfContentsFilter result' do markdown = <<-MD.strip_heredoc @@ -60,138 +54,132 @@ describe Banzai::Pipeline::WikiPipeline do end describe "Links" do - shared_examples 'a correct link rewrite' do - it 'rewrites links correctly' do - output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) - - expect(output).to include("href=\"#{page_href}\"") - end - end - - shared_examples 'link examples' do |test_name| - let(:page_href) { "#{prefix}/#{expected_page_path}" } - - context "when GitLab is hosted at a #{test_name} URL" do + let(:namespace) { create(:namespace, name: "wiki_link_ns") } + let(:project) { create(:project, :public, name: "wiki_link_project", namespace: namespace) } + let(:project_wiki) { ProjectWiki.new(project, double(:user)) } + let(:page) { build(:wiki_page, wiki: project_wiki, page: OpenStruct.new(url_path: 'nested/twice/start-page')) } + + { "when GitLab is hosted at a root URL" => '/', + "when GitLab is hosted at a relative URL" => '/nested/relative/gitlab' }.each do |test_name, relative_url_root| + context test_name do before do allow(Gitlab.config.gitlab).to receive(:relative_url_root).and_return(relative_url_root) end describe "linking to pages within the wiki" do - let(:markdown) { "[Page](#{nesting}page#{extension})" } - context "when creating hierarchical links to the current directory" do - let(:nesting) { './' } - context 'non file links' do - let(:extension) { '' } - let(:expected_page_path) { 'nested/twice/page' } - it_behaves_like 'a correct link rewrite' + it "rewrites non-file links to be at the scope of the current directory" do + markdown = "[Page](./page)" + output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) + + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/nested/twice/page\"") end - context 'file-like links' do - let(:extension) { '.md' } - let(:expected_page_path) { 'nested/twice/page.md' } - it_behaves_like 'a correct link rewrite' + it "rewrites file links to be at the scope of the current directory" do + markdown = "[Link to Page](./page.md)" + output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) + + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/nested/twice/page.md\"") end end context "when creating hierarchical links to the parent directory" do - let(:nesting) { '../' } - context "non file links" do - let(:extension) { '' } - let(:expected_page_path) { 'nested/page' } - it_behaves_like 'a correct link rewrite' + it "rewrites non-file links to be at the scope of the parent directory" do + markdown = "[Link to Page](../page)" + output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) + + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/nested/page\"") end - context "file-like links" do - let(:extension) { '.md' } - let(:expected_page_path) { 'nested/page.md' } - it_behaves_like 'a correct link rewrite' + it "rewrites file links to be at the scope of the parent directory" do + markdown = "[Link to Page](../page.md)" + output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) + + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/nested/page.md\"") end end context "when creating hierarchical links to a sub-directory" do - let(:nesting) { './subdirectory/' } + it "rewrites non-file links to be at the scope of the sub-directory" do + markdown = "[Link to Page](./subdirectory/page)" + output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) - context "non file links" do - let(:extension) { '' } - let(:expected_page_path) { 'nested/twice/subdirectory/page' } - it_behaves_like 'a correct link rewrite' + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/nested/twice/subdirectory/page\"") end - context 'file-like links' do - let(:extension) { '.md' } - let(:expected_page_path) { 'nested/twice/subdirectory/page.md' } - it_behaves_like 'a correct link rewrite' + it "rewrites file links to be at the scope of the sub-directory" do + markdown = "[Link to Page](./subdirectory/page.md)" + output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) + + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/nested/twice/subdirectory/page.md\"") end end describe "when creating non-hierarchical links" do - let(:nesting) { '' } + it 'rewrites non-file links to be at the scope of the wiki root' do + markdown = "[Link to Page](page)" + output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) - context 'non-file links' do - let(:extension) { '' } - let(:expected_page_path) { 'page' } - it_behaves_like 'a correct link rewrite' + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/page\"") end - context 'non-file links (with spaces)' do - let(:extension) { ' slug' } - let(:expected_page_path) { 'page%20slug' } - it_behaves_like 'a correct link rewrite' + it 'rewrites non-file links (with spaces) to be at the scope of the wiki root' do + markdown = "[Link to Page](page slug)" + output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) + + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/page%20slug\"") end - context "file links" do - let(:extension) { '.md' } - let(:expected_page_path) { 'nested/twice/page.md' } - it_behaves_like 'a correct link rewrite' + it "rewrites file links to be at the scope of the current directory" do + markdown = "[Link to Page](page.md)" + output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) + + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/nested/twice/page.md\"") end - context 'links with anchor' do - let(:extension) { '#title' } - let(:expected_page_path) { 'page#title' } - it_behaves_like 'a correct link rewrite' + it 'rewrites links with anchor' do + markdown = '[Link to Header](start-page#title)' + output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) + + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/start-page#title\"") end - context 'links (with spaces) with anchor' do - let(:extension) { ' two#title' } - let(:expected_page_path) { 'page%20two#title' } - it_behaves_like 'a correct link rewrite' + it 'rewrites links (with spaces) with anchor' do + markdown = '[Link to Header](start page#title)' + output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) + + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/start%20page#title\"") end end describe "when creating root links" do - let(:nesting) { '/' } + it 'rewrites non-file links to be at the scope of the wiki root' do + markdown = "[Link to Page](/page)" + output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) - context 'non-file links' do - let(:extension) { '' } - let(:expected_page_path) { 'page' } - it_behaves_like 'a correct link rewrite' + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/page\"") end - context 'file links' do - let(:extension) { '.md' } - let(:expected_page_path) { 'page.md' } - it_behaves_like 'a correct link rewrite' + it 'rewrites file links to be at the scope of the wiki root' do + markdown = "[Link to Page](/page.md)" + output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) + + expect(output).to include("href=\"#{relative_url_root}/wiki_link_ns/wiki_link_project/wikis/page.md\"") end end end describe "linking to pages outside the wiki (absolute)" do - let(:markdown) { "[Link to Page](http://example.com/page)" } - let(:page_href) { 'http://example.com/page' } - it_behaves_like 'a correct link rewrite' + it "doesn't rewrite links" do + markdown = "[Link to Page](http://example.com/page)" + output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) + + expect(output).to include('href="http://example.com/page"') + end end end end - include_examples 'link examples', :root do - let(:relative_url_root) { '/' } - end - - include_examples 'link examples', :relative do - let(:relative_url_root) { '/nested/relative/gitlab' } - end - describe "checking slug validity when assembling links" do context "with a valid slug" do let(:valid_slug) { "http://example.com" } @@ -273,54 +261,37 @@ describe Banzai::Pipeline::WikiPipeline do end describe 'videos and audio' do - def src(file_name) - "#{prefix}/nested/twice/#{file_name}" - end - - shared_examples 'correct video rewrite' do - let(:markdown) { "![video_file](#{file_name})" } - let(:video_fragment) { "<video src=\"#{prefix}/#{expected_file_path}\"" } - let(:options) do - { - project: project, - project_wiki: project_wiki, - page_slug: page.slug - } - end + let_it_be(:namespace) { create(:namespace, name: "wiki_link_ns") } + let_it_be(:project) { create(:project, :public, name: "wiki_link_project", namespace: namespace) } + let_it_be(:project_wiki) { ProjectWiki.new(project, double(:user)) } + let_it_be(:page) { build(:wiki_page, wiki: project_wiki, page: OpenStruct.new(url_path: 'nested/twice/start-page')) } - it 'generates video html structure' do - output = described_class.to_html(markdown, options) + it 'generates video html structure' do + markdown = "![video_file](video_file_name.mp4)" + output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) - expect(output).to include(video_fragment) - end + expect(output).to include('<video src="/wiki_link_ns/wiki_link_project/wikis/nested/twice/video_file_name.mp4"') end - context 'underscores' do - let(:file_name) { 'video_file_name.mp4' } - let(:expected_file_path) { 'nested/twice/video_file_name.mp4' } - it_behaves_like 'correct video rewrite' - end + it 'rewrites and replaces video links names with white spaces to %20' do + markdown = "![video file](video file name.mp4)" + output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) - context 'spaces' do - let(:file_name) { 'video file name.mp4' } - let(:expected_file_path) { 'nested/twice/video%20file%20name.mp4' } - it_behaves_like 'correct video rewrite' + expect(output).to include('<video src="/wiki_link_ns/wiki_link_project/wikis/nested/twice/video%20file%20name.mp4"') end it 'generates audio html structure' do markdown = "![audio_file](audio_file_name.wav)" - safe_name = "audio_file_name.wav" output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) - expect(output).to include(%Q'<audio src="#{src(safe_name)}"') + expect(output).to include('<audio src="/wiki_link_ns/wiki_link_project/wikis/nested/twice/audio_file_name.wav"') end it 'rewrites and replaces audio links names with white spaces to %20' do markdown = "![audio file](audio file name.wav)" - safe_name = "audio%20file%20name.wav" output = described_class.to_html(markdown, project: project, project_wiki: project_wiki, page_slug: page.slug) - expect(output).to include(%Q'<audio src="#{src(safe_name)}"') + expect(output).to include('<audio src="/wiki_link_ns/wiki_link_project/wikis/nested/twice/audio%20file%20name.wav"') end end end diff --git a/spec/lib/gitlab/tracking_spec.rb b/spec/lib/gitlab/tracking_spec.rb index 3ceaf159b3f..0bb9d6c331f 100644 --- a/spec/lib/gitlab/tracking_spec.rb +++ b/spec/lib/gitlab/tracking_spec.rb @@ -9,6 +9,7 @@ describe Gitlab::Tracking do stub_application_setting(snowplow_collector_hostname: 'gitfoo.com') stub_application_setting(snowplow_cookie_domain: '.gitfoo.com') stub_application_setting(snowplow_site_id: '_abc123_') + stub_application_setting(snowplow_iglu_registry_url: 'https://example.org') end describe '.snowplow_options' do @@ -19,7 +20,8 @@ describe Gitlab::Tracking do cookieDomain: '.gitfoo.com', appId: '_abc123_', formTracking: true, - linkClickTracking: true + linkClickTracking: true, + igluRegistryUrl: 'https://example.org' } expect(subject.snowplow_options(nil)).to match(expected_fields) diff --git a/spec/lib/gitlab/url_builder_spec.rb b/spec/lib/gitlab/url_builder_spec.rb index 4ed2c232f97..08d3c638f9e 100644 --- a/spec/lib/gitlab/url_builder_spec.rb +++ b/spec/lib/gitlab/url_builder_spec.rb @@ -150,7 +150,7 @@ describe Gitlab::UrlBuilder do wiki_page = build(:wiki_page) url = described_class.build(wiki_page) - expect(url).to eq "#{Gitlab.config.gitlab.url}#{wiki_page.wiki.wiki_page_path}/#{wiki_page.slug}" + expect(url).to eq "#{Gitlab.config.gitlab.url}#{wiki_page.wiki.wiki_base_path}/#{wiki_page.slug}" end end end diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb index 8ecab12ca28..4b6c878b20d 100644 --- a/spec/lib/gitlab/usage_data_spec.rb +++ b/spec/lib/gitlab/usage_data_spec.rb @@ -19,7 +19,11 @@ describe Gitlab::UsageData do create(:service, project: projects[2], type: 'SlackService', active: true) create(:project_error_tracking_setting, project: projects[0]) create(:project_error_tracking_setting, project: projects[1], enabled: false) - + create_list(:issue, 4, project: projects[0]) + create(:zoom_meeting, project: projects[0], issue: projects[0].issues[0], issue_status: :added) + create_list(:zoom_meeting, 2, project: projects[0], issue: projects[0].issues[1], issue_status: :removed) + create(:zoom_meeting, project: projects[0], issue: projects[0].issues[2], issue_status: :added) + create_list(:zoom_meeting, 2, project: projects[0], issue: projects[0].issues[2], issue_status: :removed) gcp_cluster = create(:cluster, :provided_by_gcp) create(:cluster, :provided_by_user) create(:cluster, :provided_by_user, :disabled) @@ -125,6 +129,8 @@ describe Gitlab::UsageData do in_review_folder groups issues + issues_with_associated_zoom_link + issues_using_zoom_quick_actions keys label_lists labels @@ -176,6 +182,8 @@ describe Gitlab::UsageData do expect(count_data[:projects_slack_slash_active]).to eq(1) expect(count_data[:projects_with_repositories_enabled]).to eq(3) expect(count_data[:projects_with_error_tracking_enabled]).to eq(1) + expect(count_data[:issues_with_associated_zoom_link]).to eq(2) + expect(count_data[:issues_using_zoom_quick_actions]).to eq(3) expect(count_data[:clusters_enabled]).to eq(7) expect(count_data[:project_clusters_enabled]).to eq(6) diff --git a/spec/lib/gitlab/utils_spec.rb b/spec/lib/gitlab/utils_spec.rb index a68434c8c66..890918d4a7c 100644 --- a/spec/lib/gitlab/utils_spec.rb +++ b/spec/lib/gitlab/utils_spec.rb @@ -252,41 +252,4 @@ describe Gitlab::Utils do expect(described_class.string_to_ip_object('1:0:0:0:0:0:0:0/124')).to eq(IPAddr.new('1:0:0:0:0:0:0:0/124')) end end - - describe '.allow_hash_values' do - it 'removes keys that do not pass the inclusion filters' do - symbols = %i[x y z] - ints = (0..100) - strings = %w[foo bar baz].to_set - - hash = { - a: :x, - b: 100, - c: 'foo', - d: :irrelevant, - aa: :w, - bb: 200, - cc: 'food', - dd: :totally_irrelevant - } - allowed = { - a: symbols, - b: ints, - c: strings, - aa: symbols, - bb: ints, - cc: strings - } - - described_class.allow_hash_values(hash, allowed) - - expect(hash).to eq({ - a: :x, - b: 100, - c: 'foo', - d: :irrelevant, - dd: :totally_irrelevant - }) - end - end end diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb index d16e83bb5df..b6fc152e478 100644 --- a/spec/models/application_setting_spec.rb +++ b/spec/models/application_setting_spec.rb @@ -72,10 +72,14 @@ describe ApplicationSetting do it { is_expected.not_to allow_value(nil).for(:snowplow_collector_hostname) } it { is_expected.to allow_value("snowplow.gitlab.com").for(:snowplow_collector_hostname) } it { is_expected.not_to allow_value('/example').for(:snowplow_collector_hostname) } + it { is_expected.to allow_value('https://example.org').for(:snowplow_iglu_registry_url) } + it { is_expected.not_to allow_value('not-a-url').for(:snowplow_iglu_registry_url) } + it { is_expected.to allow_value(nil).for(:snowplow_iglu_registry_url) } end context 'when snowplow is not enabled' do it { is_expected.to allow_value(nil).for(:snowplow_collector_hostname) } + it { is_expected.to allow_value(nil).for(:snowplow_iglu_registry_url) } end context 'when pendo is enabled' do diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb index c1f6302ee50..4566045bffd 100644 --- a/spec/models/environment_spec.rb +++ b/spec/models/environment_spec.rb @@ -515,6 +515,48 @@ describe Environment, :use_clean_rails_memory_store_caching do end end + describe '#last_visible_deployment' do + subject { environment.last_visible_deployment } + + before do + allow_any_instance_of(Deployment).to receive(:create_ref) + end + + context 'when there is an old deployment record' do + let!(:previous_deployment) { create(:deployment, :success, environment: environment) } + + context 'when there is a deployment record with created status' do + let!(:deployment) { create(:deployment, environment: environment) } + + it { is_expected.to eq(previous_deployment) } + end + + context 'when there is a deployment record with running status' do + let!(:deployment) { create(:deployment, :running, environment: environment) } + + it { is_expected.to eq(deployment) } + end + + context 'when there is a deployment record with success status' do + let!(:deployment) { create(:deployment, :success, environment: environment) } + + it { is_expected.to eq(deployment) } + end + + context 'when there is a deployment record with failed status' do + let!(:deployment) { create(:deployment, :failed, environment: environment) } + + it { is_expected.to eq(deployment) } + end + + context 'when there is a deployment record with canceled status' do + let!(:deployment) { create(:deployment, :canceled, environment: environment) } + + it { is_expected.to eq(deployment) } + end + end + end + describe '#has_terminals?' do subject { environment.has_terminals? } diff --git a/spec/models/project_wiki_spec.rb b/spec/models/project_wiki_spec.rb index f5c827e5a29..31d1d1fd7d1 100644 --- a/spec/models/project_wiki_spec.rb +++ b/spec/models/project_wiki_spec.rb @@ -28,9 +28,7 @@ describe ProjectWiki do describe '#web_url' do it 'returns the full web URL to the wiki' do - home_url = Gitlab::Routing.url_helpers.project_wiki_url(project, :home) - - expect(subject.web_url).to eq(home_url) + expect(subject.web_url).to eq("#{Gitlab.config.gitlab.url}/#{project.full_path}/wikis/home") end end @@ -73,23 +71,9 @@ describe ProjectWiki do describe "#wiki_base_path" do it "returns the wiki base path" do - wiki_path = Gitlab::Routing.url_helpers.project_wikis_path(project) - - expect(subject.wiki_base_path).to eq(wiki_path) - end - end + wiki_base_path = "#{Gitlab.config.gitlab.relative_url_root}/#{project.full_path}/wikis" - describe "#wiki_page_path" do - let(:page) { create(:wiki_page, wiki: project_wiki) } - - describe 'suffixed with /:page_slug' do - subject { "#{project_wiki.wiki_page_path}/#{page.slug}" } - - it "equals the project_wiki_path" do - path = Gitlab::Routing.url_helpers.project_wiki_path(project, page) - - expect(subject).to eq(path) - end + expect(subject.wiki_base_path).to eq(wiki_base_path) end end diff --git a/spec/models/wiki_directory_spec.rb b/spec/models/wiki_directory_spec.rb index aff21888605..5fbcccf897e 100644 --- a/spec/models/wiki_directory_spec.rb +++ b/spec/models/wiki_directory_spec.rb @@ -1,94 +1,14 @@ # frozen_string_literal: true require 'spec_helper' -require 'set' RSpec.describe WikiDirectory do - include GitHelpers - - let(:project) { create(:project, :wiki_repo) } - let(:user) { project.owner } - let(:wiki) { ProjectWiki.new(project, user) } - describe 'validations' do subject { build(:wiki_directory) } it { is_expected.to validate_presence_of(:slug) } end - describe '.group_by_directory' do - context 'when there are no pages' do - it 'returns an empty array' do - expect(described_class.group_by_directory(nil)).to eq([]) - expect(described_class.group_by_directory([])).to eq([]) - end - end - - context 'when there are pages' do - before do - create_page('dir_1/dir_1_1/page_3', 'content') - create_page('page_1', 'content') - create_page('dir_1/page_2', 'content') - create_page('dir_2', 'page with dir name') - create_page('dir_2/page_5', 'content') - create_page('page_6', 'content') - create_page('dir_2/page_4', 'content') - end - - let(:page_1) { wiki.find_page('page_1') } - let(:page_6) { wiki.find_page('page_6') } - let(:page_dir_2) { wiki.find_page('dir_2') } - - let(:dir_1) do - described_class.new('dir_1', [wiki.find_page('dir_1/page_2')]) - end - let(:dir_1_1) do - described_class.new('dir_1/dir_1_1', [wiki.find_page('dir_1/dir_1_1/page_3')]) - end - let(:dir_2) do - pages = [wiki.find_page('dir_2/page_5'), - wiki.find_page('dir_2/page_4')] - described_class.new('dir_2', pages) - end - - context "#list_pages" do - shared_examples "a correct grouping" do - let(:grouped_slugs) { grouped_entries.map(&method(:slugs)) } - let(:expected_slugs) { expected_grouped_entries.map(&method(:slugs)).map(&method(:match_array)) } - - it 'returns an array with pages and directories' do - expect(grouped_slugs).to match_array(expected_slugs) - end - end - - context 'sort by title' do - let(:grouped_entries) { described_class.group_by_directory(wiki.list_pages) } - - let(:expected_grouped_entries) { [dir_1_1, dir_1, page_dir_2, dir_2, page_1, page_6] } - - it_behaves_like "a correct grouping" - end - - context 'sort by created_at' do - let(:grouped_entries) { described_class.group_by_directory(wiki.list_pages(sort: 'created_at')) } - let(:expected_grouped_entries) { [dir_1_1, page_1, dir_1, page_dir_2, dir_2, page_6] } - - it_behaves_like "a correct grouping" - end - - it 'returns an array with retained order with directories at the top' do - expected_order = ['dir_1/dir_1_1/page_3', 'dir_1/page_2', 'dir_2', 'dir_2/page_4', 'dir_2/page_5', 'page_1', 'page_6'] - - grouped_entries = described_class.group_by_directory(wiki.list_pages) - - actual_order = grouped_entries.flat_map(&method(:slugs)) - - expect(actual_order).to eq(expected_order) - end - end - end - end - describe '#initialize' do context 'when there are pages' do let(:pages) { [build(:wiki_page)] } @@ -120,112 +40,7 @@ RSpec.describe WikiDirectory do it 'returns the relative path to the partial to be used' do directory = build(:wiki_directory) - expect(directory.to_partial_path).to eq('projects/wiki_directories/wiki_directory') - end - end - - describe 'attributes' do - def page_path(index) - "dir-path/page-#{index}" - end - - let(:page_paths) { (1..3).map { |n| page_path(n) } } - - let(:pages) do - page_paths.map { |p| wiki.find_page(p) } + expect(directory.to_partial_path).to eq('projects/wikis/wiki_directory') end - - subject { described_class.new('dir-path', pages) } - - context 'there are no pages' do - let(:pages) { [] } - - it { is_expected.to have_attributes(page_count: 0, last_version: be_nil) } - end - - context 'there is one page' do - before do - create_page("dir-path/singleton", "Just this page") - end - - let(:the_page) { wiki.find_page("dir-path/singleton") } - let(:pages) { [the_page] } - - it { is_expected.to have_attributes(page_count: 1, last_version: the_page.last_version) } - end - - context 'there are a few pages, each with a single version' do - before do - page_paths.each_with_index do |path, n| - Timecop.freeze(Time.local(1990) + n.minutes) do - create_page(path, "this is page #{n}") - end - end - end - - let(:expected_last_version) { pages.last.last_version } - - it { is_expected.to have_attributes(page_count: 3, last_version: expected_last_version) } - end - - context 'there are a few pages, each with a few versions' do - before do - page_paths.each_with_index do |path, n| - t = Time.local(1990) + n.minutes - Timecop.freeze(t) do - create_page(path, "This is page #{n}") - (2..3).each do |v| - Timecop.freeze(t + v.seconds) do - update_page(path, "Now at version #{v}") - end - end - end - end - end - - it { is_expected.to have_attributes(page_count: 3, last_version: pages.last.last_version) } - end - end - - private - - def create_page(name, content) - wiki.wiki.write_page(name, :markdown, content, commit_details) - set_time(name) - end - - def update_page(name, content) - wiki.wiki.update_page(name, name, :markdown, content, update_commit_details) - set_time(name) - end - - def set_time(name) - return unless Timecop.frozen? - - new_date = Time.now - page = wiki.find_page(name).page - commit = page.version.commit - repo = commit.instance_variable_get(:@repository) - - rug_commit = rugged_repo_at_path(repo.relative_path).lookup(commit.id) - rug_commit.amend( - message: rug_commit.message, - tree: rug_commit.tree, - author: rug_commit.author.merge(time: new_date), - committer: rug_commit.committer.merge(time: new_date), - update_ref: 'HEAD' - ) - end - - def commit_details - Gitlab::Git::Wiki::CommitDetails.new(user.id, user.username, user.name, user.email, "test commit") - end - - def update_commit_details - Gitlab::Git::Wiki::CommitDetails.new(user.id, user.username, user.name, user.email, "test update") - end - - def slugs(thing) - Array.wrap(thing.respond_to?(:pages) ? thing.pages.map(&:slug) : thing.slug) end end diff --git a/spec/models/wiki_page_spec.rb b/spec/models/wiki_page_spec.rb index 38415613b9e..9014276dcf8 100644 --- a/spec/models/wiki_page_spec.rb +++ b/spec/models/wiki_page_spec.rb @@ -9,6 +9,87 @@ describe WikiPage do subject { described_class.new(wiki) } + describe '.group_by_directory' do + context 'when there are no pages' do + it 'returns an empty array' do + expect(described_class.group_by_directory(nil)).to eq([]) + expect(described_class.group_by_directory([])).to eq([]) + end + end + + context 'when there are pages' do + before do + create_page('dir_1/dir_1_1/page_3', 'content') + create_page('page_1', 'content') + create_page('dir_1/page_2', 'content') + create_page('dir_2', 'page with dir name') + create_page('dir_2/page_5', 'content') + create_page('page_6', 'content') + create_page('dir_2/page_4', 'content') + end + + let(:page_1) { wiki.find_page('page_1') } + let(:page_6) { wiki.find_page('page_6') } + let(:page_dir_2) { wiki.find_page('dir_2') } + + let(:dir_1) do + WikiDirectory.new('dir_1', [wiki.find_page('dir_1/page_2')]) + end + let(:dir_1_1) do + WikiDirectory.new('dir_1/dir_1_1', [wiki.find_page('dir_1/dir_1_1/page_3')]) + end + let(:dir_2) do + pages = [wiki.find_page('dir_2/page_5'), + wiki.find_page('dir_2/page_4')] + WikiDirectory.new('dir_2', pages) + end + + context "#list_pages" do + context 'sort by title' do + let(:grouped_entries) { described_class.group_by_directory(wiki.list_pages) } + let(:expected_grouped_entries) { [dir_1_1, dir_1, page_dir_2, dir_2, page_1, page_6] } + + it 'returns an array with pages and directories' do + grouped_entries.each_with_index do |page_or_dir, i| + expected_page_or_dir = expected_grouped_entries[i] + expected_slugs = get_slugs(expected_page_or_dir) + slugs = get_slugs(page_or_dir) + + expect(slugs).to match_array(expected_slugs) + end + end + end + + context 'sort by created_at' do + let(:grouped_entries) { described_class.group_by_directory(wiki.list_pages(sort: 'created_at')) } + let(:expected_grouped_entries) { [dir_1_1, page_1, dir_1, page_dir_2, dir_2, page_6] } + + it 'returns an array with pages and directories' do + grouped_entries.each_with_index do |page_or_dir, i| + expected_page_or_dir = expected_grouped_entries[i] + expected_slugs = get_slugs(expected_page_or_dir) + slugs = get_slugs(page_or_dir) + + expect(slugs).to match_array(expected_slugs) + end + end + end + + it 'returns an array with retained order with directories at the top' do + expected_order = ['dir_1/dir_1_1/page_3', 'dir_1/page_2', 'dir_2', 'dir_2/page_4', 'dir_2/page_5', 'page_1', 'page_6'] + + grouped_entries = described_class.group_by_directory(wiki.list_pages) + + actual_order = + grouped_entries.flat_map do |page_or_dir| + get_slugs(page_or_dir) + end + expect(actual_order).to eq(expected_order) + end + end + end + end + describe '.unhyphenize' do it 'removes hyphens from a name' do name = 'a-name--with-hyphens' @@ -441,7 +522,7 @@ describe WikiPage do it 'returns the relative path to the partial to be used' do page = build(:wiki_page) - expect(page.to_partial_path).to eq('projects/wiki_pages/wiki_page') + expect(page.to_partial_path).to eq('projects/wikis/wiki_page') end end @@ -521,4 +602,12 @@ describe WikiPage do page = wiki.wiki.page(title: title, dir: dir) wiki.delete_page(page, "test commit") end + + def get_slugs(page_or_dir) + if page_or_dir.is_a? WikiPage + [page_or_dir.slug] + else + page_or_dir.pages.present? ? page_or_dir.pages.map(&:slug) : [] + end + end end diff --git a/spec/requests/api/settings_spec.rb b/spec/requests/api/settings_spec.rb index 0f1aa9bb2bb..760eafe33e4 100644 --- a/spec/requests/api/settings_spec.rb +++ b/spec/requests/api/settings_spec.rb @@ -178,7 +178,8 @@ describe API::Settings, 'Settings' do snowplow_collector_hostname: "snowplow.example.com", snowplow_cookie_domain: ".example.com", snowplow_enabled: true, - snowplow_site_id: "site_id" + snowplow_site_id: "site_id", + snowplow_iglu_registry_url: 'https://example.com' } end diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb index 741a981a3b1..28778bf26d4 100644 --- a/spec/routing/project_routing_spec.rb +++ b/spec/routing/project_routing_spec.rb @@ -5,12 +5,9 @@ require 'spec_helper' describe 'project routing' do before do allow(Project).to receive(:find_by_full_path).and_return(false) - allow(Project).to receive(:find_by_full_path).with('gitlab/gitlabhq', any_args).and_return(project) + allow(Project).to receive(:find_by_full_path).with('gitlab/gitlabhq', any_args).and_return(true) end - set(:namespace) { create(:namespace, name: 'gitlab') } - set(:project) { create(:project, namespace: namespace, name: 'gitlabhq') } - # Shared examples for a resource inside a Project # # By default it tests all the default REST actions: index, create, new, edit, @@ -150,39 +147,24 @@ describe 'project routing' do it_behaves_like 'redirecting a legacy project path', "/gitlab/gitlabhq/autocomplete_sources/labels", "/gitlab/gitlabhq/-/autocomplete_sources/labels" end - # GET /:project_id/wikis/pages(.:format) projects/wikis#pages - # GET /:project_id/-/wiki_pages/:id/history(.:format) projects/wiki_pages#history - # POST /:project_id/-/wiki_pages(.:format) projects/wiki_pages#create - # GET /:project_id/-/wiki_pages/:id/edit(.:format) projects/wiki_pages#edit - # GET /:project_id/-/wiki_pages/:id(.:format) projects/wiki_pages#show - # DELETE /:project_id/-/wiki_pages/:id(.:format) projects/wiki_pages#destroy + # pages_project_wikis GET /:project_id/wikis/pages(.:format) projects/wikis#pages + # history_project_wiki GET /:project_id/wikis/:id/history(.:format) projects/wikis#history + # project_wikis POST /:project_id/wikis(.:format) projects/wikis#create + # edit_project_wiki GET /:project_id/wikis/:id/edit(.:format) projects/wikis#edit + # project_wiki GET /:project_id/wikis/:id(.:format) projects/wikis#show + # DELETE /:project_id/wikis/:id(.:format) projects/wikis#destroy describe Projects::WikisController, 'routing' do - let(:wiki) { ProjectWiki.new(project, project.owner) } - let(:wiki_page) { create(:wiki_page, wiki: wiki) } - - it '#pages' do - expect(get('/gitlab/gitlabhq/wikis/pages')) - .to route_to('projects/wikis#pages', - namespace_id: 'gitlab', - project_id: 'gitlabhq') + it 'to #pages' do + expect(get('/gitlab/gitlabhq/wikis/pages')).to route_to('projects/wikis#pages', namespace_id: 'gitlab', project_id: 'gitlabhq') end - describe '#history' do - let(:history_path) { project_wiki_history_path(project, wiki_page) } - - it 'routes to history' do - expect(get(history_path)) - .to route_to('projects/wiki_pages#history', - namespace_id: namespace.path, - project_id: project.name, - id: wiki_page.slug) - end + it 'to #history' do + expect(get('/gitlab/gitlabhq/wikis/1/history')).to route_to('projects/wikis#history', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') end it_behaves_like 'RESTful project resources' do let(:actions) { [:create, :edit, :show, :destroy] } - let(:controller) { 'wiki_pages' } - let(:controller_path) { '-/wiki_pages' } + let(:controller) { 'wikis' } end end diff --git a/spec/routing/wiki_routing_spec.rb b/spec/routing/wiki_routing_spec.rb deleted file mode 100644 index 94349dbaa74..00000000000 --- a/spec/routing/wiki_routing_spec.rb +++ /dev/null @@ -1,103 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -# We build URIs to wiki pages manually in various places (most notably -# in markdown generation). To ensure these do not get out of sync, these -# tests verify that our path generation assumptions are sound. -describe 'Wiki path generation assumptions' do - set(:project) { create(:project, :public, :repository) } - - let(:project_wiki) { ProjectWiki.new(project, project.owner) } - let(:some_page_name) { 'some-wiki-page' } - let(:wiki_page) do - create(:wiki_page, wiki: project_wiki, attrs: { title: some_page_name }) - end - - describe 'WikiProject#wiki_page_path', 'routing' do - it 'is consistent with routing to wiki#show' do - uri = URI.parse(project_wiki.wiki_page_path) - path = ::File.join(uri.path, some_page_name) - - expect(get('/' + path)).to route_to('projects/wiki_pages#show', - id: some_page_name, - namespace_id: project.namespace.to_param, - project_id: project.to_param) - end - end - - describe 'project_wiki_path', 'routing' do - describe 'GET' do - it 'routes to the :show action' do - path = project_wiki_path(project, wiki_page) - - expect(get('/' + path)).to route_to('projects/wiki_pages#show', - id: wiki_page.slug, - namespace_id: project.namespace.to_param, - project_id: project.to_param) - end - end - end - - describe 'project_wiki_pages_new_path', 'routing' do - describe 'GET' do - it 'routes to the :new action' do - path = project_wiki_pages_new_path(project) - - expect(get('/' + path)).to route_to('projects/wiki_pages#new', - namespace_id: project.namespace.to_param, - project_id: project.to_param) - end - end - end - - # Early versions of the wiki paths routed all wiki pages at - # /wikis/:id - this test exists to guarantee that we support - # old URIs that may be out there, saved in bookmarks, on other wikis, etc. - describe 'legacy route support', type: 'request' do - let(:path) { ::File.join(project_wikis_path(project), some_page_name) } - - before do - get(path) - end - - it 'routes to new wiki paths' do - dest = project_wiki_path(project, wiki_page) - - expect(response).to redirect_to(dest) - end - - context 'the page is nested in a directory' do - let(:some_page_name) { 'some-dir/some-deep-dir/some-page' } - let(:path) { ::File.join(project_wikis_path(project), some_page_name) } - - it 'still routes correctly' do - dest = project_wiki_path(project, wiki_page) - - expect(response).to redirect_to(dest) - end - end - - context 'the user requested the old history path' do - let(:some_page_name) { 'some-dir/some-deep-dir/some-page' } - let(:path) { ::File.join(project_wikis_path(project), some_page_name, 'history') } - - it 'redirects to the new history path' do - dest = project_wiki_history_path(project, wiki_page) - - expect(response).to redirect_to(dest) - end - end - - context 'the user requested the old edit path' do - let(:some_page_name) { 'some-dir/some-deep-dir/some-page' } - let(:path) { ::File.join(project_wikis_path(project), some_page_name, 'edit') } - - it 'redirects to the new history path' do - dest = project_wiki_edit_path(project, wiki_page) - - expect(response).to redirect_to(dest) - end - end - end -end diff --git a/spec/support/controllers/authorization_helpers.rb b/spec/support/controllers/authorization_helpers.rb deleted file mode 100644 index e1786e0ca8a..00000000000 --- a/spec/support/controllers/authorization_helpers.rb +++ /dev/null @@ -1,6 +0,0 @@ -# frozen_string_literal: true - -def forbid_controller_ability!(ability) - allow(controller).to receive(:can?).and_call_original - allow(controller).to receive(:can?).with(anything, ability, any_args).and_return(false) -end diff --git a/spec/support/helpers/capybara_helpers.rb b/spec/support/helpers/capybara_helpers.rb index 13ec179b734..a7baa7042c9 100644 --- a/spec/support/helpers/capybara_helpers.rb +++ b/spec/support/helpers/capybara_helpers.rb @@ -46,14 +46,4 @@ module CapybaraHelpers def javascript_test? Capybara.current_driver == Capybara.javascript_driver end - - def scroll_to(element) - raise 'JS not available' unless javascript_test? - - script = <<-JS - arguments[0].scrollIntoView(true); - JS - - page.driver.browser.execute_script(script, element.native) - end end diff --git a/spec/support/helpers/dropzone_helper.rb b/spec/support/helpers/dropzone_helper.rb index 3f37673dadd..a0f261b312e 100644 --- a/spec/support/helpers/dropzone_helper.rb +++ b/spec/support/helpers/dropzone_helper.rb @@ -14,8 +14,6 @@ module DropzoneHelper # If it's 'false', then the helper will NOT wait for backend response # It lets to test behaviors while AJAX is processing. def dropzone_file(files, max_file_size = 0, wait_for_queuecomplete = true) - # Assert that there is a dropzone to use (waiting until it is ready) - expect(page).to have_css('.div-dropzone') # Generate a fake file input that Capybara can attach to page.execute_script <<-JS.strip_heredoc $('#fakeFileInput').remove(); diff --git a/spec/support/helpers/git_helpers.rb b/spec/support/helpers/git_helpers.rb index 05e31a1154a..99c5871ba54 100644 --- a/spec/support/helpers/git_helpers.rb +++ b/spec/support/helpers/git_helpers.rb @@ -2,11 +2,8 @@ module GitHelpers def rugged_repo(repository) - rugged_repo_at_path(repository.disk_path + '.git') - end + path = File.join(TestEnv.repos_path, repository.disk_path + '.git') - def rugged_repo_at_path(relative_path) - path = File.join(TestEnv.repos_path, relative_path) Rugged::Repository.new(path) end end diff --git a/spec/support/helpers/wiki_helpers.rb b/spec/support/helpers/wiki_helpers.rb index 0cf70fd4ef7..06cea728b42 100644 --- a/spec/support/helpers/wiki_helpers.rb +++ b/spec/support/helpers/wiki_helpers.rb @@ -12,10 +12,4 @@ module WikiHelpers ::Wikis::CreateAttachmentService.new(project, user, opts) .execute[:result][:file_path] end - - # Generate the form field name for a given attribute of an object. - # This is rather general, but is currently only used in the wiki featur tests. - def form_field_name(obj, attr_name) - "#{ActiveModel::Naming.param_key(obj)}[#{attr_name}]" - end end diff --git a/spec/support/matchers/issuable_matchers.rb b/spec/support/matchers/issuable_matchers.rb index ab15a80bf60..743f0b8c932 100644 --- a/spec/support/matchers/issuable_matchers.rb +++ b/spec/support/matchers/issuable_matchers.rb @@ -2,8 +2,7 @@ RSpec::Matchers.define :have_header_with_correct_id_and_link do |level, text, id, parent = ".md"| match do |actual| - # anchors may be invisible - node = find("#{parent} h#{level} a#user-content-#{id}", visible: false) + node = find("#{parent} h#{level} a#user-content-#{id}") expect(node[:href]).to end_with("##{id}") diff --git a/spec/support/shared_examples/requests/api/discussions.rb b/spec/support/shared_examples/requests/api/discussions.rb index a36bc2dc9b5..2a5a48f3054 100644 --- a/spec/support/shared_examples/requests/api/discussions.rb +++ b/spec/support/shared_examples/requests/api/discussions.rb @@ -117,6 +117,29 @@ shared_examples 'discussions API' do |parent_type, noteable_type, id_name, can_r expect(response).to have_gitlab_http_status(401) end + it 'tracks a Notes::CreateService event' do + expect(Gitlab::Tracking).to receive(:event) do |category, action, data| + expect(category).to eq('Notes::CreateService') + expect(action).to eq('execute') + expect(data[:label]).to eq('note') + expect(data[:value]).to be_an(Integer) + end + + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/discussions", user), params: { body: 'hi!' } + end + + context 'with notes_create_service_tracking feature flag disabled' do + before do + stub_feature_flags(notes_create_service_tracking: false) + end + + it 'does not track any events' do + expect(Gitlab::Tracking).not_to receive(:event) + + post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/discussions"), params: { body: 'hi!' } + end + end + context 'when an admin or owner makes the request' do it 'accepts the creation date to be set' do creation_time = 2.weeks.ago diff --git a/spec/support/shared_examples/wiki_file_attachments_examples.rb b/spec/support/shared_examples/wiki_file_attachments_examples.rb index a43b7c0300f..22fbfb48928 100644 --- a/spec/support/shared_examples/wiki_file_attachments_examples.rb +++ b/spec/support/shared_examples/wiki_file_attachments_examples.rb @@ -42,7 +42,7 @@ shared_examples 'wiki file attachments' do end end - context 'uploading is complete' do + context 'uploading is complete', :quarantine do it 'shows "Attach a file" button on uploading complete' do attach_with_dropzone wait_for_requests @@ -52,11 +52,11 @@ shared_examples 'wiki file attachments' do end it 'the markdown link is added to the page' do - fill_in(:wiki_page_content, with: '') + fill_in(:wiki_content, with: '') attach_with_dropzone(true) wait_for_requests - expect(page.find('#wiki_page_content').value) + expect(page.find('#wiki_content').value) .to match(%r{\!\[dk\]\(uploads/\h{32}/dk\.png\)$}) end @@ -70,7 +70,7 @@ shared_examples 'wiki file attachments' do img_link = page.find('a.no-attachment-icon img')['src'] expect(link).to eq img_link - expect(URI.parse(link).path).to eq File.join(wiki.wiki_page_path, file_path) + expect(URI.parse(link).path).to eq File.join(wiki.wiki_base_path, file_path) end it 'the file has been added to the wiki repository' do |