Merge branch 'master' of github.com:gitlabhq/gitlabhq
This commit is contained in:
parent
da912c8f4c
commit
41b8a238ce
25 changed files with 473 additions and 9 deletions
|
@ -106,6 +106,7 @@ v 8.3.0
|
||||||
- Fix online editor should not remove newlines at the end of the file
|
- Fix online editor should not remove newlines at the end of the file
|
||||||
- Expose Git's version in the admin area
|
- Expose Git's version in the admin area
|
||||||
- Show "New Merge Request" buttons on canonical repos when you have a fork (Josh Frye)
|
- Show "New Merge Request" buttons on canonical repos when you have a fork (Josh Frye)
|
||||||
|
- Add file finder feature in tree view
|
||||||
|
|
||||||
v 8.2.3
|
v 8.2.3
|
||||||
- Fix application settings cache not expiring after changes (Stan Hu)
|
- Fix application settings cache not expiring after changes (Stan Hu)
|
||||||
|
|
2
Gemfile
2
Gemfile
|
@ -49,7 +49,7 @@ gem "browser", '~> 1.0.0'
|
||||||
|
|
||||||
# Extracting information from a git repository
|
# Extracting information from a git repository
|
||||||
# Provide access to Gitlab::Git library
|
# Provide access to Gitlab::Git library
|
||||||
gem "gitlab_git", '~> 7.2.20'
|
gem "gitlab_git", '~> 7.2.22'
|
||||||
|
|
||||||
# LDAP Auth
|
# LDAP Auth
|
||||||
# GitLab fork with several improvements to original library. For full list of changes
|
# GitLab fork with several improvements to original library. For full list of changes
|
||||||
|
|
|
@ -887,7 +887,7 @@ DEPENDENCIES
|
||||||
github-markup (~> 1.3.1)
|
github-markup (~> 1.3.1)
|
||||||
gitlab-flowdock-git-hook (~> 1.0.1)
|
gitlab-flowdock-git-hook (~> 1.0.1)
|
||||||
gitlab_emoji (~> 0.2.0)
|
gitlab_emoji (~> 0.2.0)
|
||||||
gitlab_git (~> 7.2.20)
|
gitlab_git (~> 7.2.22)
|
||||||
gitlab_meta (= 7.0)
|
gitlab_meta (= 7.0)
|
||||||
gitlab_omniauth-ldap (~> 1.2.1)
|
gitlab_omniauth-ldap (~> 1.2.1)
|
||||||
gollum-lib (~> 4.1.0)
|
gollum-lib (~> 4.1.0)
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#= require shortcuts_network
|
#= require shortcuts_network
|
||||||
#= require jquery.nicescroll.min
|
#= require jquery.nicescroll.min
|
||||||
#= require_tree .
|
#= require_tree .
|
||||||
|
#= require fuzzaldrin-plus.min
|
||||||
|
|
||||||
window.slugify = (text) ->
|
window.slugify = (text) ->
|
||||||
text.replace(/[^-a-zA-Z0-9]+/g, '_').toLowerCase()
|
text.replace(/[^-a-zA-Z0-9]+/g, '_').toLowerCase()
|
||||||
|
|
|
@ -87,7 +87,9 @@ class Dispatcher
|
||||||
new GroupAvatar()
|
new GroupAvatar()
|
||||||
when 'projects:tree:show'
|
when 'projects:tree:show'
|
||||||
new TreeView()
|
new TreeView()
|
||||||
shortcut_handler = new ShortcutsNavigation()
|
shortcut_handler = new ShortcutsTree()
|
||||||
|
when 'projects:find_file:show'
|
||||||
|
shortcut_handler = true
|
||||||
when 'projects:blob:show'
|
when 'projects:blob:show'
|
||||||
new LineHighlighter()
|
new LineHighlighter()
|
||||||
shortcut_handler = new ShortcutsNavigation()
|
shortcut_handler = new ShortcutsNavigation()
|
||||||
|
|
125
app/assets/javascripts/project_find_file.js.coffee
Normal file
125
app/assets/javascripts/project_find_file.js.coffee
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
class @ProjectFindFile
|
||||||
|
constructor: (@element, @options)->
|
||||||
|
@filePaths = {}
|
||||||
|
@inputElement = @element.find(".file-finder-input")
|
||||||
|
|
||||||
|
# init event
|
||||||
|
@initEvent()
|
||||||
|
|
||||||
|
# focus text input box
|
||||||
|
@inputElement.focus()
|
||||||
|
|
||||||
|
# load file list
|
||||||
|
@load(@options.url)
|
||||||
|
|
||||||
|
# init event
|
||||||
|
initEvent: ->
|
||||||
|
@inputElement.off "keyup"
|
||||||
|
@inputElement.on "keyup", (event) =>
|
||||||
|
target = $(event.target)
|
||||||
|
value = target.val()
|
||||||
|
oldValue = target.data("oldValue") ? ""
|
||||||
|
|
||||||
|
if value != oldValue
|
||||||
|
target.data("oldValue", value)
|
||||||
|
@findFile()
|
||||||
|
@element.find("tr.tree-item").eq(0).addClass("selected").focus()
|
||||||
|
|
||||||
|
@element.find(".tree-content-holder .tree-table").on "click", (event) ->
|
||||||
|
if (event.target.nodeName != "A")
|
||||||
|
path = @element.find(".tree-item-file-name a", this).attr("href")
|
||||||
|
location.href = path if path
|
||||||
|
|
||||||
|
# find file
|
||||||
|
findFile: ->
|
||||||
|
searchText = @inputElement.val()
|
||||||
|
result = if searchText.length > 0 then fuzzaldrinPlus.filter(@filePaths, searchText) else @filePaths
|
||||||
|
@renderList result, searchText
|
||||||
|
|
||||||
|
# files pathes load
|
||||||
|
load: (url) ->
|
||||||
|
$.ajax
|
||||||
|
url: url
|
||||||
|
method: "get"
|
||||||
|
dataType: "json"
|
||||||
|
success: (data) =>
|
||||||
|
@element.find(".loading").hide()
|
||||||
|
@filePaths = data
|
||||||
|
@findFile()
|
||||||
|
@element.find(".files-slider tr.tree-item").eq(0).addClass("selected").focus()
|
||||||
|
|
||||||
|
# render result
|
||||||
|
renderList: (filePaths, searchText) ->
|
||||||
|
@element.find(".tree-table > tbody").empty()
|
||||||
|
|
||||||
|
for filePath, i in filePaths
|
||||||
|
break if i == 20
|
||||||
|
|
||||||
|
if searchText
|
||||||
|
matches = fuzzaldrinPlus.match(filePath, searchText)
|
||||||
|
|
||||||
|
blobItemUrl = "#{@options.blobUrlTemplate}/#{filePath}"
|
||||||
|
|
||||||
|
html = @makeHtml filePath, matches, blobItemUrl
|
||||||
|
@element.find(".tree-table > tbody").append(html)
|
||||||
|
|
||||||
|
# highlight text(awefwbwgtc -> <b>a</b>wefw<b>b</b>wgt<b>c</b> )
|
||||||
|
highlighter = (element, text, matches) ->
|
||||||
|
lastIndex = 0
|
||||||
|
highlightText = ""
|
||||||
|
matchedChars = []
|
||||||
|
|
||||||
|
for matchIndex in matches
|
||||||
|
unmatched = text.substring(lastIndex, matchIndex)
|
||||||
|
|
||||||
|
if unmatched
|
||||||
|
element.append(matchedChars.join("").bold()) if matchedChars.length
|
||||||
|
matchedChars = []
|
||||||
|
element.append(document.createTextNode(unmatched))
|
||||||
|
|
||||||
|
matchedChars.push(text[matchIndex])
|
||||||
|
lastIndex = matchIndex + 1
|
||||||
|
|
||||||
|
element.append(matchedChars.join("").bold()) if matchedChars.length
|
||||||
|
element.append(document.createTextNode(text.substring(lastIndex)))
|
||||||
|
|
||||||
|
# make tbody row html
|
||||||
|
makeHtml: (filePath, matches, blobItemUrl) ->
|
||||||
|
$tr = $("<tr class='tree-item'><td class='tree-item-file-name'><i class='fa fa-file-text-o fa-fw'></i><span class='str-truncated'><a></a></span></td></tr>")
|
||||||
|
if matches
|
||||||
|
$tr.find("a").replaceWith(highlighter($tr.find("a"), filePath, matches).attr("href", blobItemUrl))
|
||||||
|
else
|
||||||
|
$tr.find("a").attr("href", blobItemUrl).text(filePath)
|
||||||
|
|
||||||
|
return $tr
|
||||||
|
|
||||||
|
selectRow: (type) ->
|
||||||
|
rows = @element.find(".files-slider tr.tree-item")
|
||||||
|
selectedRow = @element.find(".files-slider tr.tree-item.selected")
|
||||||
|
|
||||||
|
if rows && rows.length > 0
|
||||||
|
if selectedRow && selectedRow.length > 0
|
||||||
|
if type == "UP"
|
||||||
|
next = selectedRow.prev()
|
||||||
|
else if type == "DOWN"
|
||||||
|
next = selectedRow.next()
|
||||||
|
|
||||||
|
if next.length > 0
|
||||||
|
selectedRow.removeClass "selected"
|
||||||
|
selectedRow = next
|
||||||
|
else
|
||||||
|
selectedRow = rows.eq(0)
|
||||||
|
selectedRow.addClass("selected").focus()
|
||||||
|
|
||||||
|
selectRowUp: =>
|
||||||
|
@selectRow "UP"
|
||||||
|
|
||||||
|
selectRowDown: =>
|
||||||
|
@selectRow "DOWN"
|
||||||
|
|
||||||
|
goToTree: =>
|
||||||
|
location.href = @options.treeUrl
|
||||||
|
|
||||||
|
goToBlob: =>
|
||||||
|
path = @element.find(".tree-item.selected .tree-item-file-name a").attr("href")
|
||||||
|
location.href = path if path
|
19
app/assets/javascripts/shortcuts_find_file.js.coffee
Normal file
19
app/assets/javascripts/shortcuts_find_file.js.coffee
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#= require shortcuts_navigation
|
||||||
|
|
||||||
|
class @ShortcutsFindFile extends ShortcutsNavigation
|
||||||
|
constructor: (@projectFindFile) ->
|
||||||
|
super()
|
||||||
|
_oldStopCallback = Mousetrap.stopCallback
|
||||||
|
# override to fire shortcuts action when focus in textbox
|
||||||
|
Mousetrap.stopCallback = (event, element, combo) =>
|
||||||
|
if element == @projectFindFile.inputElement[0] and (combo == 'up' or combo == 'down' or combo == 'esc' or combo == 'enter')
|
||||||
|
# when press up/down key in textbox, cusor prevent to move to home/end
|
||||||
|
event.preventDefault()
|
||||||
|
return false
|
||||||
|
|
||||||
|
return _oldStopCallback(event, element, combo)
|
||||||
|
|
||||||
|
Mousetrap.bind('up', @projectFindFile.selectRowUp)
|
||||||
|
Mousetrap.bind('down', @projectFindFile.selectRowDown)
|
||||||
|
Mousetrap.bind('esc', @projectFindFile.goToTree)
|
||||||
|
Mousetrap.bind('enter', @projectFindFile.goToBlob)
|
4
app/assets/javascripts/shortcuts_tree.coffee
Normal file
4
app/assets/javascripts/shortcuts_tree.coffee
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
class @ShortcutsTree extends ShortcutsNavigation
|
||||||
|
constructor: ->
|
||||||
|
super()
|
||||||
|
Mousetrap.bind('t', -> ShortcutsTree.findAndFollowLink('.shortcuts-find-file'))
|
|
@ -1,5 +1,13 @@
|
||||||
.tree-holder {
|
.tree-holder {
|
||||||
|
|
||||||
|
.file-finder {
|
||||||
|
width: 50%;
|
||||||
|
.file-finder-input {
|
||||||
|
width: 95%;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.tree-table {
|
.tree-table {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
|
|
||||||
|
|
26
app/controllers/projects/find_file_controller.rb
Normal file
26
app/controllers/projects/find_file_controller.rb
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
# Controller for viewing a repository's file structure
|
||||||
|
class Projects::FindFileController < Projects::ApplicationController
|
||||||
|
include ExtractsPath
|
||||||
|
include ActionView::Helpers::SanitizeHelper
|
||||||
|
include TreeHelper
|
||||||
|
|
||||||
|
before_action :require_non_empty_project
|
||||||
|
before_action :assign_ref_vars
|
||||||
|
before_action :authorize_download_code!
|
||||||
|
|
||||||
|
def show
|
||||||
|
return render_404 unless @repository.commit(@ref)
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.html
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def list
|
||||||
|
file_paths = @repo.ls_files(@ref)
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.json { render json: file_paths }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -20,6 +20,8 @@ class Projects::RefsController < Projects::ApplicationController
|
||||||
namespace_project_network_path(@project.namespace, @project, @id, @options)
|
namespace_project_network_path(@project.namespace, @project, @id, @options)
|
||||||
when "graphs"
|
when "graphs"
|
||||||
namespace_project_graph_path(@project.namespace, @project, @id)
|
namespace_project_graph_path(@project.namespace, @project, @id)
|
||||||
|
when "find_file"
|
||||||
|
namespace_project_find_file_path(@project.namespace, @project, @id)
|
||||||
when "graphs_commits"
|
when "graphs_commits"
|
||||||
commits_namespace_project_graph_path(@project.namespace, @project, @id)
|
commits_namespace_project_graph_path(@project.namespace, @project, @id)
|
||||||
else
|
else
|
||||||
|
|
|
@ -681,6 +681,11 @@ class Repository
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def ls_files(ref)
|
||||||
|
actual_ref = ref || root_ref
|
||||||
|
raw_repository.ls_files(actual_ref)
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def cache
|
def cache
|
||||||
|
|
|
@ -40,6 +40,32 @@
|
||||||
%td.shortcut
|
%td.shortcut
|
||||||
.key enter
|
.key enter
|
||||||
%td Open Selection
|
%td Open Selection
|
||||||
|
%tr
|
||||||
|
%td.shortcut
|
||||||
|
.key t
|
||||||
|
%td Go to finding file
|
||||||
|
%tbody
|
||||||
|
%tr
|
||||||
|
%th
|
||||||
|
%th Finding Project File
|
||||||
|
%tr
|
||||||
|
%td.shortcut
|
||||||
|
.key
|
||||||
|
%i.fa.fa-arrow-up
|
||||||
|
%td Move selection up
|
||||||
|
%tr
|
||||||
|
%td.shortcut
|
||||||
|
.key
|
||||||
|
%i.fa.fa-arrow-down
|
||||||
|
%td Move selection down
|
||||||
|
%tr
|
||||||
|
%td.shortcut
|
||||||
|
.key enter
|
||||||
|
%td Open Selection
|
||||||
|
%tr
|
||||||
|
%td.shortcut
|
||||||
|
.key esc
|
||||||
|
%td Go back
|
||||||
|
|
||||||
.col-lg-4
|
.col-lg-4
|
||||||
%table.shortcut-mappings
|
%table.shortcut-mappings
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
%span
|
%span
|
||||||
Activity
|
Activity
|
||||||
- if project_nav_tab? :files
|
- if project_nav_tab? :files
|
||||||
= nav_link(controller: %w(tree blob blame edit_tree new_tree)) do
|
= nav_link(controller: %w(tree blob blame edit_tree new_tree find_file)) do
|
||||||
= link_to project_files_path(@project), title: 'Files', class: 'shortcuts-tree' do
|
= link_to project_files_path(@project), title: 'Files', class: 'shortcuts-tree' do
|
||||||
= icon('files-o fw')
|
= icon('files-o fw')
|
||||||
%span
|
%span
|
||||||
|
@ -117,4 +117,3 @@
|
||||||
%li.hidden
|
%li.hidden
|
||||||
= link_to namespace_project_network_path(@project.namespace, @project, current_ref), title: 'Network', class: 'shortcuts-network' do
|
= link_to namespace_project_network_path(@project.namespace, @project, current_ref), title: 'Network', class: 'shortcuts-network' do
|
||||||
Network
|
Network
|
||||||
|
|
||||||
|
|
3
app/views/projects/_find_file_link.html.haml
Normal file
3
app/views/projects/_find_file_link.html.haml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
= link_to namespace_project_find_file_path(@project.namespace, @project, @ref), class: 'btn btn-grouped shortcuts-find-file', rel: 'nofollow' do
|
||||||
|
= icon('search')
|
||||||
|
%span Find File
|
27
app/views/projects/find_file/show.html.haml
Normal file
27
app/views/projects/find_file/show.html.haml
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
- page_title "Find File", @ref
|
||||||
|
- header_title project_title(@project, "Files", project_files_path(@project))
|
||||||
|
|
||||||
|
.file-finder-holder.tree-holder.clearfix
|
||||||
|
.gray-content-block.top-block
|
||||||
|
.tree-ref-holder
|
||||||
|
= render 'shared/ref_switcher', destination: 'find_file', path: @path
|
||||||
|
%ul.breadcrumb.repo-breadcrumb
|
||||||
|
%li
|
||||||
|
= link_to namespace_project_tree_path(@project.namespace, @project, @ref) do
|
||||||
|
= @project.path
|
||||||
|
%li.file-finder
|
||||||
|
%input#file_find.form-control.file-finder-input{type: "text", placeholder: 'Find by path'}
|
||||||
|
|
||||||
|
%div.tree-content-holder
|
||||||
|
.table-holder
|
||||||
|
%table.table.files-slider{class: "table_#{@hex_path} tree-table table-striped" }
|
||||||
|
%tbody
|
||||||
|
= spinner nil, true
|
||||||
|
|
||||||
|
:coffeescript
|
||||||
|
projectFindFile = new ProjectFindFile($(".file-finder-holder"), {
|
||||||
|
url: "#{escape_javascript(namespace_project_files_path(@project.namespace, @project, @ref, @options.merge(format: :json)))}"
|
||||||
|
treeUrl: "#{escape_javascript(namespace_project_tree_path(@project.namespace, @project, @ref))}"
|
||||||
|
blobUrlTemplate: "#{escape_javascript(namespace_project_blob_path(@project.namespace, @project, @id || @commit.id))}"
|
||||||
|
})
|
||||||
|
new ShortcutsFindFile(projectFindFile)
|
|
@ -3,12 +3,12 @@
|
||||||
= content_for :meta_tags do
|
= content_for :meta_tags do
|
||||||
- if current_user
|
- if current_user
|
||||||
= auto_discovery_link_tag(:atom, namespace_project_commits_url(@project.namespace, @project, @ref, format: :atom, private_token: current_user.private_token), title: "#{@project.name}:#{@ref} commits")
|
= auto_discovery_link_tag(:atom, namespace_project_commits_url(@project.namespace, @project, @ref, format: :atom, private_token: current_user.private_token), title: "#{@project.name}:#{@ref} commits")
|
||||||
|
|
||||||
= render 'projects/last_push'
|
= render 'projects/last_push'
|
||||||
|
|
||||||
- if can? current_user, :download_code, @project
|
.pull-right
|
||||||
.tree-download-holder
|
= render 'projects/find_file_link'
|
||||||
= render 'projects/repositories/download_archive', ref: @ref, btn_class: 'btn-group pull-right hidden-xs hidden-sm', split_button: true
|
- if can? current_user, :download_code, @project
|
||||||
|
= render 'projects/repositories/download_archive', ref: @ref, btn_class: 'hidden-xs hidden-sm btn-grouped', split_button: true
|
||||||
|
|
||||||
#tree-holder.tree-holder.clearfix
|
#tree-holder.tree-holder.clearfix
|
||||||
.gray-content-block.top-block
|
.gray-content-block.top-block
|
||||||
|
|
|
@ -440,6 +440,24 @@ Rails.application.routes.draw do
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
scope do
|
||||||
|
get(
|
||||||
|
'/find_file/*id',
|
||||||
|
to: 'find_file#show',
|
||||||
|
constraints: { id: /.+/, format: /html/ },
|
||||||
|
as: :find_file
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
scope do
|
||||||
|
get(
|
||||||
|
'/files/*id',
|
||||||
|
to: 'find_file#list',
|
||||||
|
constraints: { id: /(?:[^.]|\.(?!json$))+/, format: /json/ },
|
||||||
|
as: :files
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
scope do
|
scope do
|
||||||
post(
|
post(
|
||||||
'/create_dir/*id',
|
'/create_dir/*id',
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 77 KiB After Width: | Height: | Size: 48 KiB |
42
features/project/find_file.feature
Normal file
42
features/project/find_file.feature
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
@dashboard
|
||||||
|
Feature: Project Find File
|
||||||
|
Background:
|
||||||
|
Given I sign in as a user
|
||||||
|
And I own a project
|
||||||
|
And I visit my project's files page
|
||||||
|
|
||||||
|
@javascript
|
||||||
|
Scenario: Navigate to find file by shortcut
|
||||||
|
Given I press "t"
|
||||||
|
Then I should see "find file" page
|
||||||
|
|
||||||
|
Scenario: Navigate to find file
|
||||||
|
Given I click Find File button
|
||||||
|
Then I should see "find file" page
|
||||||
|
|
||||||
|
@javascript
|
||||||
|
Scenario: I search file
|
||||||
|
Given I visit project find file page
|
||||||
|
And I fill in file find with "change"
|
||||||
|
Then I should not see ".gitignore" in files
|
||||||
|
And I should not see ".gitmodules" in files
|
||||||
|
And I should see "CHANGELOG" in files
|
||||||
|
And I should not see "VERSION" in files
|
||||||
|
|
||||||
|
@javascript
|
||||||
|
Scenario: I search file that not exist
|
||||||
|
Given I visit project find file page
|
||||||
|
And I fill in file find with "asdfghjklqwertyuizxcvbnm"
|
||||||
|
Then I should not see ".gitignore" in files
|
||||||
|
And I should not see ".gitmodules" in files
|
||||||
|
And I should not see "CHANGELOG" in files
|
||||||
|
And I should not see "VERSION" in files
|
||||||
|
|
||||||
|
@javascript
|
||||||
|
Scenario: I search file that partially matches
|
||||||
|
Given I visit project find file page
|
||||||
|
And I fill in file find with "git"
|
||||||
|
Then I should see ".gitignore" in files
|
||||||
|
And I should see ".gitmodules" in files
|
||||||
|
And I should not see "CHANGELOG" in files
|
||||||
|
And I should not see "VERSION" in files
|
73
features/steps/project/project_find_file.rb
Normal file
73
features/steps/project/project_find_file.rb
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
class Spinach::Features::ProjectFindFile < Spinach::FeatureSteps
|
||||||
|
include SharedAuthentication
|
||||||
|
include SharedPaths
|
||||||
|
include SharedProject
|
||||||
|
include SharedProjectTab
|
||||||
|
|
||||||
|
step 'I press "t"' do
|
||||||
|
find('body').native.send_key('t')
|
||||||
|
end
|
||||||
|
|
||||||
|
step 'I click Find File button' do
|
||||||
|
click_link 'Find File'
|
||||||
|
end
|
||||||
|
|
||||||
|
step 'I should see "find file" page' do
|
||||||
|
ensure_active_main_tab('Files')
|
||||||
|
expect(page).to have_selector('.file-finder-holder', count: 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
step 'I fill in Find by path with "git"' do
|
||||||
|
ensure_active_main_tab('Files')
|
||||||
|
expect(page).to have_selector('.file-finder-holder', count: 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
step 'I fill in file find with "git"' do
|
||||||
|
find_file "git"
|
||||||
|
end
|
||||||
|
|
||||||
|
step 'I fill in file find with "change"' do
|
||||||
|
find_file "change"
|
||||||
|
end
|
||||||
|
|
||||||
|
step 'I fill in file find with "asdfghjklqwertyuizxcvbnm"' do
|
||||||
|
find_file "asdfghjklqwertyuizxcvbnm"
|
||||||
|
end
|
||||||
|
|
||||||
|
step 'I should see "VERSION" in files' do
|
||||||
|
expect(page).to have_content("VERSION")
|
||||||
|
end
|
||||||
|
|
||||||
|
step 'I should not see "VERSION" in files' do
|
||||||
|
expect(page).not_to have_content("VERSION")
|
||||||
|
end
|
||||||
|
|
||||||
|
step 'I should see "CHANGELOG" in files' do
|
||||||
|
expect(page).to have_content("CHANGELOG")
|
||||||
|
end
|
||||||
|
|
||||||
|
step 'I should not see "CHANGELOG" in files' do
|
||||||
|
expect(page).not_to have_content("CHANGELOG")
|
||||||
|
end
|
||||||
|
|
||||||
|
step 'I should see ".gitmodules" in files' do
|
||||||
|
expect(page).to have_content(".gitmodules")
|
||||||
|
end
|
||||||
|
|
||||||
|
step 'I should not see ".gitmodules" in files' do
|
||||||
|
expect(page).not_to have_content(".gitmodules")
|
||||||
|
end
|
||||||
|
|
||||||
|
step 'I should see ".gitignore" in files' do
|
||||||
|
expect(page).to have_content(".gitignore")
|
||||||
|
end
|
||||||
|
|
||||||
|
step 'I should not see ".gitignore" in files' do
|
||||||
|
expect(page).not_to have_content(".gitignore")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def find_file(text)
|
||||||
|
fill_in 'file_find', with: text
|
||||||
|
end
|
||||||
|
end
|
|
@ -259,6 +259,10 @@ module SharedPaths
|
||||||
visit namespace_project_deploy_keys_path(@project.namespace, @project)
|
visit namespace_project_deploy_keys_path(@project.namespace, @project)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
step 'I visit project find file page' do
|
||||||
|
visit namespace_project_find_file_path(@project.namespace, @project, root_ref)
|
||||||
|
end
|
||||||
|
|
||||||
# ----------------------------------------
|
# ----------------------------------------
|
||||||
# "Shop" Project
|
# "Shop" Project
|
||||||
# ----------------------------------------
|
# ----------------------------------------
|
||||||
|
|
66
spec/controllers/projects/find_file_controller_spec.rb
Normal file
66
spec/controllers/projects/find_file_controller_spec.rb
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Projects::FindFileController do
|
||||||
|
let(:project) { create(:project) }
|
||||||
|
let(:user) { create(:user) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
sign_in(user)
|
||||||
|
|
||||||
|
project.team << [user, :master]
|
||||||
|
controller.instance_variable_set(:@project, project)
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "GET #show" do
|
||||||
|
# Make sure any errors accessing the tree in our views bubble up to this spec
|
||||||
|
render_views
|
||||||
|
|
||||||
|
before do
|
||||||
|
get(:show,
|
||||||
|
namespace_id: project.namespace.to_param,
|
||||||
|
project_id: project.to_param,
|
||||||
|
id: id)
|
||||||
|
end
|
||||||
|
|
||||||
|
context "valid branch" do
|
||||||
|
let(:id) { 'master' }
|
||||||
|
it { is_expected.to respond_with(:success) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context "invalid branch" do
|
||||||
|
let(:id) { 'invalid-branch' }
|
||||||
|
it { is_expected.to respond_with(:not_found) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "GET #list" do
|
||||||
|
def go(format: 'json')
|
||||||
|
get :list,
|
||||||
|
namespace_id: project.namespace.to_param,
|
||||||
|
project_id: project.to_param,
|
||||||
|
id: id,
|
||||||
|
format: format
|
||||||
|
end
|
||||||
|
|
||||||
|
context "valid branch" do
|
||||||
|
let(:id) { 'master' }
|
||||||
|
it 'returns an array of file path list' do
|
||||||
|
go
|
||||||
|
|
||||||
|
json = JSON.parse(response.body)
|
||||||
|
is_expected.to respond_with(:success)
|
||||||
|
expect(json).not_to eq(nil)
|
||||||
|
expect(json.length).to be >= 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "invalid branch" do
|
||||||
|
let(:id) { 'invalid-branch' }
|
||||||
|
|
||||||
|
it 'responds with status 404' do
|
||||||
|
go
|
||||||
|
is_expected.to respond_with(:not_found)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -434,6 +434,18 @@ describe Projects::TreeController, 'routing' do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# project_find_file GET /:namespace_id/:project_id/find_file/*id(.:format) projects/find_file#show {:id=>/.+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?<!\.atom)/, :format=>/html/}
|
||||||
|
# project_files GET /:namespace_id/:project_id/files/*id(.:format) projects/find_file#list {:id=>/(?:[^.]|\.(?!json$))+/, :namespace_id=>/[a-zA-Z.0-9_\-]+/, :project_id=>/[a-zA-Z.0-9_\-]+(?<!\.atom)/, :format=>/json/}
|
||||||
|
describe Projects::FindFileController, 'routing' do
|
||||||
|
it 'to #show' do
|
||||||
|
expect(get('/gitlab/gitlabhq/find_file/master')).to route_to('projects/find_file#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'to #list' do
|
||||||
|
expect(get('/gitlab/gitlabhq/files/master.json')).to route_to('projects/find_file#list', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master', format: 'json')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe Projects::BlobController, 'routing' do
|
describe Projects::BlobController, 'routing' do
|
||||||
it 'to #edit' do
|
it 'to #edit' do
|
||||||
expect(get('/gitlab/gitlabhq/edit/master/app/models/project.rb')).to(
|
expect(get('/gitlab/gitlabhq/edit/master/app/models/project.rb')).to(
|
||||||
|
|
1
vendor/assets/javascripts/fuzzaldrin-plus.min.js
vendored
Normal file
1
vendor/assets/javascripts/fuzzaldrin-plus.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue