1112 lines
32 KiB
Ruby
1112 lines
32 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require 'spec_helper'
|
|
|
|
RSpec.describe 'File blob', :js do
|
|
include MobileHelpers
|
|
|
|
let(:project) { create(:project, :public, :repository) }
|
|
|
|
def visit_blob(path, anchor: nil, ref: 'master', **additional_args)
|
|
visit project_blob_path(project, File.join(ref, path), anchor: anchor, **additional_args)
|
|
|
|
wait_for_requests
|
|
end
|
|
|
|
def create_file(file_name, content)
|
|
project.add_maintainer(project.creator)
|
|
|
|
Files::CreateService.new(
|
|
project,
|
|
project.creator,
|
|
start_branch: 'master',
|
|
branch_name: 'master',
|
|
commit_message: "Add #{file_name}",
|
|
file_path: file_name,
|
|
file_content: <<-SPEC.strip_heredoc
|
|
#{content}
|
|
SPEC
|
|
).execute
|
|
end
|
|
|
|
context 'Ruby file' do
|
|
before do
|
|
visit_blob('files/ruby/popen.rb')
|
|
|
|
wait_for_requests
|
|
end
|
|
|
|
it 'displays the blob' do
|
|
aggregate_failures do
|
|
# shows highlighted Ruby code
|
|
expect(page).to have_css(".js-syntax-highlight")
|
|
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
|
|
|
|
it 'displays file actions on all screen sizes' do
|
|
file_actions_selector = '.file-actions'
|
|
|
|
resize_screen_sm
|
|
expect(page).to have_selector(file_actions_selector, visible: true)
|
|
|
|
resize_screen_xs
|
|
expect(page).to have_selector(file_actions_selector, visible: true)
|
|
end
|
|
end
|
|
|
|
context 'Markdown file' do
|
|
context 'visiting directly' do
|
|
before do
|
|
visit_blob('files/markdown/ruby-style-guide.md')
|
|
|
|
wait_for_requests
|
|
end
|
|
|
|
it 'displays the blob using the rich viewer' do
|
|
aggregate_failures do
|
|
# hides the simple viewer
|
|
expect(page).not_to have_selector('.blob-viewer[data-type="simple"]')
|
|
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_requests
|
|
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).not_to have_selector('.blob-viewer[data-type="rich"]')
|
|
|
|
# shows highlighted Markdown code
|
|
expect(page).to have_css(".js-syntax-highlight")
|
|
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_requests
|
|
end
|
|
|
|
it 'displays the blob using the rich viewer' do
|
|
aggregate_failures do
|
|
# hides the simple viewer
|
|
expect(page).not_to have_selector('.blob-viewer[data-type="simple"]')
|
|
expect(page).to have_selector('.blob-viewer[data-type="rich"]')
|
|
|
|
# shows a disabled copy button
|
|
expect(page).to have_selector('.js-copy-blob-source-btn.disabled')
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'when ref switch' do
|
|
def switch_ref_to(ref_name)
|
|
first('[data-testid="branches-select"]').click
|
|
|
|
page.within '.project-refs-form' do
|
|
click_link ref_name
|
|
wait_for_requests
|
|
end
|
|
end
|
|
|
|
it 'displays no highlighted number of different ref' do
|
|
Files::UpdateService.new(
|
|
project,
|
|
project.first_owner,
|
|
commit_message: 'Update',
|
|
start_branch: 'feature',
|
|
branch_name: 'feature',
|
|
file_path: 'files/js/application.js',
|
|
file_content: 'new content'
|
|
).execute
|
|
|
|
project.commit('feature').diffs.diff_files.first
|
|
|
|
visit_blob('files/js/application.js', anchor: 'L3')
|
|
switch_ref_to('feature')
|
|
|
|
page.within '.blob-content' do
|
|
expect(page).not_to have_css('.hll')
|
|
end
|
|
end
|
|
|
|
context 'successfully change ref of similar name' do
|
|
before do
|
|
project.repository.create_branch('dev')
|
|
project.repository.create_branch('development')
|
|
end
|
|
|
|
it 'switch ref from longer to shorter ref name' do
|
|
visit_blob('files/js/application.js', ref: 'development')
|
|
switch_ref_to('dev')
|
|
|
|
aggregate_failures do
|
|
expect(page.find('.file-title-name').text).to eq('application.js')
|
|
expect(page).not_to have_css('flash-container')
|
|
end
|
|
end
|
|
|
|
it 'switch ref from shorter to longer ref name' do
|
|
visit_blob('files/js/application.js', ref: 'dev')
|
|
switch_ref_to('development')
|
|
|
|
aggregate_failures do
|
|
expect(page.find('.file-title-name').text).to eq('application.js')
|
|
expect(page).not_to have_css('flash-container')
|
|
end
|
|
end
|
|
end
|
|
|
|
it 'successfully changes ref when the ref name matches the project name' do
|
|
project.repository.create_branch(project.name)
|
|
|
|
visit_blob('files/js/application.js', ref: project.name)
|
|
switch_ref_to('master')
|
|
|
|
aggregate_failures do
|
|
expect(page.find('.file-title-name').text).to eq('application.js')
|
|
expect(page).not_to have_css('flash-container')
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'Markdown rendering' do
|
|
before do
|
|
project.add_maintainer(project.creator)
|
|
|
|
Files::CreateService.new(
|
|
project,
|
|
project.creator,
|
|
start_branch: 'master',
|
|
branch_name: 'master',
|
|
commit_message: "Add RedCarpet and CommonMark Markdown ",
|
|
file_path: 'files/commonmark/file.md',
|
|
file_content: "1. one\n - sublist\n"
|
|
).execute
|
|
end
|
|
|
|
context 'when rendering default markdown' do
|
|
before do
|
|
visit_blob('files/commonmark/file.md')
|
|
|
|
wait_for_requests
|
|
end
|
|
|
|
it 'renders using CommonMark' do
|
|
aggregate_failures do
|
|
expect(page).to have_content("sublist")
|
|
expect(page).not_to have_xpath("//ol//li//ul")
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'Markdown file (stored in LFS)' do
|
|
before do
|
|
project.add_maintainer(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')
|
|
|
|
wait_for_requests
|
|
end
|
|
|
|
it 'displays an error' do
|
|
aggregate_failures do
|
|
# hides the simple viewer
|
|
expect(page).not_to have_selector('.blob-viewer[data-type="simple"]')
|
|
expect(page).not_to have_selector('.blob-viewer[data-type="rich"]')
|
|
|
|
# shows an error message
|
|
expect(page).to have_content('This content could not be displayed because it is stored in LFS. You can download it instead.')
|
|
|
|
# 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/file.md')
|
|
|
|
wait_for_requests
|
|
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_maintainer(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')
|
|
|
|
wait_for_requests
|
|
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 'Jupiter Notebook file' do
|
|
before do
|
|
project.add_maintainer(project.creator)
|
|
|
|
Files::CreateService.new(
|
|
project,
|
|
project.creator,
|
|
start_branch: 'master',
|
|
branch_name: 'master',
|
|
commit_message: "Add Jupiter Notebook",
|
|
file_path: 'files/basic.ipynb',
|
|
file_content: project.repository.blob_at('add-ipython-files', 'files/ipython/basic.ipynb').data
|
|
).execute
|
|
|
|
visit_blob('files/basic.ipynb')
|
|
|
|
wait_for_requests
|
|
end
|
|
|
|
it 'displays the blob' do
|
|
aggregate_failures do
|
|
# shows rendered notebook
|
|
expect(page).to have_selector('.js-notebook-viewer-mounted')
|
|
|
|
# does show a viewer switcher
|
|
expect(page).to have_selector('.js-blob-viewer-switcher')
|
|
|
|
# show 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')
|
|
|
|
# shows a download button
|
|
expect(page).to have_link('Download')
|
|
|
|
# shows the rendered notebook
|
|
expect(page).to have_content('test')
|
|
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')
|
|
|
|
wait_for_requests
|
|
end
|
|
|
|
it 'displays the blob' do
|
|
aggregate_failures do
|
|
# shows a download link
|
|
expect(page).to have_link('Download (1.50 MiB)')
|
|
|
|
# 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')
|
|
|
|
wait_for_requests
|
|
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')
|
|
|
|
wait_for_requests
|
|
end
|
|
|
|
it 'displays the blob' do
|
|
aggregate_failures do
|
|
# shows a download link
|
|
expect(page).to have_link('Download (2.11 KiB)')
|
|
|
|
# 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 'binary file that appears to be text in the first 1024 bytes' do
|
|
before do
|
|
visit_blob('encoding/binary-1.bin', ref: 'binary-encoding')
|
|
end
|
|
|
|
it 'displays the blob' do
|
|
expect(page).to have_link('Download (23.81 KiB)')
|
|
# does not show a viewer switcher
|
|
expect(page).not_to have_selector('.js-blob-viewer-switcher')
|
|
expect(page).not_to have_selector('.js-copy-blob-source-btn:not(.disabled)')
|
|
expect(page).not_to have_link('Open raw')
|
|
end
|
|
end
|
|
|
|
context 'empty file' do
|
|
before do
|
|
project.add_maintainer(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')
|
|
|
|
wait_for_requests
|
|
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 'files with auxiliary viewers' do
|
|
describe '.gitlab-ci.yml' do
|
|
before do
|
|
project.add_maintainer(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
|
|
|
|
describe '.gitlab/route-map.yml' do
|
|
before do
|
|
project.add_maintainer(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
|
|
|
|
describe '.gitlab/dashboards/custom-dashboard.yml' do
|
|
before do
|
|
project.add_maintainer(project.creator)
|
|
|
|
Files::CreateService.new(
|
|
project,
|
|
project.creator,
|
|
start_branch: 'master',
|
|
branch_name: 'master',
|
|
commit_message: "Add .gitlab/dashboards/custom-dashboard.yml",
|
|
file_path: '.gitlab/dashboards/custom-dashboard.yml',
|
|
file_content: file_content
|
|
).execute
|
|
end
|
|
|
|
context 'with metrics_dashboard_exhaustive_validations feature flag off' do
|
|
before do
|
|
stub_feature_flags(metrics_dashboard_exhaustive_validations: false)
|
|
visit_blob('.gitlab/dashboards/custom-dashboard.yml')
|
|
end
|
|
|
|
context 'valid dashboard file' do
|
|
let(:file_content) { File.read(Rails.root.join('config/prometheus/common_metrics.yml')) }
|
|
|
|
it 'displays an auxiliary viewer' do
|
|
aggregate_failures do
|
|
# shows that dashboard yaml is valid
|
|
expect(page).to have_content('Metrics Dashboard YAML definition is valid.')
|
|
|
|
# shows a learn more link
|
|
expect(page).to have_link('Learn more')
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'invalid dashboard file' do
|
|
let(:file_content) { "dashboard: 'invalid'" }
|
|
|
|
it 'displays an auxiliary viewer' do
|
|
aggregate_failures do
|
|
# shows that dashboard yaml is invalid
|
|
expect(page).to have_content('Metrics Dashboard YAML definition is invalid:')
|
|
expect(page).to have_content("panel_groups: should be an array of panel_groups objects")
|
|
|
|
# shows a learn more link
|
|
expect(page).to have_link('Learn more')
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'with metrics_dashboard_exhaustive_validations feature flag on' do
|
|
before do
|
|
stub_feature_flags(metrics_dashboard_exhaustive_validations: true)
|
|
visit_blob('.gitlab/dashboards/custom-dashboard.yml')
|
|
end
|
|
|
|
context 'valid dashboard file' do
|
|
let(:file_content) { File.read(Rails.root.join('config/prometheus/common_metrics.yml')) }
|
|
|
|
it 'displays an auxiliary viewer' do
|
|
aggregate_failures do
|
|
# shows that dashboard yaml is valid
|
|
expect(page).to have_content('Metrics Dashboard YAML definition is valid.')
|
|
|
|
# shows a learn more link
|
|
expect(page).to have_link('Learn more')
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'invalid dashboard file' do
|
|
let(:file_content) { "dashboard: 'invalid'" }
|
|
|
|
it 'displays an auxiliary viewer' do
|
|
aggregate_failures do
|
|
# shows that dashboard yaml is invalid
|
|
expect(page).to have_content('Metrics Dashboard YAML definition is invalid:')
|
|
expect(page).to have_content("root is missing required keys: panel_groups")
|
|
|
|
# shows a learn more link
|
|
expect(page).to have_link('Learn more')
|
|
end
|
|
end
|
|
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', href: 'http://choosealicense.com/licenses/mit/')
|
|
end
|
|
end
|
|
end
|
|
|
|
context '*.gemspec' do
|
|
before do
|
|
project.add_maintainer(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.')
|
|
|
|
# shows a learn more link
|
|
expect(page).to have_link('Learn more', href: 'https://rubygems.org/')
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'CONTRIBUTING.md' do
|
|
before do
|
|
file_name = 'CONTRIBUTING.md'
|
|
|
|
create_file(file_name, '## Contribution guidelines')
|
|
visit_blob(file_name)
|
|
end
|
|
|
|
it 'displays an auxiliary viewer' do
|
|
aggregate_failures do
|
|
expect(page).to have_content("After you've reviewed these contribution guidelines, you'll be all set to contribute to this project.")
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'CHANGELOG.md' do
|
|
before do
|
|
file_name = 'CHANGELOG.md'
|
|
|
|
create_file(file_name, '## Changelog for v1.0.0')
|
|
visit_blob(file_name)
|
|
end
|
|
|
|
it 'displays an auxiliary viewer' do
|
|
aggregate_failures do
|
|
expect(page).to have_content("To find the state of this project's repository at the time of any of these versions, check out the tags.")
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'Cargo.toml' do
|
|
before do
|
|
file_name = 'Cargo.toml'
|
|
|
|
create_file(file_name, '
|
|
[package]
|
|
name = "hello_world" # the name of the package
|
|
version = "0.1.0" # the current version, obeying semver
|
|
authors = ["Alice <a@example.com>", "Bob <b@example.com>"]
|
|
')
|
|
visit_blob(file_name)
|
|
end
|
|
|
|
it 'displays an auxiliary viewer' do
|
|
aggregate_failures do
|
|
expect(page).to have_content("This project manages its dependencies using Cargo.")
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'Cartfile' do
|
|
before do
|
|
file_name = 'Cartfile'
|
|
|
|
create_file(file_name, '
|
|
gitlab "Alamofire/Alamofire" == 4.9.0
|
|
gitlab "Alamofire/AlamofireImage" ~> 3.4
|
|
')
|
|
visit_blob(file_name)
|
|
end
|
|
|
|
it 'displays an auxiliary viewer' do
|
|
aggregate_failures do
|
|
expect(page).to have_content("This project manages its dependencies using Carthage.")
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'composer.json' do
|
|
before do
|
|
file_name = 'composer.json'
|
|
|
|
create_file(file_name, '
|
|
{
|
|
"license": "MIT"
|
|
}
|
|
')
|
|
visit_blob(file_name)
|
|
end
|
|
|
|
it 'displays an auxiliary viewer' do
|
|
aggregate_failures do
|
|
expect(page).to have_content("This project manages its dependencies using Composer.")
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'Gemfile' do
|
|
before do
|
|
file_name = 'Gemfile'
|
|
|
|
create_file(file_name, '
|
|
source "https://rubygems.org"
|
|
|
|
# Gems here
|
|
')
|
|
visit_blob(file_name)
|
|
end
|
|
|
|
it 'displays an auxiliary viewer' do
|
|
aggregate_failures do
|
|
expect(page).to have_content("This project manages its dependencies using Bundler.")
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'Godeps.json' do
|
|
before do
|
|
file_name = 'Godeps.json'
|
|
|
|
create_file(file_name, '
|
|
{
|
|
"GoVersion": "go1.6"
|
|
}
|
|
')
|
|
visit_blob(file_name)
|
|
end
|
|
|
|
it 'displays an auxiliary viewer' do
|
|
aggregate_failures do
|
|
expect(page).to have_content("This project manages its dependencies using godep.")
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'go.mod' do
|
|
before do
|
|
file_name = 'go.mod'
|
|
|
|
create_file(file_name, '
|
|
module example.com/mymodule
|
|
|
|
go 1.14
|
|
')
|
|
visit_blob(file_name)
|
|
end
|
|
|
|
it 'displays an auxiliary viewer' do
|
|
aggregate_failures do
|
|
expect(page).to have_content("This project manages its dependencies using Go Modules.")
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'package.json' do
|
|
before do
|
|
file_name = 'package.json'
|
|
|
|
create_file(file_name, '
|
|
{
|
|
"name": "my-awesome-package",
|
|
"version": "1.0.0"
|
|
}
|
|
')
|
|
visit_blob(file_name)
|
|
end
|
|
|
|
it 'displays an auxiliary viewer' do
|
|
aggregate_failures do
|
|
expect(page).to have_content("This project manages its dependencies using npm.")
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'podfile' do
|
|
before do
|
|
file_name = 'podfile'
|
|
|
|
create_file(file_name, 'platform :ios, "8.0"')
|
|
visit_blob(file_name)
|
|
end
|
|
|
|
it 'displays an auxiliary viewer' do
|
|
aggregate_failures do
|
|
expect(page).to have_content("This project manages its dependencies using CocoaPods.")
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'test.podspec' do
|
|
before do
|
|
file_name = 'test.podspec'
|
|
|
|
create_file(file_name, '
|
|
Pod::Spec.new do |s|
|
|
s.name = "TensorFlowLiteC"
|
|
')
|
|
visit_blob(file_name)
|
|
end
|
|
|
|
it 'displays an auxiliary viewer' do
|
|
aggregate_failures do
|
|
expect(page).to have_content("This project manages its dependencies using CocoaPods.")
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'JSON.podspec.json' do
|
|
before do
|
|
file_name = 'JSON.podspec.json'
|
|
|
|
create_file(file_name, '
|
|
{
|
|
"name": "JSON"
|
|
}
|
|
')
|
|
visit_blob(file_name)
|
|
end
|
|
|
|
it 'displays an auxiliary viewer' do
|
|
aggregate_failures do
|
|
expect(page).to have_content("This project manages its dependencies using CocoaPods.")
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'requirements.txt' do
|
|
before do
|
|
file_name = 'requirements.txt'
|
|
|
|
create_file(file_name, 'Project requirements')
|
|
visit_blob(file_name)
|
|
end
|
|
|
|
it 'displays an auxiliary viewer' do
|
|
aggregate_failures do
|
|
expect(page).to have_content("This project manages its dependencies using pip.")
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'yarn.lock' do
|
|
before do
|
|
file_name = 'yarn.lock'
|
|
|
|
create_file(file_name, '
|
|
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
|
# yarn lockfile v1
|
|
')
|
|
visit_blob(file_name)
|
|
end
|
|
|
|
it 'displays an auxiliary viewer' do
|
|
aggregate_failures do
|
|
expect(page).to have_content("This project manages its dependencies using Yarn.")
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'openapi.yml' do
|
|
before do
|
|
file_name = 'openapi.yml'
|
|
|
|
create_file(file_name, '
|
|
swagger: \'2.0\'
|
|
info:
|
|
title: Classic API Resource Documentation
|
|
description: |
|
|
<div class="foo-bar" style="background-color: red;" data-foo-bar="baz">
|
|
<h1>Swagger API documentation</h1>
|
|
</div>
|
|
version: production
|
|
basePath: /JSSResource/
|
|
produces:
|
|
- application/xml
|
|
- application/json
|
|
consumes:
|
|
- application/xml
|
|
- application/json
|
|
security:
|
|
- basicAuth: []
|
|
paths:
|
|
/accounts:
|
|
get:
|
|
responses:
|
|
\'200\':
|
|
description: No response was specified
|
|
tags:
|
|
- accounts
|
|
operationId: findAccounts
|
|
summary: Finds all accounts
|
|
')
|
|
visit_blob(file_name, useUnsafeMarkdown: '1')
|
|
click_button('Display rendered file')
|
|
|
|
wait_for_requests
|
|
end
|
|
|
|
it 'removes `style`, `class`, and `data-*`` attributes from HTML' do
|
|
expect(page).to have_css('h1', text: 'Swagger API documentation')
|
|
expect(page).not_to have_css('.foo-bar')
|
|
expect(page).not_to have_css('[style="background-color: red;"]')
|
|
expect(page).not_to have_css('[data-foo-bar="baz"]')
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'realtime pipelines' do
|
|
before do
|
|
Files::CreateService.new(
|
|
project,
|
|
project.creator,
|
|
start_branch: 'feature',
|
|
branch_name: 'feature',
|
|
commit_message: "Add ruby file",
|
|
file_path: 'files/ruby/test.rb',
|
|
file_content: "# Awesome content"
|
|
).execute
|
|
|
|
create(:ci_pipeline, status: 'running', project: project, ref: 'feature', sha: project.commit('feature').sha)
|
|
visit_blob('files/ruby/test.rb', ref: 'feature')
|
|
end
|
|
|
|
it 'shows the realtime pipeline status' do
|
|
page.within('.commit-actions') do
|
|
expect(page).to have_css('.ci-status-icon')
|
|
expect(page).to have_css('.ci-status-icon-running')
|
|
expect(page).to have_css('.js-ci-status-icon-running')
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'for subgroups' do
|
|
let(:group) { create(:group) }
|
|
let(:subgroup) { create(:group, parent: group) }
|
|
let(:project) { create(:project, :public, :repository, group: subgroup) }
|
|
|
|
it 'renders tree table without errors' do
|
|
visit_blob('README.md')
|
|
|
|
expect(page).to have_selector('.file-content')
|
|
expect(page).not_to have_selector('[data-testid="alert-danger"]')
|
|
end
|
|
|
|
it 'displays a GPG badge' do
|
|
visit_blob('CONTRIBUTING.md', ref: '33f3729a45c02fc67d00adb1b8bca394b0e761d9')
|
|
|
|
expect(page).not_to have_selector '.gpg-status-box.js-loading-gpg-badge'
|
|
expect(page).to have_selector '.gpg-status-box.invalid'
|
|
end
|
|
end
|
|
|
|
context 'on signed merge commit' do
|
|
it 'displays a GPG badge' do
|
|
visit_blob('conflicting-file.md', ref: '6101e87e575de14b38b4e1ce180519a813671e10')
|
|
|
|
expect(page).not_to have_selector '.gpg-status-box.js-loading-gpg-badge'
|
|
expect(page).to have_selector '.gpg-status-box.invalid'
|
|
end
|
|
end
|
|
|
|
context 'when static objects external storage is enabled' do
|
|
before do
|
|
stub_application_setting(static_objects_external_storage_url: 'https://cdn.gitlab.com')
|
|
end
|
|
|
|
context 'private project' do
|
|
let_it_be(:project) { create(:project, :repository, :private) }
|
|
let_it_be(:user) { create(:user, static_object_token: 'ABCD1234') }
|
|
|
|
before do
|
|
project.add_developer(user)
|
|
|
|
sign_in(user)
|
|
visit_blob('README.md')
|
|
end
|
|
|
|
it 'shows open raw and download buttons with external storage URL prepended and user token appended to their href' do
|
|
path = project_raw_path(project, 'master/README.md')
|
|
raw_uri = "https://cdn.gitlab.com#{path}?token=#{user.static_object_token}"
|
|
download_uri = "https://cdn.gitlab.com#{path}?token=#{user.static_object_token}&inline=false"
|
|
|
|
aggregate_failures do
|
|
expect(page).to have_link 'Open raw', href: raw_uri
|
|
expect(page).to have_link 'Download', href: download_uri
|
|
end
|
|
end
|
|
end
|
|
|
|
context 'public project' do
|
|
before do
|
|
visit_blob('README.md')
|
|
end
|
|
|
|
it 'shows open raw and download buttons with external storage URL prepended to their href' do
|
|
path = project_raw_path(project, 'master/README.md')
|
|
raw_uri = "https://cdn.gitlab.com#{path}"
|
|
download_uri = "https://cdn.gitlab.com#{path}?inline=false"
|
|
|
|
aggregate_failures do
|
|
expect(page).to have_link 'Open raw', href: raw_uri
|
|
expect(page).to have_link 'Download', href: download_uri
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|