diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-09-29 12:09:49 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-09-29 12:09:49 +0300 |
commit | 58d68e313f0152df721146e22282f9cccd2ccb4a (patch) | |
tree | a454c881ee884f7d329cf0528ddfb0e2eb1e7c59 /spec | |
parent | cd54f7e81bbedff94ea78092f44fb67bd8c2ac57 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
27 files changed, 1085 insertions, 987 deletions
diff --git a/spec/features/projects/wiki/markdown_preview_spec.rb b/spec/features/projects/wiki/markdown_preview_spec.rb deleted file mode 100644 index 8f2fb9e827c..00000000000 --- a/spec/features/projects/wiki/markdown_preview_spec.rb +++ /dev/null @@ -1,168 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe 'Projects > Wiki > User previews markdown changes', :js do - let_it_be(:user) { create(:user) } - let(:project) { create(:project, :wiki_repo, namespace: user.namespace) } - let(:wiki_page) { create(:wiki_page, wiki: project.wiki, title: 'home', content: '[some link](other-page)') } - let(:wiki_content) do - <<-HEREDOC -Some text so key event for [ does not trigger an incorrect replacement. -[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) - 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) - - 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', 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 - - 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) - - 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 "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" - - 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 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/shortcuts_spec.rb b/spec/features/projects/wiki/shortcuts_spec.rb deleted file mode 100644 index 170e7afb51f..00000000000 --- a/spec/features/projects/wiki/shortcuts_spec.rb +++ /dev/null @@ -1,20 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe 'Wiki shortcuts', :js do - let(:user) { create(:user) } - let(:project) { create(:project, :wiki_repo, namespace: user.namespace) } - let(:wiki_page) { create(:wiki_page, wiki: project.wiki, title: 'home', content: 'Home page') } - - before do - sign_in(user) - visit project_wiki_path(project, wiki_page) - end - - it 'Visit edit wiki page using "e" keyboard shortcut' do - find('body').native.send_key('e') - - expect(find('.wiki-page-title')).to have_content('Edit 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 deleted file mode 100644 index eba1b63765a..00000000000 --- a/spec/features/projects/wiki/user_creates_wiki_page_spec.rb +++ /dev/null @@ -1,360 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -RSpec.describe "User creates wiki page" do - include WikiHelpers - - let(:user) { create(:user) } - let(:wiki) { ProjectWiki.new(project, user) } - let(:project) { create(:project) } - - before do - project.add_maintainer(user) - - sign_in(user) - end - - context "when wiki is empty" do - before do |example| - visit(project_wikis_path(project)) - - wait_for_svg_to_be_loaded(example) - - click_link "Create your first page" - end - - context "in a user namespace" do - let(:project) { create(:project, :wiki_repo, namespace: user.namespace) } - - it "shows validation error message" do - page.within(".wiki-form") do - fill_in(:wiki_content, with: "") - - click_on("Create page") - end - - expect(page).to have_content("The form contains the following error:").and have_content("Content can't be blank") - - page.within(".wiki-form") do - fill_in(:wiki_content, with: "[link test](test)") - - click_on("Create page") - end - - expect(page).to have_content("Home").and have_content("link test") - - click_link("link test") - - expect(page).to have_content("Create New Page") - end - - it "shows non-escaped link in the pages list" do - 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(page).to have_xpath("//a[@href='/#{project.full_path}/-/wikis/one/two/three-test']") - end - - 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 - 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") - - 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") - .and have_content("Home") - .and have_content("Last edited by #{user.name}") - .and have_header_with_correct_id_and_link(1, "Wiki header", "wiki-header") - - click_link("test") - - expect(current_path).to eq(project_wiki_path(project, "test")) - - page.within(:css, ".nav-text") do - expect(page).to have_content("Create New Page") - end - - click_link("Home") - - expect(current_path).to eq(project_wiki_path(project, "home")) - - click_link("GitLab API") - - expect(current_path).to eq(project_wiki_path(project, "api")) - - page.within(:css, ".nav-text") do - expect(page).to have_content("Create") - end - - click_link("Home") - - expect(current_path).to eq(project_wiki_path(project, "home")) - - click_link("Rake tasks") - - expect(current_path).to eq(project_wiki_path(project, "raketasks")) - - page.within(:css, ".nav-text") do - expect(page).to have_content("Create") - end - end - - it "creates ASCII wiki with LaTeX blocks", :js do - stub_application_setting(plantuml_url: "http://localhost", plantuml_enabled: true) - - ascii_content = <<~MD - :stem: latexmath - - [stem] - ++++ - \\sqrt{4} = 2 - ++++ - - another part - - [latexmath] - ++++ - \\beta_x \\gamma - ++++ - - stem:[2+2] is 4 - MD - - find("#wiki_format option[value=asciidoc]").select_option - - fill_in(:wiki_content, with: 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 'creates a wiki page with Org markup', :aggregate_failures do - org_content = <<~ORG - * Heading - ** Subheading - [[home][Link to Home]] - ORG - - page.within('.wiki-form') do - find('#wiki_format option[value=org]').select_option - fill_in(:wiki_content, with: org_content) - click_button('Create page') - end - - expect(page).to have_selector('h1', text: 'Heading') - expect(page).to have_selector('h2', text: 'Subheading') - expect(page).to have_link('Link to Home', href: "/#{project.full_path}/-/wikis/home") - end - - it_behaves_like 'wiki file attachments' - end - - context "in a group namespace", :js do - let(:project) { create(:project, :wiki_repo, namespace: create(:group, :public)) } - - it "has `Create home` as a commit message" 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.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}") - .and have_content("My awesome wiki!") - end - end - end - - context "when wiki is not empty", :js do - before do - create(:wiki_page, wiki: wiki, title: 'home', content: 'Home page') - - visit(project_wikis_path(project)) - end - - context "in a user namespace" do - let(:project) { create(:project, :wiki_repo, namespace: user.namespace) } - - context "via the `new wiki page` page" do - it "creates a page with a single word" 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 - - 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 - click_link("New page") - - page.within(".wiki-form") do - find("#wiki_content").native.send_keys("") - - fill_in(:wiki_content, with: ":") - end - - expect(page).to have_selector(".atwho-view") - end - end - - context "in a group namespace" do - let(:project) { create(:project, :wiki_repo, namespace: create(:group, :public)) } - - context "via the `new wiki page` page" do - 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 - - describe 'sidebar feature' do - context 'when there are some existing pages' do - before do - create(:wiki_page, wiki: wiki, title: 'home', content: 'home') - create(:wiki_page, wiki: wiki, title: 'another', content: 'another') - end - - it 'renders a default sidebar when there is no customized sidebar' do - visit(project_wikis_path(project)) - - expect(page).to have_content('another') - expect(page).not_to have_link('View All Pages') - end - - context 'when there is a customized sidebar' do - before do - create(:wiki_page, wiki: wiki, title: '_sidebar', content: 'My customized sidebar') - end - - it 'renders my customized sidebar instead of the default one' do - visit(project_wikis_path(project)) - - expect(page).to have_content('My customized sidebar') - expect(page).not_to have_content('Another') - end - end - end - - context 'when there are 15 existing pages' do - before do - (1..5).each { |i| create(:wiki_page, wiki: wiki, title: "my page #{i}") } - (6..10).each { |i| create(:wiki_page, wiki: wiki, title: "parent/my page #{i}") } - (11..15).each { |i| create(:wiki_page, wiki: wiki, title: "grandparent/parent/my page #{i}") } - end - - it 'shows all pages in the sidebar' do - visit(project_wikis_path(project)) - - (1..15).each { |i| expect(page).to have_content("my page #{i}") } - expect(page).not_to have_link('View All Pages') - end - - context 'when there are more than 15 existing pages' do - before do - create(:wiki_page, wiki: wiki, title: 'my page 16') - end - - it 'shows the first 15 pages in the sidebar' do - visit(project_wikis_path(project)) - - expect(page).to have_text('my page', count: 15) - expect(page).to have_link('View All Pages') - end - 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 deleted file mode 100644 index a5d865d581b..00000000000 --- a/spec/features/projects/wiki/user_deletes_wiki_page_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.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) } - - before do - sign_in(user) - visit(project_wiki_path(project, wiki_page)) - end - - it 'deletes a page' do - click_on('Edit') - click_on('Delete') - find('.modal-footer .btn-danger').click - - expect(page).to have_content('Page was successfully deleted') - 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 deleted file mode 100644 index fdab63a56b8..00000000000 --- a/spec/features/projects/wiki/user_updates_wiki_page_spec.rb +++ /dev/null @@ -1,263 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe 'User updates wiki page' do - include WikiHelpers - - let(:user) { create(:user) } - - before do - project.add_maintainer(user) - sign_in(user) - end - - context 'when wiki is empty' do - before do |example| - visit(project_wikis_path(project)) - - wait_for_svg_to_be_loaded(example) - - click_link "Create your first page" - end - - context 'in a user namespace' do - let(:project) { create(:project, :wiki_repo) } - - it 'redirects back to the home edit page' do - page.within(:css, '.wiki-form .form-actions') do - click_on('Cancel') - end - - expect(current_path).to eq wiki_path(project.wiki) - end - - it 'updates a page that has a path', :js do - 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') - - first(:link, text: 'three').click - - expect(find('.nav-text')).to have_content('three') - - click_on('Edit') - - expect(current_path).to include('one/two/three-test') - expect(page).to have_content('Edit Page') - - fill_in('Content', with: 'Updated Wiki Content') - click_on('Save changes') - - expect(page).to have_content('Updated Wiki Content') - end - - it_behaves_like 'wiki file attachments' - end - end - - context 'when wiki is not empty' do - let(:project_wiki) { create(:project_wiki, project: project, user: project.creator) } - let!(:wiki_page) { create(:wiki_page, wiki: project_wiki, title: 'home', content: 'Home page') } - - before do - visit(project_wikis_path(project)) - - click_link('Edit') - end - - context 'in a user namespace' do - let(:project) { create(:project, :wiki_repo) } - - it 'updates a page', :js do - # Commit message field should have correct value. - expect(page).to have_field('wiki[message]', with: 'Update home') - - fill_in(:wiki_content, with: 'My awesome wiki!') - click_button('Save changes') - - expect(page).to have_content('Home') - expect(page).to have_content("Last edited by #{user.name}") - expect(page).to have_content('My awesome wiki!') - end - - it 'updates the commit message as the title is changed', :js do - fill_in(:wiki_title, with: '& < > \ \ { } &') - - expect(page).to have_field('wiki[message]', with: 'Update & < > \ \ { } &') - end - - it 'correctly escapes the commit message entities', :js do - fill_in(:wiki_title, with: 'Wiki title') - - expect(page).to have_field('wiki[message]', with: 'Update Wiki title') - end - - it 'shows a validation error message' do - 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_content').value).to eq('') - end - - it 'shows the emoji autocompletion dropdown', :js do - find('#wiki_content').native.send_keys('') - fill_in(:wiki_content, with: ':') - - expect(page).to have_selector('.atwho-view') - end - - it 'shows the error message' do - wiki_page.update(content: 'Update') - - click_button('Save changes') - - expect(page).to have_content('Someone edited the page the same time you did.') - end - - it 'updates a page' do - fill_in('Content', with: 'Updated Wiki Content') - click_on('Save changes') - - expect(page).to have_content('Updated Wiki Content') - end - - it 'cancels editing of a page' do - page.within(:css, '.wiki-form .form-actions') do - click_on('Cancel') - end - - expect(current_path).to eq(project_wiki_path(project, wiki_page)) - end - - it_behaves_like 'wiki file attachments' - end - - context 'in a group namespace' do - let(:project) { create(:project, :wiki_repo, namespace: create(:group, :public)) } - - it 'updates a page', :js do - # Commit message field should have correct value. - expect(page).to have_field('wiki[message]', with: 'Update home') - - fill_in(:wiki_content, with: 'My awesome wiki!') - - click_button('Save changes') - - expect(page).to have_content('Home') - expect(page).to have_content("Last edited by #{user.name}") - expect(page).to have_content('My awesome wiki!') - end - - it_behaves_like 'wiki file attachments' - end - end - - context 'when the page is in a subdir' do - let!(:project) { create(:project, :wiki_repo) } - let(:project_wiki) { create(:project_wiki, project: project, user: project.creator) } - let(:page_name) { 'page_name' } - let(:page_dir) { "foo/bar/#{page_name}" } - let!(:wiki_page) { create(:wiki_page, wiki: project_wiki, title: page_dir, content: 'Home page') } - - before do - visit(project_wiki_edit_path(project, wiki_page)) - end - - it 'moves the page to the root folder' do - fill_in(:wiki_title, with: "/#{page_name}") - - click_button('Save changes') - - expect(current_path).to eq(project_wiki_path(project, page_name)) - end - - it 'moves the page to other dir' do - 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_dir)) - end - - it 'remains in the same place if title has not changed' do - original_path = project_wiki_path(project, wiki_page) - - 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_dir = "foo1/bar1/new_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_dir)) - end - - it 'can be renamed and moved to the root folder' do - new_name = 'new_page_name' - - fill_in(:wiki_title, with: "/#{new_name}") - - click_button('Save changes') - - expect(current_path).to eq(project_wiki_path(project, new_name)) - end - - it 'squishes the title before creating the page' do - 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, "foo1/bar1/#{page_name}")) - end - - it_behaves_like 'wiki file attachments' - end - - context 'when an existing page exceeds the content size limit' do - let_it_be(:project) { create(:project, :wiki_repo) } - let!(:wiki_page) { create(:wiki_page, wiki: project.wiki, content: "one\ntwo\nthree") } - - before do - stub_application_setting(wiki_page_max_content_bytes: 10) - - visit wiki_page_path(wiki_page.wiki, wiki_page, action: :edit) - end - - it 'allows changing the title if the content does not change' do - fill_in 'Title', with: 'new title' - click_on 'Save changes' - - expect(page).to have_content('Wiki was successfully updated.') - end - - it 'shows a validation error when trying to change the content' do - fill_in 'Content', with: 'new content' - click_on 'Save changes' - - expect(page).to have_content('The form contains the following error:') - expect(page).to have_content('Content is too long (11 Bytes). The maximum size is 10 Bytes.') - end - end -end diff --git a/spec/features/projects/wiki/user_views_wiki_empty_spec.rb b/spec/features/projects/wiki/user_views_wiki_empty_spec.rb index 0af40a2d760..1f460f39267 100644 --- a/spec/features/projects/wiki/user_views_wiki_empty_spec.rb +++ b/spec/features/projects/wiki/user_views_wiki_empty_spec.rb @@ -2,108 +2,86 @@ require 'spec_helper' -RSpec.describe 'User views empty wiki' do - let(:user) { create(:user) } - let(:confluence_link) { 'Enable the Confluence Wiki integration' } - let(:element) { page.find('.row.empty-state') } - - shared_examples 'empty wiki and accessible issues' do - it 'show "issue tracker" message' do - visit(project_wikis_path(project)) - - expect(element).to have_content('This project has no wiki pages') - expect(element).to have_content('You must be a project member') - expect(element).to have_content('improve the wiki for this project') - expect(element).to have_link("issue tracker", href: project_issues_path(project)) - expect(element).to have_link("Suggest wiki improvement", href: new_project_issue_path(project)) - expect(element).to have_no_link(confluence_link) - end - end - - shared_examples 'empty wiki and non-accessible issues' do - it 'does not show "issue tracker" message' do - visit(project_wikis_path(project)) +RSpec.describe 'Project > User views empty wiki' do + let_it_be(:user) { create(:user) } - expect(element).to have_content('This project has no wiki pages') - expect(element).to have_content('You must be a project member') - expect(element).to have_no_link('Suggest wiki improvement') - expect(element).to have_no_link(confluence_link) - end - end + let(:wiki) { create(:project_wiki, project: project) } - context 'when user is logged out and issue tracker is public' do - let(:project) { create(:project, :public, :wiki_repo) } + it_behaves_like 'User views empty wiki' do + context 'when project is public' do + let(:project) { create(:project, :public) } - it_behaves_like 'empty wiki and accessible issues' - end + it_behaves_like 'empty wiki message', issuable: true - context 'when user is logged in and not a member' do - let(:project) { create(:project, :public, :wiki_repo) } + context 'when issue tracker is private' do + let(:project) { create(:project, :public, :issues_private) } - before do - sign_in(user) - end + it_behaves_like 'empty wiki message', issuable: false + end - it_behaves_like 'empty wiki and accessible issues' - end + context 'when issue tracker is disabled' do + let(:project) { create(:project, :public, :issues_disabled) } - context 'when issue tracker is private' do - let(:project) { create(:project, :public, :wiki_repo, :issues_private) } + it_behaves_like 'empty wiki message', issuable: false + end - it_behaves_like 'empty wiki and non-accessible issues' - end + context 'and user is logged in' do + before do + sign_in(user) + end - context 'when issue tracker is disabled' do - let(:project) { create(:project, :public, :wiki_repo, :issues_disabled) } + context 'and user is not a member' do + it_behaves_like 'empty wiki message', issuable: true + end - it_behaves_like 'empty wiki and non-accessible issues' - end + context 'and user is a member' do + before do + project.add_developer(user) + end - context 'when user is logged in and a member' do - let(:project) { create(:project, :public) } - - before do - sign_in(user) - project.add_developer(user) + it_behaves_like 'empty wiki message', writable: true, issuable: true + end + end end - it 'shows "create first page" message' do - visit(project_wikis_path(project)) - - expect(element).to have_content('your project', count: 2) + context 'when project is private' do + let(:project) { create(:project, :private) } - element.click_link 'Create your first page' + it_behaves_like 'wiki is not found' - expect(page).to have_button('Create page') - end + context 'and user is logged in' do + before do + sign_in(user) + end - it 'does not show the "enable confluence" button' do - visit(project_wikis_path(project)) + context 'and user is not a member' do + it_behaves_like 'wiki is not found' + end - expect(element).to have_no_link(confluence_link) - end - end + context 'and user is a member' do + before do + project.add_developer(user) + end - context 'when user is logged in and an admin' do - let(:project) { create(:project, :public, :wiki_repo) } + it_behaves_like 'empty wiki message', writable: true, issuable: true + end - before do - sign_in(user) - project.add_maintainer(user) - end - - it 'shows the "enable confluence" button' do - visit(project_wikis_path(project)) - - expect(element).to have_link(confluence_link) - end + context 'and user is a maintainer' do + before do + project.add_maintainer(user) + end - it 'does not show "enable confluence" button if confluence is already enabled' do - create(:confluence_service, project: project) + it_behaves_like 'empty wiki message', writable: true, issuable: true, confluence: true - visit(project_wikis_path(project)) + context 'and Confluence is already enabled' do + before do + create(:confluence_service, project: project) + end - expect(element).to have_no_link(confluence_link) + it_behaves_like 'empty wiki message', writable: true, issuable: true, confluence: false + end + end + end end end end diff --git a/spec/features/projects/wikis_spec.rb b/spec/features/projects/wikis_spec.rb new file mode 100644 index 00000000000..1c66ad81145 --- /dev/null +++ b/spec/features/projects/wikis_spec.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe 'Project wikis' do + let_it_be(:user) { create(:user) } + + let(:wiki) { create(:project_wiki, user: user, project: project) } + let(:project) { create(:project, namespace: user.namespace, creator: user) } + + it_behaves_like 'User creates wiki page' + it_behaves_like 'User deletes wiki page' + it_behaves_like 'User previews wiki changes' + it_behaves_like 'User updates wiki page' + it_behaves_like 'User uses wiki shortcuts' + it_behaves_like 'User views AsciiDoc page with includes' + it_behaves_like 'User views a wiki page' + it_behaves_like 'User views wiki pages' + it_behaves_like 'User views wiki sidebar' +end diff --git a/spec/frontend/fixtures/releases.rb b/spec/frontend/fixtures/releases.rb index a1df8893cd3..a3a43790f65 100644 --- a/spec/frontend/fixtures/releases.rb +++ b/spec/frontend/fixtures/releases.rb @@ -3,6 +3,7 @@ require 'spec_helper' RSpec.describe 'Releases (JavaScript fixtures)' do + include ApiHelpers include JavaScriptFixturesHelpers let_it_be(:admin) { create(:admin) } @@ -68,16 +69,14 @@ RSpec.describe 'Releases (JavaScript fixtures)' do link_type: :runbook) end - before(:all) do - clean_frontend_fixtures('api/releases/') - end - after(:all) do remove_repository(project) end - describe API::Releases, '(JavaScript fixtures)', type: :request do - include ApiHelpers + describe API::Releases, type: :request do + before(:all) do + clean_frontend_fixtures('api/releases/') + end it 'api/releases/release.json' do get api("/projects/#{project.id}/releases/#{release.tag}", admin) @@ -85,4 +84,22 @@ RSpec.describe 'Releases (JavaScript fixtures)' do expect(response).to be_successful end end + + graphql_query_path = 'releases/queries/all_releases.query.graphql' + + describe "~/#{graphql_query_path}", type: :request do + include GraphqlHelpers + + before(:all) do + clean_frontend_fixtures('graphql/releases/') + end + + it "graphql/#{graphql_query_path}.json" do + query = File.read(File.join(Rails.root, '/app/assets/javascripts', graphql_query_path)) + + post_graphql(query, current_user: admin, variables: { fullPath: project.full_path }) + + expect_graphql_errors_to_be_empty + end + end end diff --git a/spec/frontend/vue_shared/components/members/table/member_source_spec.js b/spec/frontend/vue_shared/components/members/table/member_source_spec.js new file mode 100644 index 00000000000..8b914d76674 --- /dev/null +++ b/spec/frontend/vue_shared/components/members/table/member_source_spec.js @@ -0,0 +1,71 @@ +import { mount, createWrapper } from '@vue/test-utils'; +import { getByText as getByTextHelper } from '@testing-library/dom'; +import { createMockDirective, getBinding } from 'helpers/vue_mock_directive'; +import MemberSource from '~/vue_shared/components/members/table/member_source.vue'; + +describe('MemberSource', () => { + let wrapper; + + const createComponent = propsData => { + wrapper = mount(MemberSource, { + propsData: { + memberSource: { + id: 102, + name: 'Foo bar', + webUrl: 'https://gitlab.com/groups/foo-bar', + }, + ...propsData, + }, + directives: { + GlTooltip: createMockDirective(), + }, + }); + }; + + const getByText = (text, options) => + createWrapper(getByTextHelper(wrapper.element, text, options)); + + const getTooltipDirective = elementWrapper => getBinding(elementWrapper.element, 'gl-tooltip'); + + afterEach(() => { + wrapper.destroy(); + }); + + describe('direct member', () => { + it('displays "Direct member"', () => { + createComponent({ + isDirectMember: true, + }); + + expect(getByText('Direct member').exists()).toBe(true); + }); + }); + + describe('inherited member', () => { + let sourceGroupLink; + + beforeEach(() => { + createComponent({ + isDirectMember: false, + }); + + sourceGroupLink = getByText('Foo bar'); + }); + + it('displays a link to source group', () => { + createComponent({ + isDirectMember: false, + }); + + expect(sourceGroupLink.exists()).toBe(true); + expect(sourceGroupLink.attributes('href')).toBe('https://gitlab.com/groups/foo-bar'); + }); + + it('displays tooltip with "Inherited"', () => { + const tooltipDirective = getTooltipDirective(sourceGroupLink); + + expect(tooltipDirective).not.toBeUndefined(); + expect(sourceGroupLink.attributes('title')).toBe('Inherited'); + }); + }); +}); diff --git a/spec/frontend/vue_shared/components/members/table/member_table_cell_spec.js b/spec/frontend/vue_shared/components/members/table/member_table_cell_spec.js index ecab22328fe..372e07d5e27 100644 --- a/spec/frontend/vue_shared/components/members/table/member_table_cell_spec.js +++ b/spec/frontend/vue_shared/components/members/table/member_table_cell_spec.js @@ -1,4 +1,5 @@ import { mount, createLocalVue } from '@vue/test-utils'; +import Vuex from 'vuex'; import { MEMBER_TYPES } from '~/vue_shared/components/members/constants'; import { member as memberMock, group, invite, accessRequest } from '../mock_data'; import MembersTableCell from '~/vue_shared/components/members/table/members_table_cell.vue'; @@ -10,6 +11,10 @@ describe('MemberList', () => { type: String, required: true, }, + isDirectMember: { + type: Boolean, + required: true, + }, }, render(createElement) { return createElement('div', this.memberType); @@ -17,20 +22,34 @@ describe('MemberList', () => { }; const localVue = createLocalVue(); + localVue.use(Vuex); localVue.component('wrapped-component', WrappedComponent); + const createStore = (state = {}) => { + return new Vuex.Store({ + state: { + sourceId: 1, + ...state, + }, + }); + }; + let wrapper; - const createComponent = propsData => { + const createComponent = (propsData, state = {}) => { wrapper = mount(MembersTableCell, { localVue, propsData, + store: createStore(state), scopedSlots: { - default: '<wrapped-component :member-type="props.memberType" />', + default: + '<wrapped-component :member-type="props.memberType" :is-direct-member="props.isDirectMember" />', }, }); }; + const findWrappedComponent = () => wrapper.find(WrappedComponent); + afterEach(() => { wrapper.destroy(); wrapper = null; @@ -47,7 +66,31 @@ describe('MemberList', () => { ({ member, expectedMemberType }) => { createComponent({ member }); - expect(wrapper.find(WrappedComponent).props('memberType')).toBe(expectedMemberType); + expect(findWrappedComponent().props('memberType')).toBe(expectedMemberType); }, ); + + describe('isDirectMember', () => { + it('returns `true` when member source has same ID as `sourceId`', () => { + createComponent({ + member: { + ...memberMock, + source: { + ...memberMock.source, + id: 1, + }, + }, + }); + + expect(findWrappedComponent().props('isDirectMember')).toBe(true); + }); + + it('returns `false` when member is inherited', () => { + createComponent({ + member: memberMock, + }); + + expect(findWrappedComponent().props('isDirectMember')).toBe(false); + }); + }); }); diff --git a/spec/frontend/vue_shared/components/members/table/members_table_spec.js b/spec/frontend/vue_shared/components/members/table/members_table_spec.js index b236d94fc8b..dbad203b4f6 100644 --- a/spec/frontend/vue_shared/components/members/table/members_table_spec.js +++ b/spec/frontend/vue_shared/components/members/table/members_table_spec.js @@ -5,7 +5,10 @@ import { getByTestId as getByTestIdHelper, } from '@testing-library/dom'; import MembersTable from '~/vue_shared/components/members/table/members_table.vue'; +import MemberAvatar from '~/vue_shared/components/members/table/member_avatar.vue'; +import MemberSource from '~/vue_shared/components/members/table/member_source.vue'; import * as initUserPopovers from '~/user_popovers'; +import { member as memberMock, invite, accessRequest } from '../mock_data'; const localVue = createLocalVue(); localVue.use(Vuex); @@ -44,20 +47,31 @@ describe('MemberList', () => { describe('fields', () => { it.each` - field | label - ${'source'} | ${'Source'} - ${'granted'} | ${'Access granted'} - ${'invited'} | ${'Invited'} - ${'requested'} | ${'Requested'} - ${'expires'} | ${'Access expires'} - ${'maxRole'} | ${'Max role'} - ${'expiration'} | ${'Expiration'} - `('renders the $label field', ({ field, label }) => { + field | label | member | expectedComponent + ${'account'} | ${'Account'} | ${memberMock} | ${MemberAvatar} + ${'source'} | ${'Source'} | ${memberMock} | ${MemberSource} + ${'granted'} | ${'Access granted'} | ${memberMock} | ${null} + ${'invited'} | ${'Invited'} | ${invite} | ${null} + ${'requested'} | ${'Requested'} | ${accessRequest} | ${null} + ${'expires'} | ${'Access expires'} | ${memberMock} | ${null} + ${'maxRole'} | ${'Max role'} | ${memberMock} | ${null} + ${'expiration'} | ${'Expiration'} | ${memberMock} | ${null} + `('renders the $label field', ({ field, label, member, expectedComponent }) => { createComponent({ + members: [member], tableFields: [field], }); expect(getByText(label, { selector: '[role="columnheader"]' }).exists()).toBe(true); + + if (expectedComponent) { + expect( + wrapper + .find(`[data-label="${label}"][role="cell"]`) + .find(expectedComponent) + .exists(), + ).toBe(true); + } }); it('renders "Actions" field for screen readers', () => { diff --git a/spec/helpers/issuables_helper_spec.rb b/spec/helpers/issuables_helper_spec.rb index 89a2a92ea57..821440db551 100644 --- a/spec/helpers/issuables_helper_spec.rb +++ b/spec/helpers/issuables_helper_spec.rb @@ -306,6 +306,38 @@ RSpec.describe IssuablesHelper do end end + describe '#reviewer_sidebar_data' do + let(:user) { create(:user) } + + subject { helper.reviewer_sidebar_data(user, merge_request: merge_request) } + + context 'without merge_request' do + let(:merge_request) { nil } + + it 'returns hash of reviewer data' do + is_expected.to eql({ + avatar_url: user.avatar_url, + name: user.name, + username: user.username + }) + end + end + + context 'with merge_request' do + let(:merge_request) { build(:merge_request) } + + where(can_merge: [true, false]) + + with_them do + before do + allow(merge_request).to receive(:can_be_merged_by?).and_return(can_merge) + end + + it { is_expected.to include({ can_merge: can_merge })} + end + end + end + describe '#issuable_squash_option?' do using RSpec::Parameterized::TableSyntax diff --git a/spec/lib/gitlab/usage_data_counters/editor_unique_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/editor_unique_counter_spec.rb index 2a674557b76..f2c1d8718d7 100644 --- a/spec/lib/gitlab/usage_data_counters/editor_unique_counter_spec.rb +++ b/spec/lib/gitlab/usage_data_counters/editor_unique_counter_spec.rb @@ -41,11 +41,11 @@ RSpec.describe Gitlab::UsageDataCounters::EditorUniqueCounter, :clean_gitlab_red context 'for web IDE edit actions' do it_behaves_like 'tracks and counts action' do def track_action(params) - described_class.track_web_ide_edit_action(params) + described_class.track_web_ide_edit_action(**params) end def count_unique(params) - described_class.count_web_ide_edit_actions(params) + described_class.count_web_ide_edit_actions(**params) end end end @@ -53,11 +53,11 @@ RSpec.describe Gitlab::UsageDataCounters::EditorUniqueCounter, :clean_gitlab_red context 'for SFE edit actions' do it_behaves_like 'tracks and counts action' do def track_action(params) - described_class.track_sfe_edit_action(params) + described_class.track_sfe_edit_action(**params) end def count_unique(params) - described_class.count_sfe_edit_actions(params) + described_class.count_sfe_edit_actions(**params) end end end @@ -65,11 +65,11 @@ RSpec.describe Gitlab::UsageDataCounters::EditorUniqueCounter, :clean_gitlab_red context 'for snippet editor edit actions' do it_behaves_like 'tracks and counts action' do def track_action(params) - described_class.track_snippet_editor_edit_action(params) + described_class.track_snippet_editor_edit_action(**params) end def count_unique(params) - described_class.count_snippet_editor_edit_actions(params) + described_class.count_snippet_editor_edit_actions(**params) end end end diff --git a/spec/lib/gitlab/usage_data_counters/track_unique_events_spec.rb b/spec/lib/gitlab/usage_data_counters/track_unique_events_spec.rb index 8f5f1347ce8..d1144dd0bc5 100644 --- a/spec/lib/gitlab/usage_data_counters/track_unique_events_spec.rb +++ b/spec/lib/gitlab/usage_data_counters/track_unique_events_spec.rb @@ -8,11 +8,11 @@ RSpec.describe Gitlab::UsageDataCounters::TrackUniqueEvents, :clean_gitlab_redis let(:time) { Time.zone.now } def track_event(params) - track_unique_events.track_event(params) + track_unique_events.track_event(**params) end def count_unique(params) - track_unique_events.count_unique_events(params) + track_unique_events.count_unique_events(**params) end context 'tracking an event' do diff --git a/spec/support/helpers/wiki_helpers.rb b/spec/support/helpers/wiki_helpers.rb index e59c6bde264..8873a90579d 100644 --- a/spec/support/helpers/wiki_helpers.rb +++ b/spec/support/helpers/wiki_helpers.rb @@ -13,16 +13,16 @@ module WikiHelpers find('.svg-content .js-lazy-loaded') if example.nil? || example.metadata.key?(:js) end - def upload_file_to_wiki(container, user, file_name) - opts = { + def upload_file_to_wiki(wiki, user, file_name) + params = { file_name: file_name, file_content: File.read(expand_fixture_path(file_name)) } ::Wikis::CreateAttachmentService.new( - container: container, + container: wiki.container, current_user: user, - params: opts - ).execute[:result][:file_path] + params: params + ).execute.dig(:result, :file_path) end end diff --git a/spec/support/shared_examples/controllers/wiki_actions_shared_examples.rb b/spec/support/shared_examples/controllers/wiki_actions_shared_examples.rb index 4ca400dd87b..1cf31c47df8 100644 --- a/spec/support/shared_examples/controllers/wiki_actions_shared_examples.rb +++ b/spec/support/shared_examples/controllers/wiki_actions_shared_examples.rb @@ -226,7 +226,7 @@ RSpec.shared_examples 'wiki controller actions' do where(:file_name) { ['dk.png', 'unsanitized.svg', 'git-cheat-sheet.pdf'] } with_them do - let(:id) { upload_file_to_wiki(container, user, file_name) } + let(:id) { upload_file_to_wiki(wiki, user, file_name) } it 'delivers the file with the correct headers' do subject diff --git a/spec/support/shared_examples/features/wiki_file_attachments_shared_examples.rb b/spec/support/shared_examples/features/wiki/file_attachments_shared_examples.rb index d30e8241da0..0ef1ccdfe57 100644 --- a/spec/support/shared_examples/features/wiki_file_attachments_shared_examples.rb +++ b/spec/support/shared_examples/features/wiki/file_attachments_shared_examples.rb @@ -1,14 +1,12 @@ # frozen_string_literal: true # Requires a context containing: -# project +# wiki RSpec.shared_examples 'wiki file attachments' do include DropzoneHelper context 'uploading attachments', :js do - let(:wiki) { project.wiki } - def attach_with_dropzone(wait = false) dropzone_file([Rails.root.join('spec', 'fixtures', 'dk.png')], 0, wait) end diff --git a/spec/support/shared_examples/features/wiki/user_creates_wiki_page_shared_examples.rb b/spec/support/shared_examples/features/wiki/user_creates_wiki_page_shared_examples.rb new file mode 100644 index 00000000000..44d82d2e753 --- /dev/null +++ b/spec/support/shared_examples/features/wiki/user_creates_wiki_page_shared_examples.rb @@ -0,0 +1,245 @@ +# frozen_string_literal: true + +# Requires a context containing: +# wiki +# user + +RSpec.shared_examples 'User creates wiki page' do + include WikiHelpers + + before do + sign_in(user) + end + + context "when wiki is empty" do + before do |example| + visit wiki_path(wiki) + + wait_for_svg_to_be_loaded(example) + + click_link "Create your first page" + end + + it "shows validation error message" do + page.within(".wiki-form") do + fill_in(:wiki_content, with: "") + + click_on("Create page") + end + + expect(page).to have_content("The form contains the following error:").and have_content("Content can't be blank") + + page.within(".wiki-form") do + fill_in(:wiki_content, with: "[link test](test)") + + click_on("Create page") + end + + expect(page).to have_content("Home").and have_content("link test") + + click_link("link test") + + expect(page).to have_content("Create New Page") + end + + it "shows non-escaped link in the pages list" do + 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(page).to have_link(href: wiki_page_path(wiki, 'one/two/three-test')) + end + + 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 + 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") + + page.within(".wiki-form") do + click_button("Create page") + end + + expect(current_path).to eq(wiki_page_path(wiki, "home")) + expect(page).to have_content("test GitLab API doc Rake tasks Wiki header") + .and have_content("Home") + .and have_content("Last edited by #{user.name}") + .and have_header_with_correct_id_and_link(1, "Wiki header", "wiki-header") + + click_link("test") + + expect(current_path).to eq(wiki_page_path(wiki, "test")) + + page.within(:css, ".nav-text") do + expect(page).to have_content("Create New Page") + end + + click_link("Home") + + expect(current_path).to eq(wiki_page_path(wiki, "home")) + + click_link("GitLab API") + + expect(current_path).to eq(wiki_page_path(wiki, "api")) + + page.within(:css, ".nav-text") do + expect(page).to have_content("Create") + end + + click_link("Home") + + expect(current_path).to eq(wiki_page_path(wiki, "home")) + + click_link("Rake tasks") + + expect(current_path).to eq(wiki_page_path(wiki, "raketasks")) + + page.within(:css, ".nav-text") do + expect(page).to have_content("Create") + end + end + + it "creates ASCII wiki with LaTeX blocks", :js do + stub_application_setting(plantuml_url: "http://localhost", plantuml_enabled: true) + + ascii_content = <<~MD + :stem: latexmath + + [stem] + ++++ + \\sqrt{4} = 2 + ++++ + + another part + + [latexmath] + ++++ + \\beta_x \\gamma + ++++ + + stem:[2+2] is 4 + MD + + find("#wiki_format option[value=asciidoc]").select_option + + fill_in(:wiki_content, with: 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 'creates a wiki page with Org markup', :aggregate_failures do + org_content = <<~ORG + * Heading + ** Subheading + [[home][Link to Home]] + ORG + + page.within('.wiki-form') do + find('#wiki_format option[value=org]').select_option + fill_in(:wiki_content, with: org_content) + click_button('Create page') + end + + expect(page).to have_selector('h1', text: 'Heading') + expect(page).to have_selector('h2', text: 'Subheading') + expect(page).to have_link(href: wiki_page_path(wiki, 'home')) + end + + it_behaves_like 'wiki file attachments' + end + + context "when wiki is not empty", :js do + before do + create(:wiki_page, wiki: wiki, title: 'home', content: 'Home page') + + visit wiki_path(wiki) + end + + context "via the `new wiki page` page" do + it "creates a page with a single word" 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 + + 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 + click_link("New page") + + page.within(".wiki-form") do + find("#wiki_content").native.send_keys("") + + fill_in(:wiki_content, with: ":") + end + + expect(page).to have_selector(".atwho-view") + end + end +end diff --git a/spec/support/shared_examples/features/wiki/user_deletes_wiki_page_shared_examples.rb b/spec/support/shared_examples/features/wiki/user_deletes_wiki_page_shared_examples.rb new file mode 100644 index 00000000000..e1fd9c8dbec --- /dev/null +++ b/spec/support/shared_examples/features/wiki/user_deletes_wiki_page_shared_examples.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +# Requires a context containing: +# wiki +# user + +RSpec.shared_examples 'User deletes wiki page' do + include WikiHelpers + + let(:wiki_page) { create(:wiki_page, wiki: wiki) } + + before do + sign_in(user) + visit wiki_page_path(wiki, wiki_page) + end + + it 'deletes a page', :js do + click_on('Edit') + click_on('Delete') + find('.modal-footer .btn-danger').click + + expect(page).to have_content('Page was successfully deleted') + end +end diff --git a/spec/support/shared_examples/features/wiki/user_previews_wiki_changes_shared_examples.rb b/spec/support/shared_examples/features/wiki/user_previews_wiki_changes_shared_examples.rb new file mode 100644 index 00000000000..cf6ae6cfa5b --- /dev/null +++ b/spec/support/shared_examples/features/wiki/user_previews_wiki_changes_shared_examples.rb @@ -0,0 +1,110 @@ +# frozen_string_literal: true + +# Requires a context containing: +# wiki +# user + +RSpec.shared_examples 'User previews wiki changes' do + let(:wiki_page) { build(:wiki_page, wiki: wiki) } + + before do + sign_in(user) + end + + shared_examples 'relative links' do + let_it_be(:page_content) do + <<~HEREDOC + Some text so key event for [ does not trigger an incorrect replacement. + [regular link](regular) + [relative link 1](../relative) + [relative link 2](./relative) + [relative link 3](./e/f/relative) + [spaced link](title with spaces) + HEREDOC + end + + def relative_path(path) + (Pathname.new(wiki.wiki_base_path) + File.dirname(wiki_page.path).tr(' ', '-') + path).to_s + end + + shared_examples "rewrites relative links" do + specify do + expect(element).to have_link('regular link', href: wiki.wiki_base_path + '/regular') + expect(element).to have_link('spaced link', href: wiki.wiki_base_path + '/title%20with%20spaces') + + expect(element).to have_link('relative link 1', href: relative_path('../relative')) + expect(element).to have_link('relative link 2', href: relative_path('./relative')) + expect(element).to have_link('relative link 3', href: relative_path('./e/f/relative')) + end + end + + context "when there are no spaces or hyphens in the page name" do + let(:wiki_page) { build(:wiki_page, wiki: wiki, title: 'a/b/c/d', content: page_content) } + + it_behaves_like 'rewrites relative links' + end + + context "when there are spaces in the page name" do + let(:wiki_page) { build(:wiki_page, wiki: wiki, title: 'a page/b page/c page/d page', content: page_content) } + + it_behaves_like 'rewrites relative links' + end + + context "when there are hyphens in the page name" do + let(:wiki_page) { build(:wiki_page, wiki: wiki, title: 'a-page/b-page/c-page/d-page', content: page_content) } + + it_behaves_like 'rewrites relative links' + end + end + + context "when rendering a new wiki page", :js do + before do + wiki_page.create # rubocop:disable Rails/SaveBang + visit wiki_page_path(wiki, wiki_page) + end + + it_behaves_like 'relative links' do + let(:element) { page.find('.js-wiki-page-content') } + end + end + + context "when previewing an existing wiki page", :js do + let(:preview) { page.find('.md-preview-holder') } + + before do + wiki_page.create # rubocop:disable Rails/SaveBang + visit wiki_page_path(wiki, wiki_page, action: :edit) + end + + it_behaves_like 'relative links' do + before do + click_on 'Preview' + end + + let(:element) { preview } + end + + it 'renders content with CommonMark' do + fill_in :wiki_content, with: "1. one\n - sublist\n" + click_on "Preview" + + # the above generates two separate lists (not embedded) in CommonMark + expect(preview).to have_content("sublist") + expect(preview).not_to have_xpath("//ol//li//ul") + end + + it "does not linkify double brackets inside code blocks as expected" do + fill_in :wiki_content, with: <<-HEREDOC + `[[do_not_linkify]]` + ``` + [[also_do_not_linkify]] + ``` + HEREDOC + click_on "Preview" + + expect(preview).to have_content("do_not_linkify") + expect(preview).to have_content('[[do_not_linkify]]') + expect(preview).to have_content('[[also_do_not_linkify]]') + end + end +end diff --git a/spec/support/shared_examples/features/wiki/user_updates_wiki_page_shared_examples.rb b/spec/support/shared_examples/features/wiki/user_updates_wiki_page_shared_examples.rb new file mode 100644 index 00000000000..fee455207f1 --- /dev/null +++ b/spec/support/shared_examples/features/wiki/user_updates_wiki_page_shared_examples.rb @@ -0,0 +1,231 @@ +# frozen_string_literal: true + +# Requires a context containing: +# wiki +# user + +RSpec.shared_examples 'User updates wiki page' do + include WikiHelpers + + before do + sign_in(user) + end + + context 'when wiki is empty' do + before do |example| + visit(wiki_path(wiki)) + + wait_for_svg_to_be_loaded(example) + + click_link "Create your first page" + end + + it 'redirects back to the home edit page' do + page.within(:css, '.wiki-form .form-actions') do + click_on('Cancel') + end + + expect(current_path).to eq wiki_path(wiki) + end + + it 'updates a page that has a path', :js do + 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') + + first(:link, text: 'three').click + + expect(find('.nav-text')).to have_content('three') + + click_on('Edit') + + expect(current_path).to include('one/two/three-test') + expect(page).to have_content('Edit Page') + + fill_in('Content', with: 'Updated Wiki Content') + click_on('Save changes') + + expect(page).to have_content('Updated Wiki Content') + end + + it_behaves_like 'wiki file attachments' + end + + context 'when wiki is not empty' do + let!(:wiki_page) { create(:wiki_page, wiki: wiki, title: 'home', content: 'Home page') } + + before do + visit(wiki_path(wiki)) + + click_link('Edit') + end + + it 'updates a page', :js do + # Commit message field should have correct value. + expect(page).to have_field('wiki[message]', with: 'Update home') + + fill_in(:wiki_content, with: 'My awesome wiki!') + click_button('Save changes') + + expect(page).to have_content('Home') + expect(page).to have_content("Last edited by #{user.name}") + expect(page).to have_content('My awesome wiki!') + end + + it 'updates the commit message as the title is changed', :js do + fill_in(:wiki_title, with: '& < > \ \ { } &') + + expect(page).to have_field('wiki[message]', with: 'Update & < > \ \ { } &') + end + + it 'correctly escapes the commit message entities', :js do + fill_in(:wiki_title, with: 'Wiki title') + + expect(page).to have_field('wiki[message]', with: 'Update Wiki title') + end + + it 'shows a validation error message' do + 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_content').value).to eq('') + end + + it 'shows the emoji autocompletion dropdown', :js do + find('#wiki_content').native.send_keys('') + fill_in(:wiki_content, with: ':') + + expect(page).to have_selector('.atwho-view') + end + + it 'shows the error message' do + wiki_page.update(content: 'Update') # rubocop:disable Rails/SaveBang + + click_button('Save changes') + + expect(page).to have_content('Someone edited the page the same time you did.') + end + + it 'updates a page' do + fill_in('Content', with: 'Updated Wiki Content') + click_on('Save changes') + + expect(page).to have_content('Updated Wiki Content') + end + + it 'cancels editing of a page' do + page.within(:css, '.wiki-form .form-actions') do + click_on('Cancel') + end + + expect(current_path).to eq(wiki_page_path(wiki, wiki_page)) + end + + it_behaves_like 'wiki file attachments' + end + + context 'when the page is in a subdir' do + let(:page_name) { 'page_name' } + let(:page_dir) { "foo/bar/#{page_name}" } + let!(:wiki_page) { create(:wiki_page, wiki: wiki, title: page_dir, content: 'Home page') } + + before do + visit wiki_page_path(wiki, wiki_page, action: :edit) + end + + it 'moves the page to the root folder' do + fill_in(:wiki_title, with: "/#{page_name}") + + click_button('Save changes') + + expect(current_path).to eq(wiki_page_path(wiki, page_name)) + end + + it 'moves the page to other dir' do + new_page_dir = "foo1/bar1/#{page_name}" + + fill_in(:wiki_title, with: new_page_dir) + + click_button('Save changes') + + expect(current_path).to eq(wiki_page_path(wiki, new_page_dir)) + end + + it 'remains in the same place if title has not changed' do + original_path = wiki_page_path(wiki, wiki_page) + + 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_dir = "foo1/bar1/new_page_name" + + fill_in(:wiki_title, with: new_page_dir) + + click_button('Save changes') + + expect(current_path).to eq(wiki_page_path(wiki, new_page_dir)) + end + + it 'can be renamed and moved to the root folder' do + new_name = 'new_page_name' + + fill_in(:wiki_title, with: "/#{new_name}") + + click_button('Save changes') + + expect(current_path).to eq(wiki_page_path(wiki, new_name)) + end + + it 'squishes the title before creating the page' do + new_page_dir = " foo1 / bar1 / #{page_name} " + + fill_in(:wiki_title, with: new_page_dir) + + click_button('Save changes') + + expect(current_path).to eq(wiki_page_path(wiki, "foo1/bar1/#{page_name}")) + end + + it_behaves_like 'wiki file attachments' + end + + context 'when an existing page exceeds the content size limit' do + let!(:wiki_page) { create(:wiki_page, wiki: wiki, content: "one\ntwo\nthree") } + + before do + stub_application_setting(wiki_page_max_content_bytes: 10) + + visit wiki_page_path(wiki_page.wiki, wiki_page, action: :edit) + end + + it 'allows changing the title if the content does not change' do + fill_in 'Title', with: 'new title' + click_on 'Save changes' + + expect(page).to have_content('Wiki was successfully updated.') + end + + it 'shows a validation error when trying to change the content' do + fill_in 'Content', with: 'new content' + click_on 'Save changes' + + expect(page).to have_content('The form contains the following error:') + expect(page).to have_content('Content is too long (11 Bytes). The maximum size is 10 Bytes.') + end + end +end diff --git a/spec/support/shared_examples/features/wiki/user_uses_wiki_shortcuts_shared_examples.rb b/spec/support/shared_examples/features/wiki/user_uses_wiki_shortcuts_shared_examples.rb new file mode 100644 index 00000000000..0330b345a18 --- /dev/null +++ b/spec/support/shared_examples/features/wiki/user_uses_wiki_shortcuts_shared_examples.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +# Requires a context containing: +# wiki +# user + +RSpec.shared_examples 'User uses wiki shortcuts' do + let(:wiki_page) { create(:wiki_page, wiki: wiki, title: 'home', content: 'Home page') } + + before do + sign_in(user) + visit wiki_page_path(wiki, wiki_page) + end + + it 'Visit edit wiki page using "e" keyboard shortcut', :js do + find('body').native.send_key('e') + + expect(find('.wiki-page-title')).to have_content('Edit Page') + end +end diff --git a/spec/features/projects/wiki/users_views_asciidoc_page_with_includes_spec.rb b/spec/support/shared_examples/features/wiki/user_views_asciidoc_page_with_includes_shared_examples.rb index 5c45e34595f..3b2fda4e05b 100644 --- a/spec/features/projects/wiki/users_views_asciidoc_page_with_includes_spec.rb +++ b/spec/support/shared_examples/features/wiki/user_views_asciidoc_page_with_includes_shared_examples.rb @@ -1,11 +1,7 @@ # frozen_string_literal: true -require 'spec_helper' - -RSpec.describe 'User views AsciiDoc page with includes', :js do - let_it_be(:user) { create(:user) } +RSpec.shared_examples 'User views AsciiDoc page with includes' do let_it_be(:wiki_content_selector) { '[data-qa-selector=wiki_page_content]' } - let(:project) { create(:project, :public, :wiki_repo) } let!(:included_wiki_page) { create_wiki_page('included_page', content: 'Content from the included page')} let!(:wiki_page) { create_wiki_page('home', content: "Content from the main page.\ninclude::included_page.asciidoc[]") } @@ -16,16 +12,16 @@ RSpec.describe 'User views AsciiDoc page with includes', :js do format: :asciidoc } - create(:wiki_page, wiki: project.wiki, **attrs) + create(:wiki_page, wiki: wiki, **attrs) end before do sign_in(user) end - context 'when the file being included exists' do + context 'when the file being included exists', :js do it 'includes the file contents' do - visit(project_wiki_path(project, wiki_page)) + visit(wiki_page_path(wiki, wiki_page)) page.within(:css, wiki_content_selector) do expect(page).to have_content('Content from the main page. Content from the included page') @@ -34,8 +30,10 @@ RSpec.describe 'User views AsciiDoc page with includes', :js do context 'when there are multiple versions of the wiki pages' do before do + # rubocop:disable Rails/SaveBang included_wiki_page.update(message: 'updated included file', content: 'Updated content from the included page') wiki_page.update(message: 'updated wiki page', content: "Updated content from the main page.\ninclude::included_page.asciidoc[]") + # rubocop:enable Rails/SaveBang end let(:latest_version_id) { wiki_page.versions.first.id } @@ -43,7 +41,7 @@ RSpec.describe 'User views AsciiDoc page with includes', :js do context 'viewing the latest version' do it 'includes the latest content' do - visit(project_wiki_path(project, wiki_page, version_id: latest_version_id)) + visit(wiki_page_path(wiki, wiki_page, version_id: latest_version_id)) page.within(:css, wiki_content_selector) do expect(page).to have_content('Updated content from the main page. Updated content from the included page') @@ -53,7 +51,7 @@ RSpec.describe 'User views AsciiDoc page with includes', :js do context 'viewing the original version' do it 'includes the content from the original version' do - visit(project_wiki_path(project, wiki_page, version_id: oldest_version_id)) + visit(wiki_page_path(wiki, wiki_page, version_id: oldest_version_id)) page.within(:css, wiki_content_selector) do expect(page).to have_content('Content from the main page. Content from the included page') @@ -63,13 +61,13 @@ RSpec.describe 'User views AsciiDoc page with includes', :js do end end - context 'when the file being included does not exist' do + context 'when the file being included does not exist', :js do before do included_wiki_page.delete end it 'outputs an error' do - visit(project_wiki_path(project, wiki_page)) + visit(wiki_page_path(wiki, wiki_page)) page.within(:css, wiki_content_selector) do expect(page).to have_content('Content from the main page. [ERROR: include::included_page.asciidoc[] - unresolved directive]') diff --git a/spec/support/shared_examples/features/wiki/user_views_wiki_empty_shared_examples.rb b/spec/support/shared_examples/features/wiki/user_views_wiki_empty_shared_examples.rb new file mode 100644 index 00000000000..d7f5b485a82 --- /dev/null +++ b/spec/support/shared_examples/features/wiki/user_views_wiki_empty_shared_examples.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +# Requires a context containing: +# wiki + +RSpec.shared_examples 'User views empty wiki' do + let(:element) { page.find('.row.empty-state') } + let(:container_name) { wiki.container.class.name.humanize(capitalize: false) } + let(:confluence_link) { 'Enable the Confluence Wiki integration' } + + shared_examples 'wiki is not found' do + it 'shows an error message' do + visit wiki_path(wiki) + + if @current_user + expect(page).to have_content('Page Not Found') + else + expect(page).to have_content('You need to sign in') + end + end + end + + shared_examples 'empty wiki message' do |writable: false, issuable: false, confluence: false| + # This mirrors the logic in: + # - app/views/shared/empty_states/_wikis.html.haml + # - WikiHelper#wiki_empty_state_messages + it 'shows the empty state message with the expected elements' do + visit wiki_path(wiki) + + if writable + expect(element).to have_content("The wiki lets you write documentation for your #{container_name}") + else + expect(element).to have_content("This #{container_name} has no wiki pages") + expect(element).to have_content("You must be a #{container_name} member") + end + + if issuable && !writable + expect(element).to have_content("improve the wiki for this #{container_name}") + expect(element).to have_link("issue tracker", href: project_issues_path(project)) + expect(element).to have_link("Suggest wiki improvement", href: new_project_issue_path(project)) + else + expect(element).not_to have_content("improve the wiki for this #{container_name}") + expect(element).not_to have_link("issue tracker") + expect(element).not_to have_link("Suggest wiki improvement") + end + + if confluence + expect(element).to have_link(confluence_link) + else + expect(element).not_to have_link(confluence_link) + end + + if writable + element.click_link 'Create your first page' + + expect(page).to have_button('Create page') + else + expect(element).not_to have_link('Create your first page') + end + end + end +end diff --git a/spec/features/projects/wiki/user_views_wiki_page_spec.rb b/spec/support/shared_examples/features/wiki/user_views_wiki_page_shared_examples.rb index e93689af0aa..40998ebde4c 100644 --- a/spec/features/projects/wiki/user_views_wiki_page_spec.rb +++ b/spec/support/shared_examples/features/wiki/user_views_wiki_page_shared_examples.rb @@ -1,14 +1,13 @@ # frozen_string_literal: true -require 'spec_helper' +# Requires a context containing: +# wiki +# user -RSpec.describe 'User views a wiki page' do +RSpec.shared_examples 'User views a wiki page' do include WikiHelpers - let(:user) { create(:user) } - let(:project) { create(:project, :wiki_repo, namespace: user.namespace) } let(:path) { 'image.png' } - let(:wiki) { project.wiki } let(:wiki_page) do create(:wiki_page, wiki: wiki, @@ -16,13 +15,12 @@ RSpec.describe 'User views a wiki page' do end before do - project.add_maintainer(user) sign_in(user) end context 'when wiki is empty', :js do before do - visit project_wikis_path(project) + visit wiki_path(wiki) wait_for_svg_to_be_loaded @@ -83,7 +81,7 @@ RSpec.describe 'User views a wiki page' do context 'when a page does not have history' do before do - visit(project_wiki_path(project, wiki_page)) + visit(wiki_page_path(wiki, wiki_page)) end it 'shows all the pages' do @@ -92,7 +90,7 @@ RSpec.describe 'User views a wiki page' do end context 'shows a file stored in a page' do - let(:path) { upload_file_to_wiki(project, user, 'dk.png') } + let(:path) { upload_file_to_wiki(wiki, user, 'dk.png') } it do expect(page).to have_xpath("//img[@data-src='#{wiki.wiki_base_path}/#{path}']") @@ -121,7 +119,7 @@ RSpec.describe 'User views a wiki page' do end it 'shows the page history' do - visit(project_wiki_path(project, wiki_page)) + visit(wiki_page_path(wiki, wiki_page)) expect(page).to have_selector('a.btn', text: 'Edit') @@ -133,12 +131,16 @@ RSpec.describe 'User views a wiki page' do end it 'does not show the "Edit" button' do - visit(project_wiki_path(project, wiki_page, version_id: wiki_page.versions.last.id)) + visit(wiki_page_path(wiki, wiki_page, version_id: wiki_page.versions.last.id)) expect(page).not_to have_selector('a.btn', text: 'Edit') end context 'show the diff' do + before do + skip('Diffing for group wikis will be implemented in https://gitlab.com/gitlab-org/gitlab/-/merge_requests/42610') if wiki.container.is_a?(Group) + end + def expect_diff_links(commit) diff_path = wiki_page_path(wiki, wiki_page, version_id: commit, action: :diff) @@ -150,7 +152,7 @@ RSpec.describe 'User views a wiki page' do end it 'links to the correct diffs' do - visit project_wiki_history_path(project, wiki_page) + visit wiki_page_path(wiki, wiki_page, action: :history) commit1 = wiki.commit('HEAD^') commit2 = wiki.commit @@ -208,7 +210,7 @@ RSpec.describe 'User views a wiki page' do end it 'preserves the special characters' do - visit(project_wiki_path(project, wiki_page)) + visit(wiki_page_path(wiki, wiki_page)) expect(page).to have_css('.wiki-page-title', text: title) expect(page).to have_css('.wiki-pages li', text: title) @@ -223,7 +225,7 @@ RSpec.describe 'User views a wiki page' do end it 'safely displays the page' do - visit(project_wiki_path(project, wiki_page)) + visit(wiki_page_path(wiki, wiki_page)) expect(page).to have_css('.wiki-page-title', text: title) expect(page).to have_content('foo bar') @@ -236,7 +238,7 @@ RSpec.describe 'User views a wiki page' do end it 'safely displays the message' do - visit(project_wiki_history_path(project, wiki_page)) + visit(wiki_page_path(wiki, wiki_page, action: :history)) expect(page).to have_content('<script>alert(true)<script>') end @@ -248,7 +250,7 @@ RSpec.describe 'User views a wiki page' do before do allow(Gitlab::EncodingHelper).to receive(:encode!).and_return(content) - visit(project_wiki_path(project, wiki_page)) + visit(wiki_page_path(wiki, wiki_page)) end it 'does not show "Edit" button' do @@ -263,7 +265,7 @@ RSpec.describe 'User views a wiki page' do end it 'opens a default wiki page', :js do - visit project_path(project) + visit wiki.container.web_url find('.shortcuts-wiki').click diff --git a/spec/features/projects/wiki/user_views_wiki_pages_spec.rb b/spec/support/shared_examples/features/wiki/user_views_wiki_pages_shared_examples.rb index 4f29ae0cc8a..314c2074eee 100644 --- a/spec/features/projects/wiki/user_views_wiki_pages_spec.rb +++ b/spec/support/shared_examples/features/wiki/user_views_wiki_pages_shared_examples.rb @@ -1,23 +1,22 @@ # frozen_string_literal: true -require 'spec_helper' +# Requires a context containing: +# wiki +# user -RSpec.describe 'User views wiki pages' do +RSpec.shared_examples 'User views wiki pages' do include WikiHelpers - let(:user) { create(:user) } - let(:project) { create(:project, :wiki_repo, namespace: user.namespace) } - let!(:wiki_page1) do - create(:wiki_page, wiki: project.wiki, title: '3 home', content: '3') + create(:wiki_page, wiki: wiki, title: '3 home', content: '3') end let!(:wiki_page2) do - create(:wiki_page, wiki: project.wiki, title: '1 home', content: '1') + create(:wiki_page, wiki: wiki, title: '1 home', content: '1') end let!(:wiki_page3) do - create(:wiki_page, wiki: project.wiki, title: '2 home', content: '2') + create(:wiki_page, wiki: wiki, title: '2 home', content: '2') end let(:pages) do @@ -25,9 +24,8 @@ RSpec.describe 'User views wiki pages' do end before do - project.add_maintainer(user) sign_in(user) - visit(project_wikis_pages_path(project)) + visit(wiki_path(wiki, action: :pages)) end context 'ordered by title' do diff --git a/spec/support/shared_examples/features/wiki/user_views_wiki_sidebar_shared_examples.rb b/spec/support/shared_examples/features/wiki/user_views_wiki_sidebar_shared_examples.rb new file mode 100644 index 00000000000..a7ba7a8ad07 --- /dev/null +++ b/spec/support/shared_examples/features/wiki/user_views_wiki_sidebar_shared_examples.rb @@ -0,0 +1,68 @@ +# frozen_string_literal: true + +# Requires a context containing: +# wiki +# user + +RSpec.shared_examples 'User views wiki sidebar' do + include WikiHelpers + + before do + sign_in(user) + end + + context 'when there are some existing pages' do + before do + create(:wiki_page, wiki: wiki, title: 'home', content: 'home') + create(:wiki_page, wiki: wiki, title: 'another', content: 'another') + end + + it 'renders a default sidebar when there is no customized sidebar' do + visit wiki_path(wiki) + + expect(page).to have_content('another') + expect(page).not_to have_link('View All Pages') + end + + context 'when there is a customized sidebar' do + before do + create(:wiki_page, wiki: wiki, title: '_sidebar', content: 'My customized sidebar') + end + + it 'renders my customized sidebar instead of the default one' do + visit wiki_path(wiki) + + expect(page).to have_content('My customized sidebar') + expect(page).not_to have_content('Another') + end + end + end + + context 'when there are 15 existing pages' do + before do + (1..5).each { |i| create(:wiki_page, wiki: wiki, title: "my page #{i}") } + (6..10).each { |i| create(:wiki_page, wiki: wiki, title: "parent/my page #{i}") } + (11..15).each { |i| create(:wiki_page, wiki: wiki, title: "grandparent/parent/my page #{i}") } + end + + it 'shows all pages in the sidebar' do + visit wiki_path(wiki) + + (1..15).each { |i| expect(page).to have_content("my page #{i}") } + expect(page).not_to have_link('View All Pages') + end + + context 'when there are more than 15 existing pages' do + before do + create(:wiki_page, wiki: wiki, title: 'my page 16') + end + + it 'shows the first 15 pages in the sidebar' do + visit wiki_path(wiki) + + expect(page).to have_text('my page', count: 15) + expect(page).to have_link('View All Pages') + end + end + end +end |