summaryrefslogtreecommitdiff
path: root/spec/features/projects/blobs
diff options
context:
space:
mode:
Diffstat (limited to 'spec/features/projects/blobs')
-rw-r--r--spec/features/projects/blobs/blob_show_spec.rb466
-rw-r--r--spec/features/projects/blobs/edit_spec.rb146
-rw-r--r--spec/features/projects/blobs/user_create_spec.rb9
3 files changed, 588 insertions, 33 deletions
diff --git a/spec/features/projects/blobs/blob_show_spec.rb b/spec/features/projects/blobs/blob_show_spec.rb
new file mode 100644
index 00000000000..fc242082278
--- /dev/null
+++ b/spec/features/projects/blobs/blob_show_spec.rb
@@ -0,0 +1,466 @@
+require 'spec_helper'
+
+feature 'File blob', :js, feature: true do
+ let(:project) { create(:project, :public) }
+
+ def visit_blob(path, fragment = nil)
+ visit namespace_project_blob_path(project.namespace, project, File.join('master', path), anchor: fragment)
+
+ wait_for_ajax
+ end
+
+ context 'Ruby file' do
+ before do
+ visit_blob('files/ruby/popen.rb')
+ end
+
+ it 'displays the blob' do
+ aggregate_failures do
+ # shows highlighted Ruby code
+ expect(page).to have_content("require 'fileutils'")
+
+ # does not show a viewer switcher
+ expect(page).not_to have_selector('.js-blob-viewer-switcher')
+
+ # shows an enabled copy button
+ expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)')
+
+ # shows a raw button
+ expect(page).to have_link('Open raw')
+ end
+ end
+ end
+
+ context 'Markdown file' do
+ context 'visiting directly' do
+ before do
+ visit_blob('files/markdown/ruby-style-guide.md')
+ end
+
+ it 'displays the blob using the rich viewer' do
+ aggregate_failures do
+ # hides the simple viewer
+ expect(page).to have_selector('.blob-viewer[data-type="simple"]', visible: false)
+ expect(page).to have_selector('.blob-viewer[data-type="rich"]')
+
+ # shows rendered Markdown
+ expect(page).to have_link("PEP-8")
+
+ # shows a viewer switcher
+ expect(page).to have_selector('.js-blob-viewer-switcher')
+
+ # shows a disabled copy button
+ expect(page).to have_selector('.js-copy-blob-source-btn.disabled')
+
+ # shows a raw button
+ expect(page).to have_link('Open raw')
+ end
+ end
+
+ context 'switching to the simple viewer' do
+ before do
+ find('.js-blob-viewer-switch-btn[data-viewer=simple]').click
+
+ wait_for_ajax
+ end
+
+ it 'displays the blob using the simple viewer' do
+ aggregate_failures do
+ # hides the rich viewer
+ expect(page).to have_selector('.blob-viewer[data-type="simple"]')
+ expect(page).to have_selector('.blob-viewer[data-type="rich"]', visible: false)
+
+ # shows highlighted Markdown code
+ expect(page).to have_content("[PEP-8](http://www.python.org/dev/peps/pep-0008/)")
+
+ # shows an enabled copy button
+ expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)')
+ end
+ end
+
+ context 'switching to the rich viewer again' do
+ before do
+ find('.js-blob-viewer-switch-btn[data-viewer=rich]').click
+
+ wait_for_ajax
+ end
+
+ it 'displays the blob using the rich viewer' do
+ aggregate_failures do
+ # hides the simple viewer
+ expect(page).to have_selector('.blob-viewer[data-type="simple"]', visible: false)
+ expect(page).to have_selector('.blob-viewer[data-type="rich"]')
+
+ # shows an enabled copy button
+ expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)')
+ end
+ end
+ end
+ end
+ end
+
+ context 'visiting with a line number anchor' do
+ before do
+ visit_blob('files/markdown/ruby-style-guide.md', 'L1')
+ end
+
+ it 'displays the blob using the simple viewer' do
+ aggregate_failures do
+ # hides the rich viewer
+ expect(page).to have_selector('.blob-viewer[data-type="simple"]')
+ expect(page).to have_selector('.blob-viewer[data-type="rich"]', visible: false)
+
+ # highlights the line in question
+ expect(page).to have_selector('#LC1.hll')
+
+ # shows highlighted Markdown code
+ expect(page).to have_content("[PEP-8](http://www.python.org/dev/peps/pep-0008/)")
+
+ # shows an enabled copy button
+ expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)')
+ end
+ end
+ end
+ end
+
+ context 'Markdown file (stored in LFS)' do
+ before do
+ project.add_master(project.creator)
+
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add Markdown in LFS",
+ file_path: 'files/lfs/file.md',
+ file_content: project.repository.blob_at('master', 'files/lfs/lfs_object.iso').data
+ ).execute
+ end
+
+ context 'when LFS is enabled on the project' do
+ before do
+ allow(Gitlab.config.lfs).to receive(:enabled).and_return(true)
+ project.update_attribute(:lfs_enabled, true)
+
+ visit_blob('files/lfs/file.md')
+ end
+
+ it 'displays an error' do
+ aggregate_failures do
+ # hides the simple viewer
+ expect(page).to have_selector('.blob-viewer[data-type="simple"]', visible: false)
+ expect(page).to have_selector('.blob-viewer[data-type="rich"]')
+
+ # shows an error message
+ expect(page).to have_content('The rendered file could not be displayed because it is stored in LFS. You can download it instead.')
+
+ # shows a viewer switcher
+ expect(page).to have_selector('.js-blob-viewer-switcher')
+
+ # does not show a copy button
+ expect(page).not_to have_selector('.js-copy-blob-source-btn')
+
+ # shows a download button
+ expect(page).to have_link('Download')
+ end
+ end
+
+ context 'switching to the simple viewer' do
+ before do
+ find('.js-blob-viewer-switcher .js-blob-viewer-switch-btn[data-viewer=simple]').click
+
+ wait_for_ajax
+ end
+
+ it 'displays an error' do
+ aggregate_failures do
+ # hides the rich viewer
+ expect(page).to have_selector('.blob-viewer[data-type="simple"]')
+ expect(page).to have_selector('.blob-viewer[data-type="rich"]', visible: false)
+
+ # shows an error message
+ expect(page).to have_content('The source could not be displayed because it is stored in LFS. You can download it instead.')
+
+ # does not show a copy button
+ expect(page).not_to have_selector('.js-copy-blob-source-btn')
+ end
+ end
+ end
+ end
+
+ context 'when LFS is disabled on the project' do
+ before do
+ visit_blob('files/lfs/file.md')
+ end
+
+ it 'displays the blob' do
+ aggregate_failures do
+ # shows text
+ expect(page).to have_content('size 1575078')
+
+ # does not show a viewer switcher
+ expect(page).not_to have_selector('.js-blob-viewer-switcher')
+
+ # shows an enabled copy button
+ expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)')
+
+ # shows a raw button
+ expect(page).to have_link('Open raw')
+ end
+ end
+ end
+ end
+
+ context 'PDF file' do
+ before do
+ project.add_master(project.creator)
+
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add PDF",
+ file_path: 'files/test.pdf',
+ file_content: project.repository.blob_at('add-pdf-file', 'files/pdf/test.pdf').data
+ ).execute
+
+ visit_blob('files/test.pdf')
+ end
+
+ it 'displays the blob' do
+ aggregate_failures do
+ # shows rendered PDF
+ expect(page).to have_selector('.js-pdf-viewer')
+
+ # does not show a viewer switcher
+ expect(page).not_to have_selector('.js-blob-viewer-switcher')
+
+ # does not show a copy button
+ expect(page).not_to have_selector('.js-copy-blob-source-btn')
+
+ # shows a download button
+ expect(page).to have_link('Download')
+ end
+ end
+ end
+
+ context 'ISO file (stored in LFS)' do
+ context 'when LFS is enabled on the project' do
+ before do
+ allow(Gitlab.config.lfs).to receive(:enabled).and_return(true)
+ project.update_attribute(:lfs_enabled, true)
+
+ visit_blob('files/lfs/lfs_object.iso')
+ end
+
+ it 'displays the blob' do
+ aggregate_failures do
+ # shows a download link
+ expect(page).to have_link('Download (1.5 MB)')
+
+ # does not show a viewer switcher
+ expect(page).not_to have_selector('.js-blob-viewer-switcher')
+
+ # does not show a copy button
+ expect(page).not_to have_selector('.js-copy-blob-source-btn')
+
+ # shows a download button
+ expect(page).to have_link('Download')
+ end
+ end
+ end
+
+ context 'when LFS is disabled on the project' do
+ before do
+ visit_blob('files/lfs/lfs_object.iso')
+ end
+
+ it 'displays the blob' do
+ aggregate_failures do
+ # shows text
+ expect(page).to have_content('size 1575078')
+
+ # does not show a viewer switcher
+ expect(page).not_to have_selector('.js-blob-viewer-switcher')
+
+ # shows an enabled copy button
+ expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)')
+
+ # shows a raw button
+ expect(page).to have_link('Open raw')
+ end
+ end
+ end
+ end
+
+ context 'ZIP file' do
+ before do
+ visit_blob('Gemfile.zip')
+ end
+
+ it 'displays the blob' do
+ aggregate_failures do
+ # shows a download link
+ expect(page).to have_link('Download (2.11 KB)')
+
+ # does not show a viewer switcher
+ expect(page).not_to have_selector('.js-blob-viewer-switcher')
+
+ # does not show a copy button
+ expect(page).not_to have_selector('.js-copy-blob-source-btn')
+
+ # shows a download button
+ expect(page).to have_link('Download')
+ end
+ end
+ end
+
+ context 'empty file' do
+ before do
+ project.add_master(project.creator)
+
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add empty file",
+ file_path: 'files/empty.md',
+ file_content: ''
+ ).execute
+
+ visit_blob('files/empty.md')
+ end
+
+ it 'displays an error' do
+ aggregate_failures do
+ # shows an error message
+ expect(page).to have_content('Empty file')
+
+ # does not show a viewer switcher
+ expect(page).not_to have_selector('.js-blob-viewer-switcher')
+
+ # does not show a copy button
+ expect(page).not_to have_selector('.js-copy-blob-source-btn')
+
+ # does not show a download or raw button
+ expect(page).not_to have_link('Download')
+ expect(page).not_to have_link('Open raw')
+ end
+ end
+ end
+
+ context '.gitlab-ci.yml' do
+ before do
+ project.add_master(project.creator)
+
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add .gitlab-ci.yml",
+ file_path: '.gitlab-ci.yml',
+ file_content: File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml'))
+ ).execute
+
+ visit_blob('.gitlab-ci.yml')
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ # shows that configuration is valid
+ expect(page).to have_content('This GitLab CI configuration is valid.')
+
+ # shows a learn more link
+ expect(page).to have_link('Learn more')
+ end
+ end
+ end
+
+ context '.gitlab/route-map.yml' do
+ before do
+ project.add_master(project.creator)
+
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add .gitlab/route-map.yml",
+ file_path: '.gitlab/route-map.yml',
+ file_content: <<-MAP.strip_heredoc
+ # Team data
+ - source: 'data/team.yml'
+ public: 'team/'
+ MAP
+ ).execute
+
+ visit_blob('.gitlab/route-map.yml')
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ # shows that map is valid
+ expect(page).to have_content('This Route Map is valid.')
+
+ # shows a learn more link
+ expect(page).to have_link('Learn more')
+ end
+ end
+ end
+
+ context 'LICENSE' do
+ before do
+ visit_blob('LICENSE')
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ # shows license
+ expect(page).to have_content('This project is licensed under the MIT License.')
+
+ # shows a learn more link
+ expect(page).to have_link('Learn more', 'http://choosealicense.com/licenses/mit/')
+ end
+ end
+ end
+
+ context '*.gemspec' do
+ before do
+ project.add_master(project.creator)
+
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add activerecord.gemspec",
+ file_path: 'activerecord.gemspec',
+ file_content: <<-SPEC.strip_heredoc
+ Gem::Specification.new do |s|
+ s.platform = Gem::Platform::RUBY
+ s.name = "activerecord"
+ end
+ SPEC
+ ).execute
+
+ visit_blob('activerecord.gemspec')
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ # shows names of dependency manager and package
+ expect(page).to have_content('This project manages its dependencies using RubyGems and defines a gem named activerecord.')
+
+ # shows a link to the gem
+ expect(page).to have_link('activerecord', 'https://rubygems.org/gems/activerecord')
+
+ # shows a learn more link
+ expect(page).to have_link('Learn more', 'http://choosealicense.com/licenses/mit/')
+ end
+ end
+ end
+end
diff --git a/spec/features/projects/blobs/edit_spec.rb b/spec/features/projects/blobs/edit_spec.rb
index a820d07ab3b..cc5b1a7e734 100644
--- a/spec/features/projects/blobs/edit_spec.rb
+++ b/spec/features/projects/blobs/edit_spec.rb
@@ -1,45 +1,135 @@
require 'spec_helper'
feature 'Editing file blob', feature: true, js: true do
- include WaitForAjax
+ include TreeHelper
- given(:user) { create(:user) }
- given(:role) { :developer }
- given(:merge_request) { create(:merge_request, source_branch: 'feature', target_branch: 'master') }
- given(:project) { merge_request.target_project }
+ let(:project) { create(:project, :public, :test_repo) }
+ let(:merge_request) { create(:merge_request, source_project: project, source_branch: 'feature', target_branch: 'master') }
+ let(:branch) { 'master' }
+ let(:file_path) { project.repository.ls_files(project.repository.root_ref)[1] }
- background do
- login_as(user)
- project.team << [user, role]
- end
-
- def edit_and_commit
- wait_for_ajax
- first('.file-actions').click_link 'Edit'
- execute_script('ace.edit("editor").setValue("class NextFeature\nend\n")')
- click_button 'Commit Changes'
- end
+ context 'as a developer' do
+ let(:user) { create(:user) }
+ let(:role) { :developer }
- context 'from MR diff' do
before do
- visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request)
- edit_and_commit
+ project.team << [user, role]
+ login_as(user)
+ end
+
+ def edit_and_commit
+ wait_for_ajax
+ find('.js-edit-blob').click
+ execute_script('ace.edit("editor").setValue("class NextFeature\nend\n")')
+ click_button 'Commit changes'
+ end
+
+ context 'from MR diff' do
+ before do
+ visit diffs_namespace_project_merge_request_path(project.namespace, project, merge_request)
+ edit_and_commit
+ end
+
+ it 'returns me to the mr' do
+ expect(page).to have_content(merge_request.title)
+ end
end
- scenario 'returns me to the mr' do
- expect(page).to have_content(merge_request.title)
+ context 'from blob file path' do
+ before do
+ visit namespace_project_blob_path(project.namespace, project, tree_join(branch, file_path))
+ edit_and_commit
+ end
+
+ it 'updates content' do
+ expect(page).to have_content 'successfully committed'
+ expect(page).to have_content 'NextFeature'
+ end
end
end
- context 'from blob file path' do
- before do
- visit namespace_project_blob_path(project.namespace, project, '/feature/files/ruby/feature.rb')
- edit_and_commit
+ context 'visit blob edit' do
+ context 'redirects to sign in and returns' do
+ context 'as developer' do
+ let(:user) { create(:user) }
+
+ before do
+ project.team << [user, :developer]
+ visit namespace_project_edit_blob_path(project.namespace, project, tree_join(branch, file_path))
+ end
+
+ it 'redirects to sign in and returns' do
+ expect(page).to have_current_path(new_user_session_path)
+
+ login_as(user)
+
+ expect(page).to have_current_path(namespace_project_edit_blob_path(project.namespace, project, tree_join(branch, file_path)))
+ end
+ end
+
+ context 'as guest' do
+ let(:user) { create(:user) }
+
+ before do
+ visit namespace_project_edit_blob_path(project.namespace, project, tree_join(branch, file_path))
+ end
+
+ it 'redirects to sign in and returns' do
+ expect(page).to have_current_path(new_user_session_path)
+
+ login_as(user)
+
+ expect(page).to have_current_path(namespace_project_blob_path(project.namespace, project, tree_join(branch, file_path)))
+ end
+ end
+ end
+
+ context 'as developer' do
+ let(:user) { create(:user) }
+ let(:protected_branch) { 'protected-branch' }
+
+ before do
+ project.team << [user, :developer]
+ project.repository.add_branch(user, protected_branch, 'master')
+ create(:protected_branch, project: project, name: protected_branch)
+ login_as(user)
+ end
+
+ context 'on some branch' do
+ before do
+ visit namespace_project_edit_blob_path(project.namespace, project, tree_join(branch, file_path))
+ end
+
+ it 'shows blob editor with same branch' do
+ expect(page).to have_current_path(namespace_project_edit_blob_path(project.namespace, project, tree_join(branch, file_path)))
+ expect(find('.js-target-branch .dropdown-toggle-text').text).to eq(branch)
+ end
+ end
+
+ context 'with protected branch' do
+ before do
+ visit namespace_project_edit_blob_path(project.namespace, project, tree_join(protected_branch, file_path))
+ end
+
+ it 'shows blob editor with patch branch' do
+ expect(find('.js-target-branch .dropdown-toggle-text').text).to eq('patch-1')
+ end
+ end
end
- scenario 'updates content' do
- expect(page).to have_content 'successfully committed'
- expect(page).to have_content 'NextFeature'
+ context 'as master' do
+ let(:user) { create(:user) }
+
+ before do
+ project.team << [user, :master]
+ login_as(user)
+ visit namespace_project_edit_blob_path(project.namespace, project, tree_join(branch, file_path))
+ end
+
+ it 'shows blob editor with same branch' do
+ expect(page).to have_current_path(namespace_project_edit_blob_path(project.namespace, project, tree_join(branch, file_path)))
+ expect(find('.js-target-branch .dropdown-toggle-text').text).to eq(branch)
+ end
end
end
end
diff --git a/spec/features/projects/blobs/user_create_spec.rb b/spec/features/projects/blobs/user_create_spec.rb
index 5686868a0c4..d805450e095 100644
--- a/spec/features/projects/blobs/user_create_spec.rb
+++ b/spec/features/projects/blobs/user_create_spec.rb
@@ -1,7 +1,6 @@
require 'spec_helper'
feature 'New blob creation', feature: true, js: true do
- include WaitForAjax
include TargetBranchHelpers
given(:user) { create(:user) }
@@ -22,7 +21,7 @@ feature 'New blob creation', feature: true, js: true do
end
def commit_file
- click_button 'Commit Changes'
+ click_button 'Commit changes'
end
context 'with default target branch' do
@@ -77,7 +76,7 @@ feature 'New blob creation', feature: true, js: true do
project,
user,
start_branch: 'master',
- target_branch: 'master',
+ branch_name: 'master',
commit_message: 'Create file',
file_path: 'feature.rb',
file_content: content
@@ -87,8 +86,8 @@ feature 'New blob creation', feature: true, js: true do
end
scenario 'shows error message' do
- expect(page).to have_content('Your changes could not be committed because a file with the same name already exists')
- expect(page).to have_content('New File')
+ expect(page).to have_content('A file with this name already exists')
+ expect(page).to have_content('New file')
expect(page).to have_content('NextFeature')
end
end