Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
d8458c4d
Commit
d8458c4d
authored
Oct 15, 2020
by
Himanshu Kapoor
Committed by
Ash McKenzie
Oct 15, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Consolidate the Edit and Web IDE buttons
parent
49ed45ff
Changes
23
Hide whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
660 additions
and
160 deletions
+660
-160
app/assets/javascripts/pages/projects/blob/show/index.js
app/assets/javascripts/pages/projects/blob/show/index.js
+3
-0
app/assets/javascripts/pages/projects/shared/web_ide_link/index.js
...s/javascripts/pages/projects/shared/web_ide_link/index.js
+31
-0
app/assets/javascripts/repository/index.js
app/assets/javascripts/repository/index.js
+4
-28
app/assets/javascripts/vue_shared/components/actions_button.vue
...sets/javascripts/vue_shared/components/actions_button.vue
+18
-5
app/assets/javascripts/vue_shared/components/web_ide_link.vue
...assets/javascripts/vue_shared/components/web_ide_link.vue
+74
-14
app/helpers/blob_helper.rb
app/helpers/blob_helper.rb
+13
-5
app/helpers/tree_helper.rb
app/helpers/tree_helper.rb
+17
-26
app/helpers/web_ide_button_helper.rb
app/helpers/web_ide_button_helper.rb
+61
-0
app/views/projects/blob/_header.html.haml
app/views/projects/blob/_header.html.haml
+5
-2
app/views/projects/tree/_tree_header.html.haml
app/views/projects/tree/_tree_header.html.haml
+1
-11
app/views/shared/_confirm_fork_modal.html.haml
app/views/shared/_confirm_fork_modal.html.haml
+1
-1
app/views/shared/_web_ide_button.html.haml
app/views/shared/_web_ide_button.html.haml
+10
-0
config/feature_flags/development/consolidated_edit_button.yml
...ig/feature_flags/development/consolidated_edit_button.yml
+7
-0
locale/gitlab.pot
locale/gitlab.pot
+3
-0
spec/features/projects/blobs/edit_spec.rb
spec/features/projects/blobs/edit_spec.rb
+6
-1
spec/features/projects/files/user_browses_lfs_files_spec.rb
spec/features/projects/files/user_browses_lfs_files_spec.rb
+22
-2
spec/features/projects/files/user_creates_files_spec.rb
spec/features/projects/files/user_creates_files_spec.rb
+5
-1
spec/features/projects/files/user_edits_files_spec.rb
spec/features/projects/files/user_edits_files_spec.rb
+148
-25
spec/frontend/vue_shared/components/actions_button_spec.js
spec/frontend/vue_shared/components/actions_button_spec.js
+15
-13
spec/frontend/vue_shared/components/web_ide_link_spec.js
spec/frontend/vue_shared/components/web_ide_link_spec.js
+60
-12
spec/helpers/blob_helper_spec.rb
spec/helpers/blob_helper_spec.rb
+34
-4
spec/helpers/tree_helper_spec.rb
spec/helpers/tree_helper_spec.rb
+100
-10
spec/support/helpers/features/blob_spec_helpers.rb
spec/support/helpers/features/blob_spec_helpers.rb
+22
-0
No files found.
app/assets/javascripts/pages/projects/blob/show/index.js
View file @
d8458c4d
...
...
@@ -3,6 +3,7 @@ import commitPipelineStatus from '~/projects/tree/components/commit_pipeline_sta
import
BlobViewer
from
'
~/blob/viewer/index
'
;
import
initBlob
from
'
~/pages/projects/init_blob
'
;
import
GpgBadges
from
'
~/gpg_badges
'
;
import
initWebIdeLink
from
'
~/pages/projects/shared/web_ide_link
'
;
import
'
~/sourcegraph/load
'
;
import
PipelineTourSuccessModal
from
'
~/blob/pipeline_tour_success_modal.vue
'
;
import
{
parseBoolean
}
from
'
~/lib/utils/common_utils
'
;
...
...
@@ -55,6 +56,8 @@ document.addEventListener('DOMContentLoaded', () => {
});
}
initWebIdeLink
({
el
:
document
.
getElementById
(
'
js-blob-web-ide-link
'
)
});
GpgBadges
.
fetch
();
const
codeNavEl
=
document
.
getElementById
(
'
js-code-navigation
'
);
...
...
app/assets/javascripts/pages/projects/shared/web_ide_link/index.js
0 → 100644
View file @
d8458c4d
import
Vue
from
'
vue
'
;
import
{
convertObjectPropsToCamelCase
}
from
'
~/lib/utils/common_utils
'
;
import
{
joinPaths
,
webIDEUrl
}
from
'
~/lib/utils/url_utility
'
;
import
WebIdeButton
from
'
~/vue_shared/components/web_ide_link.vue
'
;
export
default
({
el
,
router
})
=>
{
if
(
!
el
)
return
;
const
{
projectPath
,
ref
,
isBlob
,
webIdeUrl
,
...
options
}
=
convertObjectPropsToCamelCase
(
JSON
.
parse
(
el
.
dataset
.
options
),
);
// eslint-disable-next-line no-new
new
Vue
({
el
,
router
,
render
(
h
)
{
return
h
(
WebIdeButton
,
{
props
:
{
isBlob
,
webIdeUrl
:
isBlob
?
webIdeUrl
:
webIDEUrl
(
joinPaths
(
'
/
'
,
projectPath
,
'
edit
'
,
ref
,
'
-
'
,
this
.
$route
?.
params
.
path
||
''
,
'
/
'
),
),
...
options
,
},
});
},
});
};
app/assets/javascripts/repository/index.js
View file @
d8458c4d
import
Vue
from
'
vue
'
;
import
PathLastCommitQuery
from
'
shared_queries/repository/path_last_commit.query.graphql
'
;
import
{
escapeFileUrl
,
joinPaths
,
webIDEUrl
}
from
'
../lib/utils/url_utility
'
;
import
{
escapeFileUrl
}
from
'
../lib/utils/url_utility
'
;
import
createRouter
from
'
./router
'
;
import
App
from
'
./components/app.vue
'
;
import
Breadcrumbs
from
'
./components/breadcrumbs.vue
'
;
import
LastCommit
from
'
./components/last_commit.vue
'
;
import
TreeActionLink
from
'
./components/tree_action_link.vue
'
;
import
WebIdeLink
from
'
~/vue_shared/components/web_ide_link.vue
'
;
import
initWebIdeLink
from
'
~/pages/projects/shared/web_ide_link
'
;
import
DirectoryDownloadLinks
from
'
./components/directory_download_links.vue
'
;
import
apolloProvider
from
'
./graphql
'
;
import
{
setTitle
}
from
'
./utils/title
'
;
import
{
updateFormAction
}
from
'
./utils/dom
'
;
import
{
convertObjectPropsToCamelCase
,
parseBoolean
}
from
'
../lib/utils/common_utils
'
;
import
{
parseBoolean
}
from
'
../lib/utils/common_utils
'
;
import
{
__
}
from
'
../locale
'
;
export
default
function
setupVueRepositoryList
()
{
...
...
@@ -138,31 +138,7 @@ export default function setupVueRepositoryList() {
},
});
const
webIdeLinkEl
=
document
.
getElementById
(
'
js-tree-web-ide-link
'
);
if
(
webIdeLinkEl
)
{
const
{
webIdeUrlData
:
{
path
:
ideBasePath
,
isFork
:
webIdeIsFork
},
...
options
}
=
convertObjectPropsToCamelCase
(
JSON
.
parse
(
webIdeLinkEl
.
dataset
.
options
),
{
deep
:
true
});
// eslint-disable-next-line no-new
new
Vue
({
el
:
webIdeLinkEl
,
router
,
render
(
h
)
{
return
h
(
WebIdeLink
,
{
props
:
{
webIdeUrl
:
webIDEUrl
(
joinPaths
(
'
/
'
,
ideBasePath
,
'
edit
'
,
ref
,
'
-
'
,
this
.
$route
.
params
.
path
||
''
,
'
/
'
),
),
webIdeIsFork
,
...
options
,
},
});
},
});
}
initWebIdeLink
({
el
:
document
.
getElementById
(
'
js-tree-web-ide-link
'
),
router
});
const
directoryDownloadLinks
=
document
.
getElementById
(
'
js-directory-downloads
'
);
...
...
app/assets/javascripts/vue_shared/components/actions_button.vue
View file @
d8458c4d
...
...
@@ -3,7 +3,7 @@ import {
GlDropdown
,
GlDropdownItem
,
GlDropdownDivider
,
Gl
Link
,
Gl
Button
,
GlTooltipDirective
,
}
from
'
@gitlab/ui
'
;
...
...
@@ -12,7 +12,7 @@ export default {
GlDropdown
,
GlDropdownItem
,
GlDropdownDivider
,
Gl
Link
,
Gl
Button
,
},
directives
:
{
GlTooltip
:
GlTooltipDirective
,
...
...
@@ -27,6 +27,16 @@ export default {
required
:
false
,
default
:
''
,
},
category
:
{
type
:
String
,
required
:
false
,
default
:
'
secondary
'
,
},
variant
:
{
type
:
String
,
required
:
false
,
default
:
'
default
'
,
},
},
computed
:
{
hasMultipleActions
()
{
...
...
@@ -54,6 +64,8 @@ export default {
class=
"gl-button-deprecated-adapter"
:text=
"selectedAction.text"
:split-href=
"selectedAction.href"
:variant=
"variant"
:category=
"category"
split
@
click=
"handleClick(selectedAction, $event)"
>
...
...
@@ -77,14 +89,15 @@ export default {
<gl-dropdown-divider
v-if=
"index != actions.length - 1"
:key=
"action.key + '_divider'"
/>
</
template
>
</gl-dropdown>
<gl-
link
<gl-
button
v-else-if=
"selectedAction"
v-gl-tooltip=
"selectedAction.tooltip"
v-bind=
"selectedAction.attrs"
class=
"btn"
:variant=
"variant"
:category=
"category"
:href=
"selectedAction.href"
@
click=
"handleClick(selectedAction, $event)"
>
{{ selectedAction.text }}
</gl-
link
>
</gl-
button
>
</template>
app/assets/javascripts/vue_shared/components/web_ide_link.vue
View file @
d8458c4d
...
...
@@ -4,6 +4,7 @@ import { __ } from '~/locale';
import
LocalStorageSync
from
'
~/vue_shared/components/local_storage_sync.vue
'
;
import
ActionsButton
from
'
~/vue_shared/components/actions_button.vue
'
;
const
KEY_EDIT
=
'
edit
'
;
const
KEY_WEB_IDE
=
'
webide
'
;
const
KEY_GITPOD
=
'
gitpod
'
;
...
...
@@ -13,21 +14,31 @@ export default {
LocalStorageSync
,
},
props
:
{
webIdeUrl
:
{
type
:
String
,
isFork
:
{
type
:
Boolean
,
required
:
false
,
default
:
''
,
default
:
false
,
},
webIdeIs
Fork
:
{
needsTo
Fork
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
needsToFork
:
{
gitpodEnabled
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
isBlob
:
{
type
:
Boolean
,
required
:
false
,
default
:
false
,
},
showEditButton
:
{
type
:
Boolean
,
required
:
false
,
default
:
true
,
},
showWebIdeButton
:
{
type
:
Boolean
,
required
:
false
,
...
...
@@ -38,15 +49,20 @@ export default {
required
:
false
,
default
:
false
,
},
gitpod
Url
:
{
edit
Url
:
{
type
:
String
,
required
:
false
,
default
:
''
,
},
gitpodEnabled
:
{
type
:
Boolean
,
webIdeUrl
:
{
type
:
String
,
required
:
false
,
default
:
false
,
default
:
''
,
},
gitpodUrl
:
{
type
:
String
,
required
:
false
,
default
:
''
,
},
},
data
()
{
...
...
@@ -56,7 +72,33 @@ export default {
},
computed
:
{
actions
()
{
return
[
this
.
webIdeAction
,
this
.
gitpodAction
].
filter
(
x
=>
x
);
return
[
this
.
webIdeAction
,
this
.
editAction
,
this
.
gitpodAction
].
filter
(
action
=>
action
);
},
editAction
()
{
if
(
!
this
.
showEditButton
)
{
return
null
;
}
const
handleOptions
=
this
.
needsToFork
?
{
href
:
'
#modal-confirm-fork-edit
'
,
handle
:
()
=>
this
.
showModal
(
'
#modal-confirm-fork-edit
'
),
}
:
{
href
:
this
.
editUrl
};
return
{
key
:
KEY_EDIT
,
text
:
__
(
'
Edit
'
),
secondaryText
:
__
(
'
Edit this file only.
'
),
tooltip
:
''
,
attrs
:
{
'
data-qa-selector
'
:
'
edit_button
'
,
'
data-track-event
'
:
'
click_edit
'
,
// eslint-disable-next-line @gitlab/require-i18n-strings
'
data-track-label
'
:
'
Edit
'
,
},
...
handleOptions
,
};
},
webIdeAction
()
{
if
(
!
this
.
showWebIdeButton
)
{
...
...
@@ -64,10 +106,19 @@ export default {
}
const
handleOptions
=
this
.
needsToFork
?
{
href
:
'
#modal-confirm-fork
'
,
handle
:
()
=>
this
.
showModal
(
'
#modal-confirm-fork
'
)
}
?
{
href
:
'
#modal-confirm-fork-webide
'
,
handle
:
()
=>
this
.
showModal
(
'
#modal-confirm-fork-webide
'
),
}
:
{
href
:
this
.
webIdeUrl
};
const
text
=
this
.
webIdeIsFork
?
__
(
'
Edit fork in Web IDE
'
)
:
__
(
'
Web IDE
'
);
let
text
=
__
(
'
Web IDE
'
);
if
(
this
.
isBlob
)
{
text
=
__
(
'
Edit in Web IDE
'
);
}
else
if
(
this
.
isFork
)
{
text
=
__
(
'
Edit fork in Web IDE
'
);
}
return
{
key
:
KEY_WEB_IDE
,
...
...
@@ -76,6 +127,9 @@ export default {
tooltip
:
''
,
attrs
:
{
'
data-qa-selector
'
:
'
web_ide_button
'
,
'
data-track-event
'
:
'
click_edit_ide
'
,
// eslint-disable-next-line @gitlab/require-i18n-strings
'
data-track-label
'
:
'
Web IDE
'
,
},
...
handleOptions
,
};
...
...
@@ -115,8 +169,14 @@ export default {
</
script
>
<
template
>
<div>
<actions-button
:actions=
"actions"
:selected-key=
"selection"
@
select=
"select"
/>
<div
class=
"d-inline-block gl-ml-3"
>
<actions-button
:actions=
"actions"
:selected-key=
"selection"
:variant=
"isBlob ? 'info' : 'default'"
:category=
"isBlob ? 'primary' : 'secondary'"
@
select=
"select"
/>
<local-storage-sync
storage-key=
"gl-web-ide-button-selected"
:value=
"selection"
...
...
app/helpers/blob_helper.rb
View file @
d8458c4d
...
...
@@ -27,11 +27,19 @@ module BlobHelper
end
def
ide_fork_and_edit_path
(
project
=
@project
,
ref
=
@ref
,
path
=
@path
,
options
=
{})
if
current_user
project_forks_path
(
project
,
namespace_key:
current_user
&
.
namespace
&
.
id
,
continue:
edit_blob_fork_params
(
ide_edit_path
(
project
,
ref
,
path
)))
end
fork_path_for_current_user
(
project
,
ide_edit_path
(
project
,
ref
,
path
))
end
def
fork_and_edit_path
(
project
=
@project
,
ref
=
@ref
,
path
=
@path
,
options
=
{})
fork_path_for_current_user
(
project
,
edit_blob_path
(
project
,
ref
,
path
,
options
))
end
def
fork_path_for_current_user
(
project
,
path
)
return
unless
current_user
project_forks_path
(
project
,
namespace_key:
current_user
.
namespace
&
.
id
,
continue:
edit_blob_fork_params
(
path
))
end
def
encode_ide_path
(
path
)
...
...
app/helpers/tree_helper.rb
View file @
d8458c4d
# frozen_string_literal: true
module
TreeHelper
include
BlobHelper
include
WebIdeButtonHelper
FILE_LIMIT
=
1_000
# Sorts a repository's tree so that folders are before files and renders
...
...
@@ -199,38 +202,26 @@ module TreeHelper
}
end
def
web_ide_url_data
(
project
)
can_push_code
=
current_user
&
.
can?
(
:push_code
,
project
)
fork_path
=
current_user
&
.
fork_of
(
project
)
&
.
full_path
def
web_ide_button_data
(
options
=
{})
{
project_path:
project_to_use
.
full_path
,
ref:
ActionDispatch
::
Journey
::
Router
::
Utils
.
escape_path
(
@ref
),
if
fork_path
&&
!
can_push_code
{
path:
fork_path
,
is_fork:
true
}
else
{
path:
project
.
full_path
,
is_fork:
false
}
end
end
is_fork:
fork
?,
needs_to_fork:
needs_to_fork?
,
gitpod_enabled:
!
current_user
.
nil?
&&
current_user
.
gitpod_enabled
,
is_blob:
!
options
[:
blob
].
nil?
,
def
vue_ide_link_data
(
project
,
ref
)
can_collaborate
=
can_collaborate_with_project?
(
project
)
can_create_mr_from_fork
=
can?
(
current_user
,
:fork_project
,
project
)
&&
can?
(
current_user
,
:create_merge_request_in
,
project
)
show_web_ide_button
=
(
can_collaborate
||
current_user
&
.
already_forked?
(
project
)
||
can_create_mr_from_fork
)
show_edit_button:
show_edit_button?
,
show_web_ide_button:
show_web_ide_button?
,
show_gitpod_button:
show_gitpod_button?
,
{
web_ide_url_data:
web_ide_url_data
(
project
),
needs_to_fork:
!
can_collaborate
&&
!
current_user
&
.
already_forked?
(
project
),
show_web_ide_button:
show_web_ide_button
,
show_gitpod_button:
show_web_ide_button
&&
Gitlab
::
Gitpod
.
feature_and_settings_enabled?
(
project
),
gitpod_url:
full_gitpod_url
(
project
,
ref
),
gitpod_enabled:
current_user
&
.
gitpod_enabled
web_ide_url:
web_ide_url
,
edit_url:
edit_url
,
gitpod_url:
gitpod_url
}
end
def
full_gitpod_url
(
project
,
ref
)
return
""
unless
Gitlab
::
Gitpod
.
feature_and_settings_enabled?
(
project
)
"
#{
Gitlab
::
CurrentSettings
.
gitpod_url
}
#
#{
project_tree_url
(
project
,
tree_join
(
ref
,
@path
||
''
))
}
"
end
def
directory_download_links
(
project
,
ref
,
archive_prefix
)
Gitlab
::
Workhorse
::
ARCHIVE_FORMATS
.
map
do
|
fmt
|
{
...
...
app/helpers/web_ide_button_helper.rb
0 → 100644
View file @
d8458c4d
# frozen_string_literal: true
module
WebIdeButtonHelper
def
project_fork
current_user
&
.
fork_of
(
@project
)
end
def
project_to_use
fork
?
?
project_fork
:
@project
end
def
can_collaborate?
can_collaborate_with_project?
(
@project
)
end
def
can_create_mr_from_fork?
can?
(
current_user
,
:fork_project
,
@project
)
&&
can?
(
current_user
,
:
create_merge_request_in
,
@project
)
end
def
show_web_ide_button?
can_collaborate?
||
can_create_mr_from_fork?
end
def
show_edit_button?
readable_blob?
&&
show_web_ide_button?
end
def
show_gitpod_button?
show_web_ide_button?
&&
Gitlab
::
Gitpod
.
feature_and_settings_enabled?
(
@project
)
end
def
can_push_code?
current_user
&
.
can?
(
:push_code
,
@project
)
end
def
fork?
!
project_fork
.
nil?
&&
!
can_push_code?
end
def
readable_blob?
!
readable_blob
({},
@path
,
@project
,
@ref
).
nil?
end
def
needs_to_fork?
!
can_collaborate?
&&
!
current_user
&
.
already_forked?
(
@project
)
end
def
web_ide_url
ide_edit_path
(
project_to_use
,
@ref
,
@path
||
''
)
end
def
edit_url
readable_blob?
?
edit_blob_path
(
@project
,
@ref
,
@path
||
''
)
:
''
end
def
gitpod_url
return
""
unless
Gitlab
::
Gitpod
.
feature_and_settings_enabled?
(
@project
)
"
#{
Gitlab
::
CurrentSettings
.
gitpod_url
}
#
#{
project_tree_url
(
@project
,
tree_join
(
@ref
,
@path
||
''
))
}
"
end
end
app/views/projects/blob/_header.html.haml
View file @
d8458c4d
...
...
@@ -4,8 +4,11 @@
.file-actions
<
=
render
'projects/blob/viewer_switcher'
,
blob:
blob
unless
blame
=
edit_blob_button
(
@project
,
@ref
,
@path
,
blob:
blob
)
=
ide_edit_button
(
@project
,
@ref
,
@path
,
blob:
blob
)
-
if
Feature
.
enabled?
(
:consolidated_edit_button
)
=
render
'shared/web_ide_button'
,
blob:
blob
-
else
=
edit_blob_button
(
@project
,
@ref
,
@path
,
blob:
blob
)
=
ide_edit_button
(
@project
,
@ref
,
@path
,
blob:
blob
)
.btn-group.ml-2
{
role:
"group"
}
>
=
render_if_exists
'projects/blob/header_file_locks_link'
-
if
current_user
...
...
app/views/projects/tree/_tree_header.html.haml
View file @
d8458c4d
-
can_collaborate
=
can_collaborate_with_project?
(
@project
)
-
can_create_mr_from_fork
=
can?
(
current_user
,
:fork_project
,
@project
)
&&
can?
(
current_user
,
:create_merge_request_in
,
@project
)
-
can_visit_ide
=
can_collaborate
||
current_user
&
.
already_forked?
(
@project
)
.tree-ref-container
.tree-ref-holder
=
render
'shared/ref_switcher'
,
destination:
'tree'
,
path:
@path
,
show_create:
true
...
...
@@ -14,13 +10,7 @@
#js-tree-history-link
.d-inline-block
{
data:
{
history_link:
project_commits_path
(
@project
,
@ref
)
}
}
=
render
'projects/find_file_link'
-
if
can_visit_ide
||
can_create_mr_from_fork
#js-tree-web-ide-link
.d-inline-block
{
data:
{
options:
vue_ide_link_data
(
@project
,
@ref
).
to_json
}
}
-
if
!
can_visit_ide
=
render
'shared/confirm_fork_modal'
,
fork_path:
ide_fork_and_edit_path
(
@project
,
@ref
,
@path
)
-
unless
current_user
&
.
gitpod_enabled
=
render
'shared/gitpod/enable_gitpod_modal'
=
render
'shared/web_ide_button'
,
blob:
nil
-
if
show_xcode_link?
(
@project
)
.project-action-button.project-xcode.inline
<
...
...
app/views/shared/_confirm_fork_modal.html.haml
View file @
d8458c4d
#modal-confirm-fork
.modal
{
data:
{
qa_selector:
'confirm_fork_modal'
}
}
.modal
{
data:
{
qa_selector:
'confirm_fork_modal'
},
id:
"modal-confirm-fork-#{type}"
}
.modal-dialog
.modal-content
.modal-header
...
...
app/views/shared/_web_ide_button.html.haml
0 → 100644
View file @
d8458c4d
-
type
=
blob
?
'blob'
:
'tree'
.d-inline-block
{
data:
{
options:
web_ide_button_data
(
blob:
blob
).
to_json
},
id:
"js-#{type}-web-ide-link"
}
-
if
show_edit_button?
=
render
'shared/confirm_fork_modal'
,
fork_path:
fork_and_edit_path
(
@project
,
@ref
,
@path
),
type:
'edit'
-
if
show_web_ide_button?
=
render
'shared/confirm_fork_modal'
,
fork_path:
ide_fork_and_edit_path
(
@project
,
@ref
,
@path
),
type:
'webide'
-
if
show_gitpod_button?
=
render
'shared/gitpod/enable_gitpod_modal'
config/feature_flags/development/consolidated_edit_button.yml
0 → 100644
View file @
d8458c4d
---
name
:
consolidated_edit_button
introduced_by_url
:
https://gitlab.com/gitlab-org/gitlab/-/merge_requests/44311
rollout_issue_url
:
group
:
group::editor
type
:
development
default_enabled
:
false
locale/gitlab.pot
View file @
d8458c4d
...
...
@@ -9545,6 +9545,9 @@ msgstr ""
msgid "Edit stage"
msgstr ""
msgid "Edit this file only."
msgstr ""
msgid "Edit this release"
msgstr ""
...
...
spec/features/projects/blobs/edit_spec.rb
View file @
d8458c4d
...
...
@@ -4,6 +4,7 @@ require 'spec_helper'
RSpec
.
describe
'Editing file blob'
,
:js
do
include
TreeHelper
include
BlobSpecHelpers
let
(
:project
)
{
create
(
:project
,
:public
,
:repository
)
}
let
(
:merge_request
)
{
create
(
:merge_request
,
source_project:
project
,
source_branch:
'feature'
,
target_branch:
'master'
)
}
...
...
@@ -21,13 +22,17 @@ RSpec.describe 'Editing file blob', :js do
end
def
edit_and_commit
(
commit_changes:
true
,
is_diff:
false
)
set_default_button
(
'edit'
)
refresh
wait_for_requests
if
is_diff
first
(
'.js-diff-more-actions'
).
click
click_link
(
'Edit in single-file editor'
)
else
click_link
(
'Edit'
)
end
first
(
'.js-edit-blob'
).
click
fill_editor
(
content:
'class NextFeature\\nend\\n'
)
if
commit_changes
...
...
spec/features/projects/files/user_browses_lfs_files_spec.rb
View file @
d8458c4d
...
...
@@ -66,10 +66,30 @@ RSpec.describe 'Projects > Files > User browses LFS files' do
expect
(
page
).
to
have_content
(
'History'
)
expect
(
page
).
to
have_content
(
'Permalink'
)
expect
(
page
).
to
have_content
(
'Replace'
)
expect
(
page
).
to
have_link
(
'Download'
)
expect
(
page
).
not_to
have_content
(
'Annotate'
)
expect
(
page
).
not_to
have_content
(
'Blame'
)
expect
(
page
).
not_to
have_content
(
'Edit'
)
expect
(
page
).
to
have_link
(
'Download'
)
expect
(
page
).
not_to
have_selector
(
:link_or_button
,
text:
/^Edit$/
)
expect
(
page
).
to
have_selector
(
:link_or_button
,
'Edit in Web IDE'
)
end
end
context
'when feature flag :consolidated_edit_button is off'
do
before
do
stub_feature_flags
(
consolidated_edit_button:
false
)
click_link
(
'files'
)
click_link
(
'lfs'
)
click_link
(
'lfs_object.iso'
)
end
it
'does not show single file edit link'
do
page
.
within
(
'.content'
)
do
expect
(
page
).
to
have_selector
(
:link_or_button
,
'Web IDE'
)
expect
(
page
).
not_to
have_selector
(
:link_or_button
,
'Edit'
)
end
end
end
end
...
...
spec/features/projects/files/user_creates_files_spec.rb
View file @
d8458c4d
...
...
@@ -3,6 +3,8 @@
require
'spec_helper'
RSpec
.
describe
'Projects > Files > User creates files'
,
:js
do
include
BlobSpecHelpers
let
(
:fork_message
)
do
"You're not allowed to make changes to this project directly. "
\
"A fork of this project has been created that you can make changes in, so you can submit a merge request."
...
...
@@ -103,6 +105,8 @@ RSpec.describe 'Projects > Files > User creates files', :js do
end
it
'creates and commit a new file with new lines at the end of file'
do
set_default_button
(
'edit'
)
find
(
'#editor'
)
execute_script
(
'monaco.editor.getModels()[0].setValue("Sample\n\n\n")'
)
fill_in
(
:file_name
,
with:
'not_a_file.md'
)
...
...
@@ -113,7 +117,7 @@ RSpec.describe 'Projects > Files > User creates files', :js do
expect
(
current_path
).
to
eq
(
new_file_path
)
find
(
'.js-edit-blob'
).
click
click_link
(
'Edit'
)
find
(
'#editor'
)
expect
(
evaluate_script
(
'monaco.editor.getModels()[0].getValue()'
)).
to
eq
(
"Sample
\n\n\n
"
)
...
...
spec/features/projects/files/user_edits_files_spec.rb
View file @
d8458c4d
...
...
@@ -4,6 +4,8 @@ require 'spec_helper'
RSpec
.
describe
'Projects > Files > User edits files'
,
:js
do
include
ProjectForksHelper
include
BlobSpecHelpers
let
(
:project
)
{
create
(
:project
,
:repository
,
name:
'Shop'
)
}
let
(
:project2
)
{
create
(
:project
,
:repository
,
name:
'Another Project'
,
path:
'another-project'
)
}
let
(
:project_tree_path_root_ref
)
{
project_tree_path
(
project
,
project
.
repository
.
root_ref
)
}
...
...
@@ -14,6 +16,10 @@ RSpec.describe 'Projects > Files > User edits files', :js do
sign_in
(
user
)
end
after
do
unset_default_button
end
shared_examples
'unavailable for an archived project'
do
it
'does not show the edit link for an archived project'
,
:js
do
project
.
update!
(
archived:
true
)
...
...
@@ -39,14 +45,15 @@ RSpec.describe 'Projects > Files > User edits files', :js do
end
it
'inserts a content of a file'
do
set_default_button
(
'edit'
)
click_link
(
'.gitignore'
)
find
(
'.js-edit-blob'
).
click
click_link_or_button
(
'Edit'
)
find
(
'.file-editor'
,
match: :first
)
find
(
'#editor'
)
execute_script
(
"monaco.editor.getModels()[0].setValue('*.rbca')"
)
set_editor_value
(
'*.rbca'
)
expect
(
e
valuate_script
(
'monaco.editor.getModels()[0].getValue()'
)
).
to
eq
(
'*.rbca'
)
expect
(
e
ditor_value
).
to
eq
(
'*.rbca'
)
end
it
'does not show the edit link if a file is binary'
do
...
...
@@ -60,12 +67,13 @@ RSpec.describe 'Projects > Files > User edits files', :js do
end
it
'commits an edited file'
do
set_default_button
(
'edit'
)
click_link
(
'.gitignore'
)
find
(
'.js-edit-blob'
).
click
click_link_or_button
(
'Edit'
)
find
(
'.file-editor'
,
match: :first
)
find
(
'#editor'
)
execute_script
(
"monaco.editor.getModels()[0].setValue('*.rbca')"
)
set_editor_value
(
'*.rbca'
)
fill_in
(
:commit_message
,
with:
'New commit message'
,
visible:
true
)
click_button
(
'Commit changes'
)
...
...
@@ -77,13 +85,14 @@ RSpec.describe 'Projects > Files > User edits files', :js do
end
it
'commits an edited file to a new branch'
do
set_default_button
(
'edit'
)
click_link
(
'.gitignore'
)
find
(
'.js-edit-blob'
).
click
click_link_or_button
(
'Edit'
)
find
(
'.file-editor'
,
match: :first
)
find
(
'#editor'
)
execute_script
(
"monaco.editor.getModels()[0].setValue('*.rbca')"
)
set_editor_value
(
'*.rbca'
)
fill_in
(
:commit_message
,
with:
'New commit message'
,
visible:
true
)
fill_in
(
:branch_name
,
with:
'new_branch_name'
,
visible:
true
)
click_button
(
'Commit changes'
)
...
...
@@ -96,12 +105,13 @@ RSpec.describe 'Projects > Files > User edits files', :js do
end
it
'shows the diff of an edited file'
do
set_default_button
(
'edit'
)
click_link
(
'.gitignore'
)
find
(
'.js-edit-blob'
).
click
click_link_or_button
(
'Edit'
)
find
(
'.file-editor'
,
match: :first
)
find
(
'#editor'
)
execute_script
(
"monaco.editor.getModels()[0].setValue('*.rbca')"
)
set_editor_value
(
'*.rbca'
)
click_link
(
'Preview changes'
)
expect
(
page
).
to
have_css
(
'.line_holder.new'
)
...
...
@@ -118,8 +128,8 @@ RSpec.describe 'Projects > Files > User edits files', :js do
end
def
expect_fork_prompt
expect
(
page
).
to
have_
link
(
'Fork'
)
expect
(
page
).
to
have_
button
(
'Cancel'
)
expect
(
page
).
to
have_
selector
(
:link_or_button
,
'Fork'
)
expect
(
page
).
to
have_
selector
(
:link_or_button
,
'Cancel'
)
expect
(
page
).
to
have_content
(
"You're not allowed to edit files in this project directly. "
\
"Please fork this project, make your changes there, and submit a merge request."
...
...
@@ -134,30 +144,32 @@ RSpec.describe 'Projects > Files > User edits files', :js do
end
it
'inserts a content of a file in a forked project'
,
:sidekiq_might_not_need_inline
do
set_default_button
(
'edit'
)
click_link
(
'.gitignore'
)
click_button
(
'Edit'
)
click_
link_or_
button
(
'Edit'
)
expect_fork_prompt
click_link
(
'Fork
'
)
click_link
_or_button
(
'Fork project
'
)
expect_fork_status
find
(
'.file-editor'
,
match: :first
)
find
(
'#editor'
)
execute_script
(
"monaco.editor.getModels()[0].setValue('*.rbca')"
)
set_editor_value
(
'*.rbca'
)
expect
(
e
valuate_script
(
'monaco.editor.getModels()[0].getValue()'
)
).
to
eq
(
'*.rbca'
)
expect
(
e
ditor_value
).
to
eq
(
'*.rbca'
)
end
it
'opens the Web IDE in a forked project'
,
:sidekiq_might_not_need_inline
do
set_default_button
(
'webide'
)
click_link
(
'.gitignore'
)
click_button
(
'Web IDE'
)
click_
link_or_
button
(
'Web IDE'
)
expect_fork_prompt
click_link
(
'Fork
'
)
click_link
_or_button
(
'Fork project
'
)
expect_fork_status
...
...
@@ -166,17 +178,17 @@ RSpec.describe 'Projects > Files > User edits files', :js do
end
it
'commits an edited file in a forked project'
,
:sidekiq_might_not_need_inline
do
set_default_button
(
'edit'
)
click_link
(
'.gitignore'
)
find
(
'.js-edit-blob'
).
click
click_link_or_button
(
'Edit'
)
expect_fork_prompt
click_link
(
'Fork'
)
click_link_or_button
(
'Fork project'
)
find
(
'.file-editor'
,
match: :first
)
find
(
'#editor'
)
execute_script
(
"monaco.editor.getModels()[0].setValue('*.rbca')"
)
set_editor_value
(
'*.rbca'
)
fill_in
(
:commit_message
,
with:
'New commit message'
,
visible:
true
)
click_button
(
'Commit changes'
)
...
...
@@ -198,14 +210,14 @@ RSpec.describe 'Projects > Files > User edits files', :js do
end
it
'links to the forked project for editing'
,
:sidekiq_might_not_need_inline
do
set_default_button
(
'edit'
)
click_link
(
'.gitignore'
)
find
(
'.js-edit-blob'
).
click
click_link_or_button
(
'Edit'
)
expect
(
page
).
not_to
have_link
(
'Fork'
)
expect
(
page
).
not_to
have_button
(
'Cancel'
)
expect
(
page
).
not_to
have_link
(
'Fork project'
)
find
(
'#editor'
)
execute_script
(
"monaco.editor.getModels()[0].setValue('*.rbca')"
)
set_editor_value
(
'*.rbca'
)
fill_in
(
:commit_message
,
with:
'Another commit'
,
visible:
true
)
click_button
(
'Commit changes'
)
...
...
@@ -224,5 +236,116 @@ RSpec.describe 'Projects > Files > User edits files', :js do
let
(
:project
)
{
project2
}
end
end
context
'when feature flag :consolidated_edit_button is off'
do
before
do
stub_feature_flags
(
consolidated_edit_button:
false
)
end
context
'when an user does not have write access'
,
:js
do
before
do
project2
.
add_reporter
(
user
)
visit
(
project2_tree_path_root_ref
)
wait_for_requests
end
it
'inserts a content of a file in a forked project'
,
:sidekiq_might_not_need_inline
do
set_default_button
(
'edit'
)
click_link
(
'.gitignore'
)
click_link_or_button
(
'Edit'
)
expect_fork_prompt
click_link_or_button
(
'Fork'
)
expect_fork_status
find
(
'.file-editor'
,
match: :first
)
find
(
'#editor'
)
set_editor_value
(
'*.rbca'
)
expect
(
editor_value
).
to
eq
(
'*.rbca'
)
end
it
'opens the Web IDE in a forked project'
,
:sidekiq_might_not_need_inline
do
set_default_button
(
'webide'
)
click_link
(
'.gitignore'
)
click_link_or_button
(
'Web IDE'
)
expect_fork_prompt
click_link_or_button
(
'Fork'
)
expect_fork_status
expect
(
page
).
to
have_css
(
'.ide-sidebar-project-title'
,
text:
"
#{
project2
.
name
}
#{
user
.
namespace
.
full_path
}
/
#{
project2
.
path
}
"
)
expect
(
page
).
to
have_css
(
'.ide .multi-file-tab'
,
text:
'.gitignore'
)
end
it
'commits an edited file in a forked project'
,
:sidekiq_might_not_need_inline
do
set_default_button
(
'edit'
)
click_link
(
'.gitignore'
)
click_link_or_button
(
'Edit'
)
expect_fork_prompt
click_link_or_button
(
'Fork'
)
expect_fork_status
find
(
'.file-editor'
,
match: :first
)
find
(
'#editor'
)
set_editor_value
(
'*.rbca'
)
fill_in
(
:commit_message
,
with:
'New commit message'
,
visible:
true
)
click_button
(
'Commit changes'
)
fork
=
user
.
fork_of
(
project2
.
reload
)
expect
(
current_path
).
to
eq
(
project_new_merge_request_path
(
fork
))
wait_for_requests
expect
(
page
).
to
have_content
(
'New commit message'
)
end
context
'when the user already had a fork of the project'
,
:js
do
let!
(
:forked_project
)
{
fork_project
(
project2
,
user
,
namespace:
user
.
namespace
,
repository:
true
)
}
before
do
visit
(
project2_tree_path_root_ref
)
wait_for_requests
end
it
'links to the forked project for editing'
,
:sidekiq_might_not_need_inline
do
set_default_button
(
'edit'
)
click_link
(
'.gitignore'
)
click_link_or_button
(
'Edit'
)
expect
(
page
).
not_to
have_link
(
'Fork'
)
find
(
'#editor'
)
set_editor_value
(
'*.rbca'
)
fill_in
(
:commit_message
,
with:
'Another commit'
,
visible:
true
)
click_button
(
'Commit changes'
)
fork
=
user
.
fork_of
(
project2
)
expect
(
current_path
).
to
eq
(
project_new_merge_request_path
(
fork
))
wait_for_requests
expect
(
page
).
to
have_content
(
'Another commit'
)
expect
(
page
).
to
have_content
(
"From
#{
forked_project
.
full_path
}
"
)
expect
(
page
).
to
have_content
(
"into
#{
project2
.
full_path
}
"
)
end
it_behaves_like
'unavailable for an archived project'
do
let
(
:project
)
{
project2
}
end
end
end
end
end
end
spec/frontend/vue_shared/components/actions_button_spec.js
View file @
d8458c4d
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
GlDropdown
,
Gl
Link
}
from
'
@gitlab/ui
'
;
import
{
GlDropdown
,
Gl
Button
}
from
'
@gitlab/ui
'
;
import
{
createMockDirective
,
getBinding
}
from
'
helpers/vue_mock_directive
'
;
import
ActionsButton
from
'
~/vue_shared/components/actions_button.vue
'
;
...
...
@@ -9,7 +9,12 @@ const TEST_ACTION = {
secondaryText
:
'
Lorem ipsum.
'
,
tooltip
:
''
,
href
:
'
/sample
'
,
attrs
:
{
'
data-test
'
:
'
123
'
},
attrs
:
{
'
data-test
'
:
'
123
'
,
category
:
'
secondary
'
,
href
:
'
/sample
'
,
variant
:
'
default
'
,
},
};
const
TEST_ACTION_2
=
{
key
:
'
action2
'
,
...
...
@@ -40,8 +45,8 @@ describe('Actions button component', () => {
return
directiveBinding
.
value
;
};
const
find
Link
=
()
=>
wrapper
.
find
(
GlLink
);
const
find
LinkTooltip
=
()
=>
getTooltip
(
findLink
());
const
find
Button
=
()
=>
wrapper
.
find
(
GlButton
);
const
find
ButtonTooltip
=
()
=>
getTooltip
(
findButton
());
const
findDropdown
=
()
=>
wrapper
.
find
(
GlDropdown
);
const
findDropdownTooltip
=
()
=>
getTooltip
(
findDropdown
());
const
parseDropdownItems
=
()
=>
...
...
@@ -63,7 +68,7 @@ describe('Actions button component', () => {
};
});
const
clickOn
=
(
child
,
evt
=
new
Event
(
'
click
'
))
=>
child
.
vm
.
$emit
(
'
click
'
,
evt
);
const
clickLink
=
(...
args
)
=>
clickOn
(
find
Link
(),
...
args
);
const
clickLink
=
(...
args
)
=>
clickOn
(
find
Button
(),
...
args
);
const
clickDropdown
=
(...
args
)
=>
clickOn
(
findDropdown
(),
...
args
);
describe
(
'
with 1 action
'
,
()
=>
{
...
...
@@ -76,22 +81,19 @@ describe('Actions button component', () => {
});
it
(
'
should render single button
'
,
()
=>
{
const
link
=
findLink
();
expect
(
link
.
attributes
()).
toEqual
({
class
:
expect
.
any
(
String
),
expect
(
findButton
().
attributes
()).
toMatchObject
({
href
:
TEST_ACTION
.
href
,
...
TEST_ACTION
.
attrs
,
});
expect
(
link
.
text
()).
toBe
(
TEST_ACTION
.
text
);
expect
(
findButton
()
.
text
()).
toBe
(
TEST_ACTION
.
text
);
});
it
(
'
should have tooltip
'
,
()
=>
{
expect
(
find
Link
Tooltip
()).
toBe
(
TEST_ACTION
.
tooltip
);
expect
(
find
Button
Tooltip
()).
toBe
(
TEST_ACTION
.
tooltip
);
});
it
(
'
should have attrs
'
,
()
=>
{
expect
(
find
Link
().
attributes
()).
toMatchObject
(
TEST_ACTION
.
attrs
);
expect
(
find
Button
().
attributes
()).
toMatchObject
(
TEST_ACTION
.
attrs
);
});
it
(
'
can click
'
,
()
=>
{
...
...
@@ -103,7 +105,7 @@ describe('Actions button component', () => {
it
(
'
should have tooltip
'
,
()
=>
{
createComponent
({
actions
:
[{
...
TEST_ACTION
,
tooltip
:
TEST_TOOLTIP
}]
});
expect
(
find
Link
Tooltip
()).
toBe
(
TEST_TOOLTIP
);
expect
(
find
Button
Tooltip
()).
toBe
(
TEST_TOOLTIP
);
});
});
...
...
spec/frontend/vue_shared/components/web_ide_link_spec.js
View file @
d8458c4d
...
...
@@ -3,9 +3,27 @@ import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
import
WebIdeLink
from
'
~/vue_shared/components/web_ide_link.vue
'
;
import
ActionsButton
from
'
~/vue_shared/components/actions_button.vue
'
;
const
TEST_EDIT_URL
=
'
/gitlab-test/test/-/edit/master/
'
;
const
TEST_WEB_IDE_URL
=
'
/-/ide/project/gitlab-test/test/edit/master/-/
'
;
const
TEST_GITPOD_URL
=
'
https://gitpod.test/
'
;
const
ACTION_EDIT
=
{
href
:
TEST_EDIT_URL
,
key
:
'
edit
'
,
text
:
'
Edit
'
,
secondaryText
:
'
Edit this file only.
'
,
tooltip
:
''
,
attrs
:
{
'
data-qa-selector
'
:
'
edit_button
'
,
'
data-track-event
'
:
'
click_edit
'
,
'
data-track-label
'
:
'
Edit
'
,
},
};
const
ACTION_EDIT_CONFIRM_FORK
=
{
...
ACTION_EDIT
,
href
:
'
#modal-confirm-fork-edit
'
,
handle
:
expect
.
any
(
Function
),
};
const
ACTION_WEB_IDE
=
{
href
:
TEST_WEB_IDE_URL
,
key
:
'
webide
'
,
...
...
@@ -14,13 +32,16 @@ const ACTION_WEB_IDE = {
text
:
'
Web IDE
'
,
attrs
:
{
'
data-qa-selector
'
:
'
web_ide_button
'
,
'
data-track-event
'
:
'
click_edit_ide
'
,
'
data-track-label
'
:
'
Web IDE
'
,
},
};
const
ACTION_WEB_IDE_FORK
=
{
const
ACTION_WEB_IDE_
CONFIRM_
FORK
=
{
...
ACTION_WEB_IDE
,
href
:
'
#modal-confirm-fork
'
,
href
:
'
#modal-confirm-fork
-webide
'
,
handle
:
expect
.
any
(
Function
),
};
const
ACTION_WEB_IDE_EDIT_FORK
=
{
...
ACTION_WEB_IDE
,
text
:
'
Edit fork in Web IDE
'
};
const
ACTION_GITPOD
=
{
href
:
TEST_GITPOD_URL
,
key
:
'
gitpod
'
,
...
...
@@ -43,6 +64,7 @@ describe('Web IDE link component', () => {
function
createComponent
(
props
)
{
wrapper
=
shallowMount
(
WebIdeLink
,
{
propsData
:
{
editUrl
:
TEST_EDIT_URL
,
webIdeUrl
:
TEST_WEB_IDE_URL
,
gitpodUrl
:
TEST_GITPOD_URL
,
...
props
,
...
...
@@ -57,15 +79,36 @@ describe('Web IDE link component', () => {
const
findActionsButton
=
()
=>
wrapper
.
find
(
ActionsButton
);
const
findLocalStorageSync
=
()
=>
wrapper
.
find
(
LocalStorageSync
);
it
.
each
`
props | expectedActions
${{}}
|
$
{[
ACTION_WEB_IDE
]}
${{
webIdeIsFork
:
true
}
} |
${[{
...
ACTION_WEB_IDE
,
text
:
'
Edit fork in Web IDE
'
}]}
${{
needsToFork
:
true
}
} |
${[
ACTION_WEB_IDE_FORK
]}
${{
showWebIdeButton
:
false
,
showGitpodButton
:
true
,
gitpodEnabled
:
true
}
} |
${[
ACTION_GITPOD
]}
${{
showWebIdeButton
:
false
,
showGitpodButton
:
true
,
gitpodEnabled
:
false
}
} |
${[
ACTION_GITPOD_ENABLE
]}
${{
showGitpodButton
:
true
,
gitpodEnabled
:
false
}
} |
${[
ACTION_WEB_IDE
,
ACTION_GITPOD_ENABLE
]}
`
(
'
renders actions with props=$props
'
,
({
props
,
expectedActions
})
=>
{
it
.
each
([
{
props
:
{},
expectedActions
:
[
ACTION_WEB_IDE
,
ACTION_EDIT
],
},
{
props
:
{
isFork
:
true
},
expectedActions
:
[
ACTION_WEB_IDE_EDIT_FORK
,
ACTION_EDIT
],
},
{
props
:
{
needsToFork
:
true
},
expectedActions
:
[
ACTION_WEB_IDE_CONFIRM_FORK
,
ACTION_EDIT_CONFIRM_FORK
],
},
{
props
:
{
showWebIdeButton
:
false
,
showGitpodButton
:
true
,
gitpodEnabled
:
true
},
expectedActions
:
[
ACTION_EDIT
,
ACTION_GITPOD
],
},
{
props
:
{
showWebIdeButton
:
false
,
showGitpodButton
:
true
,
gitpodEnabled
:
false
},
expectedActions
:
[
ACTION_EDIT
,
ACTION_GITPOD_ENABLE
],
},
{
props
:
{
showGitpodButton
:
true
,
gitpodEnabled
:
false
},
expectedActions
:
[
ACTION_WEB_IDE
,
ACTION_EDIT
,
ACTION_GITPOD_ENABLE
],
},
{
props
:
{
showEditButton
:
false
},
expectedActions
:
[
ACTION_WEB_IDE
],
},
])(
'
renders actions with appropriately for given props
'
,
({
props
,
expectedActions
})
=>
{
createComponent
(
props
);
expect
(
findActionsButton
().
props
(
'
actions
'
)).
toEqual
(
expectedActions
);
...
...
@@ -73,7 +116,12 @@ describe('Web IDE link component', () => {
describe
(
'
with multiple actions
'
,
()
=>
{
beforeEach
(()
=>
{
createComponent
({
showWebIdeButton
:
true
,
showGitpodButton
:
true
,
gitpodEnabled
:
true
});
createComponent
({
showEditButton
:
false
,
showWebIdeButton
:
true
,
showGitpodButton
:
true
,
gitpodEnabled
:
true
,
});
});
it
(
'
selected Web IDE by default
'
,
()
=>
{
...
...
spec/helpers/blob_helper_spec.rb
View file @
d8458c4d
...
...
@@ -445,13 +445,14 @@ RSpec.describe BlobHelper do
end
describe
'#ide_fork_and_edit_path'
do
let
(
:project
)
{
create
(
:project
)
}
let
(
:current_user
)
{
create
(
:user
)
}
let
(
:can_push_code
)
{
true
}
let_it_be
(
:project
)
{
create
(
:project
)
}
let_it_be
(
:user
)
{
create
(
:user
)
}
let
(
:current_user
)
{
user
}
before
do
allow
(
helper
).
to
receive
(
:current_user
).
and_return
(
current_user
)
allow
(
helper
).
to
receive
(
:can?
).
and_return
(
can_push_cod
e
)
allow
(
helper
).
to
receive
(
:can?
).
and_return
(
tru
e
)
end
it
'returns path to fork the repo with a redirect param to the full IDE path'
do
...
...
@@ -472,6 +473,35 @@ RSpec.describe BlobHelper do
end
end
describe
'#fork_and_edit_path'
do
let_it_be
(
:project
)
{
create
(
:project
)
}
let_it_be
(
:user
)
{
create
(
:user
)
}
let
(
:current_user
)
{
user
}
before
do
allow
(
helper
).
to
receive
(
:current_user
).
and_return
(
current_user
)
allow
(
helper
).
to
receive
(
:can?
).
and_return
(
true
)
end
it
'returns path to fork the repo with a redirect param to the full edit path'
do
uri
=
URI
(
helper
.
fork_and_edit_path
(
project
,
"master"
,
""
))
params
=
CGI
.
unescape
(
uri
.
query
)
expect
(
uri
.
path
).
to
eq
(
"/
#{
project
.
namespace
.
path
}
/
#{
project
.
path
}
/-/forks"
)
expect
(
params
).
to
include
(
"continue[to]=/
#{
project
.
namespace
.
path
}
/
#{
project
.
path
}
/-/edit/master/"
)
expect
(
params
).
to
include
(
"namespace_key=
#{
current_user
.
namespace
.
id
}
"
)
end
context
'when user is not logged in'
do
let
(
:current_user
)
{
nil
}
it
'returns nil'
do
expect
(
helper
.
ide_fork_and_edit_path
(
project
,
"master"
,
""
)).
to
be_nil
end
end
end
describe
'#editing_ci_config?'
do
let
(
:project
)
{
build
(
:project
)
}
...
...
spec/helpers/tree_helper_spec.rb
View file @
d8458c4d
...
...
@@ -167,31 +167,60 @@ RSpec.describe TreeHelper do
end
end
describe
'#vue_ide_link_data'
do
describe
'#web_ide_button_data'
do
let
(
:blob
)
{
project
.
repository
.
blob_at
(
'refs/heads/master'
,
@path
)
}
before
do
@path
=
''
@project
=
project
@ref
=
sha
allow
(
helper
).
to
receive
(
:current_user
).
and_return
(
nil
)
allow
(
helper
).
to
receive
(
:can_collaborate_with_project?
).
and_return
(
true
)
allow
(
helper
).
to
receive
(
:can?
).
and_return
(
true
)
end
subject
{
helper
.
vue_ide_link_data
(
project
,
sha
)
}
subject
{
helper
.
web_ide_button_data
(
blob:
blob
)
}
it
'returns a list of attributes related to the project'
do
expect
(
subject
).
to
include
(
web_ide_url_data:
{
path:
project
.
full_path
,
is_fork:
false
},
project_path:
project
.
full_path
,
ref:
sha
,
is_fork:
false
,
needs_to_fork:
false
,
gitpod_enabled:
false
,
is_blob:
false
,
show_edit_button:
false
,
show_web_ide_button:
true
,
show_gitpod_button:
false
,
gitpod_url:
""
,
gitpod_enabled:
nil
edit_url:
''
,
web_ide_url:
"/-/ide/project/
#{
project
.
full_path
}
/edit/
#{
sha
}
"
,
gitpod_url:
''
)
end
context
'a blob is passed'
do
before
do
@path
=
'README.md'
end
it
'returns edit url and webide url for the blob'
do
expect
(
subject
).
to
include
(
show_edit_button:
true
,
edit_url:
"/
#{
project
.
full_path
}
/-/edit/
#{
sha
}
/
#{
@path
}
"
,
web_ide_url:
"/-/ide/project/
#{
project
.
full_path
}
/edit/
#{
sha
}
/-/
#{
@path
}
"
)
end
end
context
'user does not have write access but a personal fork exists'
do
include
ProjectForksHelper
let_it_be
(
:user
)
{
create
(
:user
)
}
let
!
(
:forked_project
)
{
create
(
:project
,
:repository
,
namespace:
user
.
namespace
)
}
let
(
:forked_project
)
{
create
(
:project
,
:repository
,
namespace:
user
.
namespace
)
}
before
do
project
.
add_guest
(
user
)
...
...
@@ -200,9 +229,49 @@ RSpec.describe TreeHelper do
allow
(
helper
).
to
receive
(
:current_user
).
and_return
(
user
)
end
it
'includes web_ide_url_data: forked_project.full_path'
do
it
'includes forked project path as project_path'
do
expect
(
subject
).
to
include
(
project_path:
forked_project
.
full_path
,
is_fork:
true
,
needs_to_fork:
false
,
show_edit_button:
false
,
web_ide_url:
"/-/ide/project/
#{
forked_project
.
full_path
}
/edit/
#{
sha
}
"
)
end
context
'a blob is passed'
do
before
do
@path
=
'README.md'
end
it
'returns edit url and web ide for the blob in the fork'
do
expect
(
subject
).
to
include
(
is_blob:
true
,
show_edit_button:
true
,
# edit urls are automatically redirected to the fork
edit_url:
"/
#{
project
.
full_path
}
/-/edit/
#{
sha
}
/
#{
@path
}
"
,
web_ide_url:
"/-/ide/project/
#{
forked_project
.
full_path
}
/edit/
#{
sha
}
/-/
#{
@path
}
"
)
end
end
end
context
'for archived project'
do
before
do
allow
(
helper
).
to
receive
(
:can_collaborate_with_project?
).
and_return
(
false
)
allow
(
helper
).
to
receive
(
:can?
).
and_return
(
false
)
project
.
update!
(
archived:
true
)
@path
=
'README.md'
end
it
'does not show any buttons'
do
expect
(
subject
).
to
include
(
web_ide_url_data:
{
path:
forked_project
.
full_path
,
is_fork:
true
}
is_blob:
true
,
show_edit_button:
false
,
show_web_ide_button:
false
,
show_gitpod_button:
false
)
end
end
...
...
@@ -216,11 +285,32 @@ RSpec.describe TreeHelper do
allow
(
helper
).
to
receive
(
:current_user
).
and_return
(
user
)
end
it
'includes
web_ide_url_data: project.full
_path'
do
it
'includes
original project path as project
_path'
do
expect
(
subject
).
to
include
(
web_ide_url_data:
{
path:
project
.
full_path
,
is_fork:
false
}
project_path:
project
.
full_path
,
is_fork:
false
,
needs_to_fork:
false
,
show_edit_button:
false
,
web_ide_url:
"/-/ide/project/
#{
project
.
full_path
}
/edit/
#{
sha
}
"
)
end
context
'a blob is passed'
do
before
do
@path
=
'README.md'
end
it
'returns edit url and web ide for the blob in the fork'
do
expect
(
subject
).
to
include
(
is_blob:
true
,
show_edit_button:
true
,
edit_url:
"/
#{
project
.
full_path
}
/-/edit/
#{
sha
}
/
#{
@path
}
"
,
web_ide_url:
"/-/ide/project/
#{
project
.
full_path
}
/edit/
#{
sha
}
/-/
#{
@path
}
"
)
end
end
end
context
'gitpod feature is enabled'
do
...
...
spec/support/helpers/features/blob_spec_helpers.rb
0 → 100644
View file @
d8458c4d
# frozen_string_literal: true
# These helpers help you interact within the blobs page and blobs edit page (Single file editor).
module
BlobSpecHelpers
include
ActionView
::
Helpers
::
JavaScriptHelper
def
set_default_button
(
type
)
evaluate_script
(
"localStorage.setItem('gl-web-ide-button-selected', '
#{
type
}
')"
)
end
def
unset_default_button
set_default_button
(
''
)
end
def
editor_value
evaluate_script
(
'monaco.editor.getModels()[0].getValue()'
)
end
def
set_editor_value
(
value
)
execute_script
(
"monaco.editor.getModels()[0].setValue('
#{
value
}
')"
)
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment