Skip to content
Snippets Groups Projects
Commit 8f210aeb authored by GitLab Bot's avatar GitLab Bot
Browse files

Add latest changes from gitlab-org/gitlab@master

parent 996f7009
No related branches found
No related tags found
No related merge requests found
Showing
with 318 additions and 702 deletions
Loading
Loading
@@ -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' })
Loading
Loading
@@ -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
Loading
Loading
@@ -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();
Loading
Loading
@@ -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';
Loading
Loading
Loading
Loading
@@ -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}"
Loading
Loading
@@ -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')
Loading
Loading
Loading
Loading
@@ -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]
 
Loading
Loading
@@ -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
Loading
Loading
@@ -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
 
Loading
Loading
@@ -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
Loading
Loading
Loading
Loading
@@ -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
Loading
Loading
@@ -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" }
Loading
Loading
@@ -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
Loading
Loading
@@ -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
Loading
Loading
@@ -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)
Loading
Loading
Loading
Loading
@@ -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
Loading
Loading
Loading
Loading
@@ -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)
Loading
Loading
@@ -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
Loading
Loading
@@ -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)
Loading
Loading
Loading
Loading
@@ -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
Loading
Loading
@@ -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
Loading
Loading
Loading
Loading
@@ -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? }
 
Loading
Loading
Loading
Loading
@@ -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
 
Loading
Loading
@@ -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
 
Loading
Loading
# 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)] }
Loading
Loading
@@ -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
Loading
Loading
@@ -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'
Loading
Loading
@@ -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
 
Loading
Loading
@@ -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
Loading
Loading
@@ -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
 
Loading
Loading
Loading
Loading
@@ -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,
Loading
Loading
@@ -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
 
Loading
Loading
# 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
# 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
Loading
Loading
@@ -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
Loading
Loading
@@ -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();
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment