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
0
Merge Requests
0
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
Boxiang Sun
gitlab-ce
Commits
d77181d5
Commit
d77181d5
authored
Jan 27, 2018
by
Matija Čupić
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into persistent-callouts
parents
860c7c4b
dc325c67
Changes
26
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
295 additions
and
173 deletions
+295
-173
app/assets/javascripts/clusters/clusters_bundle.js
app/assets/javascripts/clusters/clusters_bundle.js
+2
-10
app/assets/javascripts/clusters/clusters_index.js
app/assets/javascripts/clusters/clusters_index.js
+15
-53
app/assets/javascripts/toggle_buttons.js
app/assets/javascripts/toggle_buttons.js
+61
-0
app/models/project.rb
app/models/project.rb
+3
-0
app/models/project_services/emails_on_push_service.rb
app/models/project_services/emails_on_push_service.rb
+1
-1
app/models/project_services/irker_service.rb
app/models/project_services/irker_service.rb
+1
-1
app/models/project_services/pipelines_email_service.rb
app/models/project_services/pipelines_email_service.rb
+1
-1
app/models/service.rb
app/models/service.rb
+6
-0
app/views/help/index.html.haml
app/views/help/index.html.haml
+9
-8
app/views/projects/clusters/_cluster.html.haml
app/views/projects/clusters/_cluster.html.haml
+3
-2
app/views/projects/clusters/_integration_form.html.haml
app/views/projects/clusters/_integration_form.html.haml
+3
-4
app/workers/repository_import_worker.rb
app/workers/repository_import_worker.rb
+9
-1
changelogs/unreleased/42327-import-from-gitlab-com-fails-destination-already-exists-and-is-not-an-empty-directory-error.yml
...on-already-exists-and-is-not-an-empty-directory-error.yml
+6
-0
changelogs/unreleased/cs-fix-commercial-content-check.yml
changelogs/unreleased/cs-fix-commercial-content-check.yml
+6
-0
lib/gitlab/import_export/shared.rb
lib/gitlab/import_export/shared.rb
+6
-1
spec/features/projects/clusters/gcp_spec.rb
spec/features/projects/clusters/gcp_spec.rb
+1
-1
spec/features/projects/clusters/user_spec.rb
spec/features/projects/clusters/user_spec.rb
+1
-1
spec/features/projects/clusters_spec.rb
spec/features/projects/clusters_spec.rb
+3
-3
spec/javascripts/clusters/clusters_bundle_spec.js
spec/javascripts/clusters/clusters_bundle_spec.js
+16
-8
spec/javascripts/clusters/clusters_index_spec.js
spec/javascripts/clusters/clusters_index_spec.js
+0
-58
spec/javascripts/fixtures/clusters.rb
spec/javascripts/fixtures/clusters.rb
+0
-15
spec/javascripts/toggle_buttons_spec.js
spec/javascripts/toggle_buttons_spec.js
+120
-0
spec/lib/gitlab/import_export/project.json
spec/lib/gitlab/import_export/project.json
+1
-1
spec/lib/gitlab/import_export/project_tree_saver_spec.rb
spec/lib/gitlab/import_export/project_tree_saver_spec.rb
+5
-1
spec/requests/api/issues_spec.rb
spec/requests/api/issues_spec.rb
+2
-2
spec/workers/repository_import_worker_spec.rb
spec/workers/repository_import_worker_spec.rb
+14
-1
No files found.
app/assets/javascripts/clusters/clusters_bundle.js
View file @
d77181d5
...
...
@@ -14,6 +14,7 @@ import {
import
ClustersService
from
'
./services/clusters_service
'
;
import
ClustersStore
from
'
./stores/clusters_store
'
;
import
applications
from
'
./components/applications.vue
'
;
import
setupToggleButtons
from
'
../toggle_buttons
'
;
/**
* Cluster page has 2 separate parts:
...
...
@@ -48,12 +49,9 @@ export default class Clusters {
installPrometheusEndpoint
:
installPrometheusPath
,
});
this
.
toggle
=
this
.
toggle
.
bind
(
this
);
this
.
installApplication
=
this
.
installApplication
.
bind
(
this
);
this
.
showToken
=
this
.
showToken
.
bind
(
this
);
this
.
toggleButton
=
document
.
querySelector
(
'
.js-toggle-cluster
'
);
this
.
toggleInput
=
document
.
querySelector
(
'
.js-toggle-input
'
);
this
.
errorContainer
=
document
.
querySelector
(
'
.js-cluster-error
'
);
this
.
successContainer
=
document
.
querySelector
(
'
.js-cluster-success
'
);
this
.
creatingContainer
=
document
.
querySelector
(
'
.js-cluster-creating
'
);
...
...
@@ -63,6 +61,7 @@ export default class Clusters {
this
.
tokenField
=
document
.
querySelector
(
'
.js-cluster-token
'
);
initSettingsPanels
();
setupToggleButtons
(
document
.
querySelector
(
'
.js-cluster-enable-toggle-area
'
));
this
.
initApplications
();
if
(
this
.
store
.
state
.
status
!==
'
created
'
)
{
...
...
@@ -101,13 +100,11 @@ export default class Clusters {
}
addListeners
()
{
this
.
toggleButton
.
addEventListener
(
'
click
'
,
this
.
toggle
);
if
(
this
.
showTokenButton
)
this
.
showTokenButton
.
addEventListener
(
'
click
'
,
this
.
showToken
);
eventHub
.
$on
(
'
installApplication
'
,
this
.
installApplication
);
}
removeListeners
()
{
this
.
toggleButton
.
removeEventListener
(
'
click
'
,
this
.
toggle
);
if
(
this
.
showTokenButton
)
this
.
showTokenButton
.
removeEventListener
(
'
click
'
,
this
.
showToken
);
eventHub
.
$off
(
'
installApplication
'
,
this
.
installApplication
);
}
...
...
@@ -151,11 +148,6 @@ export default class Clusters {
this
.
updateContainer
(
prevStatus
,
this
.
store
.
state
.
status
,
this
.
store
.
state
.
statusReason
);
}
toggle
()
{
this
.
toggleButton
.
classList
.
toggle
(
'
is-checked
'
);
this
.
toggleInput
.
setAttribute
(
'
value
'
,
this
.
toggleButton
.
classList
.
contains
(
'
is-checked
'
).
toString
());
}
showToken
()
{
const
type
=
this
.
tokenField
.
getAttribute
(
'
type
'
);
...
...
app/assets/javascripts/clusters/clusters_index.js
View file @
d77181d5
import
Flash
from
'
../flash
'
;
import
{
s__
}
from
'
../locale
'
;
import
setupToggleButtons
from
'
../toggle_buttons
'
;
import
ClustersService
from
'
./services/clusters_service
'
;
/**
* Toggles loading and disabled classes.
* @param {HTMLElement} button
*/
const
toggleLoadingButton
=
(
button
)
=>
{
if
(
button
.
getAttribute
(
'
disabled
'
))
{
button
.
removeAttribute
(
'
disabled
'
);
}
else
{
button
.
setAttribute
(
'
disabled
'
,
true
);
}
button
.
classList
.
toggle
(
'
is-loading
'
);
};
/**
* Toggles checked class for the given button
* @param {HTMLElement} button
*/
const
toggleValue
=
(
button
)
=>
{
button
.
classList
.
toggle
(
'
is-checked
'
);
export
default
()
=>
{
const
clusterList
=
document
.
querySelector
(
'
.js-clusters-list
'
);
// The empty state won't have a clusterList
if
(
clusterList
)
{
setupToggleButtons
(
document
.
querySelector
(
'
.js-clusters-list
'
),
(
value
,
toggle
)
=>
ClustersService
.
updateCluster
(
toggle
.
dataset
.
endpoint
,
{
cluster
:
{
enabled
:
value
}
})
.
catch
((
err
)
=>
{
Flash
(
s__
(
'
ClusterIntegration|Something went wrong on our end.
'
));
throw
err
;
}),
);
}
};
/**
* Handles toggle buttons in the cluster's table.
*
* When the user clicks the toggle button for each cluster, it:
* - toggles the button
* - shows a loading and disables button
* - Makes a put request to the given endpoint
* Once we receive the response, either:
* 1) Show updated status in case of successfull response
* 2) Show initial status in case of failed response
*/
export
default
function
setClusterTableToggles
()
{
document
.
querySelectorAll
(
'
.js-toggle-cluster-list
'
)
.
forEach
(
button
=>
button
.
addEventListener
(
'
click
'
,
(
e
)
=>
{
const
toggleButton
=
e
.
currentTarget
;
const
endpoint
=
toggleButton
.
getAttribute
(
'
data-endpoint
'
);
toggleValue
(
toggleButton
);
toggleLoadingButton
(
toggleButton
);
const
value
=
toggleButton
.
classList
.
contains
(
'
is-checked
'
);
ClustersService
.
updateCluster
(
endpoint
,
{
cluster
:
{
enabled
:
value
}
})
.
then
(()
=>
{
toggleLoadingButton
(
toggleButton
);
})
.
catch
(()
=>
{
toggleLoadingButton
(
toggleButton
);
toggleValue
(
toggleButton
);
Flash
(
s__
(
'
ClusterIntegration|Something went wrong on our end.
'
));
});
}));
}
app/assets/javascripts/toggle_buttons.js
0 → 100644
View file @
d77181d5
import
$
from
'
jquery
'
;
import
Flash
from
'
./flash
'
;
import
{
__
}
from
'
./locale
'
;
import
{
convertPermissionToBoolean
}
from
'
./lib/utils/common_utils
'
;
/*
example HAML:
```
%button.js-project-feature-toggle.project-feature-toggle{ type: "button",
class: "#{'is-checked' if enabled?}",
'aria-label': _('Toggle Cluster') }
%input{ type: "hidden", class: 'js-project-feature-toggle-input', value: enabled? }
```
*/
function
updatetoggle
(
toggle
,
isOn
)
{
toggle
.
classList
.
toggle
(
'
is-checked
'
,
isOn
);
}
function
onToggleClicked
(
toggle
,
input
,
clickCallback
)
{
const
previousIsOn
=
convertPermissionToBoolean
(
input
.
value
);
// Visually change the toggle and start loading
updatetoggle
(
toggle
,
!
previousIsOn
);
toggle
.
setAttribute
(
'
disabled
'
,
true
);
toggle
.
classList
.
toggle
(
'
is-loading
'
,
true
);
Promise
.
resolve
(
clickCallback
(
!
previousIsOn
,
toggle
))
.
then
(()
=>
{
// Actually change the input value
input
.
setAttribute
(
'
value
'
,
!
previousIsOn
);
})
.
catch
(()
=>
{
// Revert the visuals if something goes wrong
updatetoggle
(
toggle
,
previousIsOn
);
})
.
then
(()
=>
{
// Remove the loading indicator in any case
toggle
.
removeAttribute
(
'
disabled
'
);
toggle
.
classList
.
toggle
(
'
is-loading
'
,
false
);
$
(
input
).
trigger
(
'
trigger-change
'
);
})
.
catch
(()
=>
{
Flash
(
__
(
'
Something went wrong when toggling the button
'
));
});
}
export
default
function
setupToggleButtons
(
container
,
clickCallback
=
()
=>
{})
{
const
toggles
=
container
.
querySelectorAll
(
'
.js-project-feature-toggle
'
);
toggles
.
forEach
((
toggle
)
=>
{
const
input
=
toggle
.
querySelector
(
'
.js-project-feature-toggle-input
'
);
const
isOn
=
convertPermissionToBoolean
(
input
.
value
);
// Get the visible toggle in sync with the hidden input
updatetoggle
(
toggle
,
isOn
);
toggle
.
addEventListener
(
'
click
'
,
onToggleClicked
.
bind
(
null
,
toggle
,
input
,
clickCallback
));
});
}
app/models/project.rb
View file @
d77181d5
...
...
@@ -568,6 +568,9 @@ class Project < ActiveRecord::Base
RepositoryForkWorker
.
perform_async
(
id
,
forked_from_project
.
repository_storage_path
,
forked_from_project
.
disk_path
)
elsif
gitlab_project_import?
# Do not retry on Import/Export until https://gitlab.com/gitlab-org/gitlab-ce/issues/26189 is solved.
RepositoryImportWorker
.
set
(
retry:
false
).
perform_async
(
self
.
id
)
else
RepositoryImportWorker
.
perform_async
(
self
.
id
)
end
...
...
app/models/project_services/emails_on_push_service.rb
View file @
d77181d5
...
...
@@ -2,7 +2,7 @@ class EmailsOnPushService < Service
boolean_accessor
:send_from_committer_email
boolean_accessor
:disable_diffs
prop_accessor
:recipients
validates
:recipients
,
presence:
true
,
if: :
activated
?
validates
:recipients
,
presence:
true
,
if: :
valid_recipients
?
def
title
'Emails on push'
...
...
app/models/project_services/irker_service.rb
View file @
d77181d5
...
...
@@ -4,7 +4,7 @@ class IrkerService < Service
prop_accessor
:server_host
,
:server_port
,
:default_irc_uri
prop_accessor
:recipients
,
:channels
boolean_accessor
:colorize_messages
validates
:recipients
,
presence:
true
,
if: :
activated
?
validates
:recipients
,
presence:
true
,
if: :
valid_recipients
?
before_validation
:get_channels
...
...
app/models/project_services/pipelines_email_service.rb
View file @
d77181d5
class
PipelinesEmailService
<
Service
prop_accessor
:recipients
boolean_accessor
:notify_only_broken_pipelines
validates
:recipients
,
presence:
true
,
if: :
activated
?
validates
:recipients
,
presence:
true
,
if: :
valid_recipients
?
def
initialize_properties
self
.
properties
||=
{
notify_only_broken_pipelines:
true
}
...
...
app/models/service.rb
View file @
d77181d5
...
...
@@ -2,6 +2,8 @@
# and implement a set of methods
class
Service
<
ActiveRecord
::
Base
include
Sortable
include
Importable
serialize
:properties
,
JSON
# rubocop:disable Cop/ActiveRecordSerialize
default_value_for
:active
,
false
...
...
@@ -295,4 +297,8 @@ class Service < ActiveRecord::Base
project
.
cache_has_external_wiki
end
end
def
valid_recipients?
activated?
&&
!
importing?
end
end
app/views/help/index.html.haml
View file @
d77181d5
...
...
@@ -5,15 +5,16 @@
=
markdown_field
(
current_application_settings
,
:help_page_text
)
%hr
-
unless
current_application_settings
.
help_page_hide_commercial_content?
%h1
GitLab
Community Edition
-
if
user_signed_in?
%span
=
Gitlab
::
VERSION
%small
=
link_to
Gitlab
::
REVISION
,
Gitlab
::
COM_URL
+
namespace_project_commits_path
(
'gitlab-org'
,
'gitlab-ce'
,
Gitlab
::
REVISION
)
=
version_status_badge
%h1
GitLab
Community Edition
-
if
user_signed_in?
%span
=
Gitlab
::
VERSION
%small
=
link_to
Gitlab
::
REVISION
,
Gitlab
::
COM_URL
+
namespace_project_commits_path
(
'gitlab-org'
,
'gitlab-ce'
,
Gitlab
::
REVISION
)
=
version_status_badge
%hr
-
unless
current_application_settings
.
help_page_hide_commercial_content?
%p
.slead
GitLab is open source software to collaborate on code.
%br
...
...
app/views/projects/clusters/_cluster.html.haml
View file @
d77181d5
...
...
@@ -12,11 +12,12 @@
.table-section.section-10
.table-mobile-header
{
role:
"rowheader"
}
.table-mobile-content
%button
{
type:
"button"
,
class:
"
js-toggle-cluster-list project-feature-toggle
#{'is-checked' if cluster.enabled?} #{'is-disabled' if !cluster.can_toggle_cluster?}"
,
%button
.js-project-feature-toggle.project-feature-toggle
{
type:
"button"
,
class:
"#{'is-checked' if cluster.enabled?} #{'is-disabled' if !cluster.can_toggle_cluster?}"
,
"aria-label"
:
s_
(
"ClusterIntegration|Toggle Cluster"
),
disabled:
!
cluster
.
can_toggle_cluster?
,
data:
{
endpoint:
namespace_project_cluster_path
(
@project
.
namespace
,
@project
,
cluster
,
format: :json
)
}
}
%input
.js-project-feature-toggle-input
{
type:
"hidden"
,
value:
cluster
.
enabled?
}
=
icon
(
"spinner spin"
,
class:
"loading-icon"
)
%span
.toggle-icon
=
sprite_icon
(
'status_success_borderless'
,
size:
16
,
css_class:
'toggle-icon-svg toggle-status-checked'
)
...
...
app/views/projects/clusters/_integration_form.html.haml
View file @
d77181d5
...
...
@@ -10,13 +10,12 @@
=
s_
(
'ClusterIntegration|Cluster integration is enabled for this project.'
)
-
else
=
s_
(
'ClusterIntegration|Cluster integration is disabled for this project.'
)
%label
.append-bottom-10
=
field
.
hidden_field
:enabled
,
{
class:
'js-toggle-input'
}
%label
.append-bottom-10.js-cluster-enable-toggle-area
%button
{
type:
'button'
,
class:
"js-
toggle-cluster project-feature-toggle #{'is-checked' unless !
@cluster.enabled?} #{'is-disabled' unless can?(current_user, :update_cluster, @cluster)}"
,
class:
"js-
project-feature-toggle project-feature-toggle #{'is-checked' if
@cluster.enabled?} #{'is-disabled' unless can?(current_user, :update_cluster, @cluster)}"
,
"aria-label"
:
s_
(
"ClusterIntegration|Toggle Cluster"
),
disabled:
!
can?
(
current_user
,
:update_cluster
,
@cluster
)
}
=
field
.
hidden_field
:enabled
,
{
class:
'js-project-feature-toggle-input'
}
%span
.toggle-icon
=
sprite_icon
(
'status_success_borderless'
,
size:
16
,
css_class:
'toggle-icon-svg toggle-status-checked'
)
=
sprite_icon
(
'status_failed_borderless'
,
size:
16
,
css_class:
'toggle-icon-svg toggle-status-unchecked'
)
...
...
app/workers/repository_import_worker.rb
View file @
d77181d5
...
...
@@ -20,7 +20,11 @@ class RepositoryImportWorker
# to those importers to mark the import process as complete.
return
if
service
.
async?
raise
result
[
:message
]
if
result
[
:status
]
==
:error
if
result
[
:status
]
==
:error
fail_import
(
project
,
result
[
:message
])
if
project
.
gitlab_project_import?
raise
result
[
:message
]
end
project
.
after_import
end
...
...
@@ -33,4 +37,8 @@ class RepositoryImportWorker
Rails
.
logger
.
info
(
"Project
#{
project
.
full_path
}
was in inconsistent state (
#{
project
.
import_status
}
) while importing."
)
false
end
def
fail_import
(
project
,
message
)
project
.
mark_import_as_failed
(
message
)
end
end
changelogs/unreleased/42327-import-from-gitlab-com-fails-destination-already-exists-and-is-not-an-empty-directory-error.yml
0 → 100644
View file @
d77181d5
---
title
:
Fixes destination already exists, and some particular service errors on Import/Export
error
merge_request
:
16714
author
:
type
:
fixed
changelogs/unreleased/cs-fix-commercial-content-check.yml
0 → 100644
View file @
d77181d5
---
title
:
Fix version information not showing on help page if commercial content display
was disabled.
merge_request
:
16743
author
:
type
:
fixed
lib/gitlab/import_export/shared.rb
View file @
d77181d5
...
...
@@ -19,8 +19,13 @@ module Gitlab
def
error
(
error
)
error_out
(
error
.
message
,
caller
[
0
].
dup
)
@errors
<<
error
.
message
# Debug:
Rails
.
logger
.
error
(
error
.
backtrace
.
join
(
"
\n
"
))
if
error
.
backtrace
Rails
.
logger
.
error
(
"Import/Export backtrace:
#{
error
.
backtrace
.
join
(
"
\n
"
)
}
"
)
else
Rails
.
logger
.
error
(
"No backtrace found"
)
end
end
private
...
...
spec/features/projects/clusters/gcp_spec.rb
View file @
d77181d5
...
...
@@ -95,7 +95,7 @@ feature 'Gcp Cluster', :js do
context
'when user disables the cluster'
do
before
do
page
.
find
(
:css
,
'.js-
toggle-cluster
'
).
click
page
.
find
(
:css
,
'.js-
cluster-enable-toggle-area .js-project-feature-toggle
'
).
click
page
.
within
(
'#cluster-integration'
)
{
click_button
'Save changes'
}
end
...
...
spec/features/projects/clusters/user_spec.rb
View file @
d77181d5
...
...
@@ -62,7 +62,7 @@ feature 'User Cluster', :js do
context
'when user disables the cluster'
do
before
do
page
.
find
(
:css
,
'.js-
toggle-cluster
'
).
click
page
.
find
(
:css
,
'.js-
cluster-enable-toggle-area .js-project-feature-toggle
'
).
click
fill_in
'cluster_name'
,
with:
'dev-cluster'
page
.
within
(
'#cluster-integration'
)
{
click_button
'Save changes'
}
end
...
...
spec/features/projects/clusters_spec.rb
View file @
d77181d5
...
...
@@ -37,13 +37,13 @@ feature 'Clusters', :js do
context
'inline update of cluster'
do
it
'user can update cluster'
do
expect
(
page
).
to
have_selector
(
'.js-
toggle-cluster-list
'
)
expect
(
page
).
to
have_selector
(
'.js-
project-feature-toggle
'
)
end
context
'with sucessfull request'
do
it
'user sees updated cluster'
do
expect
do
page
.
find
(
'.js-
toggle-cluster-list
'
).
click
page
.
find
(
'.js-
project-feature-toggle
'
).
click
wait_for_requests
end
.
to
change
{
cluster
.
reload
.
enabled
}
...
...
@@ -57,7 +57,7 @@ feature 'Clusters', :js do
expect_any_instance_of
(
Clusters
::
UpdateService
).
to
receive
(
:execute
).
and_call_original
allow_any_instance_of
(
Clusters
::
Cluster
).
to
receive
(
:valid?
)
{
false
}
page
.
find
(
'.js-
toggle-cluster-list
'
).
click
page
.
find
(
'.js-
project-feature-toggle
'
).
click
expect
(
page
).
to
have_content
(
'Something went wrong on our end.'
)
expect
(
page
).
to
have_selector
(
'.is-checked'
)
...
...
spec/javascripts/clusters/clusters_bundle_spec.js
View file @
d77181d5
...
...
@@ -23,16 +23,24 @@ describe('Clusters', () => {
});
describe
(
'
toggle
'
,
()
=>
{
it
(
'
should update the button and the input field on click
'
,
()
=>
{
cluster
.
toggleButton
.
click
();
it
(
'
should update the button and the input field on click
'
,
(
done
)
=>
{
const
toggleButton
=
document
.
querySelector
(
'
.js-cluster-enable-toggle-area .js-project-feature-toggle
'
);
const
toggleInput
=
document
.
querySelector
(
'
.js-cluster-enable-toggle-area .js-project-feature-toggle-input
'
);
expect
(
cluster
.
toggleButton
.
classList
,
).
not
.
toContain
(
'
is-checked
'
);
toggleButton
.
click
();
expect
(
cluster
.
toggleInput
.
getAttribute
(
'
value
'
),
).
toEqual
(
'
false
'
);
getSetTimeoutPromise
()
.
then
(()
=>
{
expect
(
toggleButton
.
classList
,
).
not
.
toContain
(
'
is-checked
'
);
expect
(
toggleInput
.
getAttribute
(
'
value
'
),
).
toEqual
(
'
false
'
);
})
.
then
(
done
)
.
catch
(
done
.
fail
);
});
});
...
...
spec/javascripts/clusters/clusters_index_spec.js
deleted
100644 → 0
View file @
860c7c4b
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
setClusterTableToggles
from
'
~/clusters/clusters_index
'
;
import
{
setTimeout
}
from
'
core-js/library/web/timers
'
;
describe
(
'
Clusters table
'
,
()
=>
{
preloadFixtures
(
'
clusters/index_cluster.html.raw
'
);
let
mock
;
beforeEach
(()
=>
{
loadFixtures
(
'
clusters/index_cluster.html.raw
'
);
mock
=
new
MockAdapter
(
axios
);
setClusterTableToggles
();
});
describe
(
'
update cluster
'
,
()
=>
{
it
(
'
renders loading state while request is made
'
,
()
=>
{
const
button
=
document
.
querySelector
(
'
.js-toggle-cluster-list
'
);
button
.
click
();
expect
(
button
.
classList
).
toContain
(
'
is-loading
'
);
expect
(
button
.
getAttribute
(
'
disabled
'
)).
toEqual
(
'
true
'
);
});
afterEach
(()
=>
{
mock
.
restore
();
});
it
(
'
shows updated state after sucessfull request
'
,
(
done
)
=>
{
mock
.
onPut
().
reply
(
200
,
{},
{});
const
button
=
document
.
querySelector
(
'
.js-toggle-cluster-list
'
);
button
.
click
();
expect
(
button
.
classList
).
toContain
(
'
is-loading
'
);
setTimeout
(()
=>
{
expect
(
button
.
classList
).
not
.
toContain
(
'
is-loading
'
);
expect
(
button
.
classList
).
not
.
toContain
(
'
is-checked
'
);
done
();
},
0
);
});
it
(
'
shows inital state after failed request
'
,
(
done
)
=>
{
mock
.
onPut
().
reply
(
500
,
{},
{});
const
button
=
document
.
querySelector
(
'
.js-toggle-cluster-list
'
);
button
.
click
();
expect
(
button
.
classList
).
toContain
(
'
is-loading
'
);
setTimeout
(()
=>
{
expect
(
button
.
classList
).
not
.
toContain
(
'
is-loading
'
);
expect
(
button
.
classList
).
toContain
(
'
is-checked
'
);
done
();
},
0
);
});
});
});
spec/javascripts/fixtures/clusters.rb
View file @
d77181d5
...
...
@@ -31,19 +31,4 @@ describe Projects::ClustersController, '(JavaScript fixtures)', type: :controlle
expect
(
response
).
to
be_success
store_frontend_fixture
(
response
,
example
.
description
)
end
context
'rendering non-empty state'
do
before
do
cluster
end
it
'clusters/index_cluster.html.raw'
do
|
example
|
get
:index
,
namespace_id:
namespace
,
project_id:
project
expect
(
response
).
to
be_success
store_frontend_fixture
(
response
,
example
.
description
)
end
end
end
spec/javascripts/toggle_buttons_spec.js
0 → 100644
View file @
d77181d5
import
setupToggleButtons
from
'
~/toggle_buttons
'
;
import
getSetTimeoutPromise
from
'
./helpers/set_timeout_promise_helper
'
;
function
generateMarkup
(
isChecked
=
true
)
{
return
`
<button type="button" class="
${
isChecked
?
'
is-checked
'
:
''
}
js-project-feature-toggle">
<input type="hidden" class="js-project-feature-toggle-input" value="
${
isChecked
}
" />
</button>
`
;
}
function
setupFixture
(
isChecked
,
clickCallback
)
{
const
wrapper
=
document
.
createElement
(
'
div
'
);
wrapper
.
innerHTML
=
generateMarkup
(
isChecked
);
setupToggleButtons
(
wrapper
,
clickCallback
);
return
wrapper
;
}
describe
(
'
ToggleButtons
'
,
()
=>
{
describe
(
'
when input value is true
'
,
()
=>
{
it
(
'
should initialize as checked
'
,
()
=>
{
const
wrapper
=
setupFixture
(
true
);
expect
(
wrapper
.
querySelector
(
'
.js-project-feature-toggle
'
).
classList
.
contains
(
'
is-checked
'
)).
toEqual
(
true
);
expect
(
wrapper
.
querySelector
(
'
.js-project-feature-toggle-input
'
).
value
).
toEqual
(
'
true
'
);
});
it
(
'
should toggle to unchecked when clicked
'
,
(
done
)
=>
{
const
wrapper
=
setupFixture
(
true
);
const
toggleButton
=
wrapper
.
querySelector
(
'
.js-project-feature-toggle
'
);
toggleButton
.
click
();
getSetTimeoutPromise
()
.
then
(()
=>
{
expect
(
toggleButton
.
classList
.
contains
(
'
is-checked
'
)).
toEqual
(
false
);
expect
(
wrapper
.
querySelector
(
'
.js-project-feature-toggle-input
'
).
value
).
toEqual
(
'
false
'
);
})
.
then
(
done
)
.
catch
(
done
.
fail
);
});
});
describe
(
'
when input value is false
'
,
()
=>
{
it
(
'
should initialize as unchecked
'
,
()
=>
{
const
wrapper
=
setupFixture
(
false
);
expect
(
wrapper
.
querySelector
(
'
.js-project-feature-toggle
'
).
classList
.
contains
(
'
is-checked
'
)).
toEqual
(
false
);
expect
(
wrapper
.
querySelector
(
'
.js-project-feature-toggle-input
'
).
value
).
toEqual
(
'
false
'
);
});
it
(
'
should toggle to checked when clicked
'
,
(
done
)
=>
{
const
wrapper
=
setupFixture
(
false
);
const
toggleButton
=
wrapper
.
querySelector
(
'
.js-project-feature-toggle
'
);
toggleButton
.
click
();
getSetTimeoutPromise
()
.
then
(()
=>
{
expect
(
toggleButton
.
classList
.
contains
(
'
is-checked
'
)).
toEqual
(
true
);
expect
(
wrapper
.
querySelector
(
'
.js-project-feature-toggle-input
'
).
value
).
toEqual
(
'
true
'
);
})
.
then
(
done
)
.
catch
(
done
.
fail
);
});
});
it
(
'
should emit `trigger-change` event
'
,
(
done
)
=>
{
const
changeSpy
=
jasmine
.
createSpy
(
'
changeEventHandler
'
);
const
wrapper
=
setupFixture
(
false
);
const
toggleButton
=
wrapper
.
querySelector
(
'
.js-project-feature-toggle
'
);
const
input
=
wrapper
.
querySelector
(
'
.js-project-feature-toggle-input
'
);
$
(
input
).
on
(
'
trigger-change
'
,
changeSpy
);
toggleButton
.
click
();
getSetTimeoutPromise
()
.
then
(()
=>
{
expect
(
changeSpy
).
toHaveBeenCalled
();
})
.
then
(
done
)
.
catch
(
done
.
fail
);
});
describe
(
'
clickCallback
'
,
()
=>
{
it
(
'
should show loading indicator while waiting
'
,
(
done
)
=>
{
const
isChecked
=
true
;
const
clickCallback
=
(
newValue
,
toggleButton
)
=>
{
const
input
=
toggleButton
.
querySelector
(
'
.js-project-feature-toggle-input
'
);
expect
(
newValue
).
toEqual
(
false
);
// Check for the loading state
expect
(
toggleButton
.
classList
.
contains
(
'
is-checked
'
)).
toEqual
(
false
);
expect
(
toggleButton
.
classList
.
contains
(
'
is-loading
'
)).
toEqual
(
true
);
expect
(
toggleButton
.
disabled
).
toEqual
(
true
);
expect
(
input
.
value
).
toEqual
(
'
true
'
);
// After the callback finishes, check that the loading state is gone
getSetTimeoutPromise
()
.
then
(()
=>
{
expect
(
toggleButton
.
classList
.
contains
(
'
is-checked
'
)).
toEqual
(
false
);
expect
(
toggleButton
.
classList
.
contains
(
'
is-loading
'
)).
toEqual
(
false
);
expect
(
toggleButton
.
disabled
).
toEqual
(
false
);
expect
(
input
.
value
).
toEqual
(
'
false
'
);
})
.
then
(
done
)
.
catch
(
done
.
fail
);
};
const
wrapper
=
setupFixture
(
isChecked
,
clickCallback
);
const
toggleButton
=
wrapper
.
querySelector
(
'
.js-project-feature-toggle
'
);
toggleButton
.
click
();
});
});
});
spec/lib/gitlab/import_export/project.json
View file @
d77181d5
...
...
@@ -7096,7 +7096,7 @@
"project_id"
:
5
,
"created_at"
:
"2016-06-14T15:01:51.232Z"
,
"updated_at"
:
"2016-06-14T15:01:51.232Z"
,
"active"
:
fals
e
,
"active"
:
tru
e
,
"properties"
:
{
},
...
...
spec/lib/gitlab/import_export/project_tree_saver_spec.rb
View file @
d77181d5
...
...
@@ -164,6 +164,10 @@ describe Gitlab::ImportExport::ProjectTreeSaver do
expect
(
saved_project_json
[
'services'
].
first
[
'type'
]).
to
eq
(
'CustomIssueTrackerService'
)
end
it
'saves the properties for a service'
do
expect
(
saved_project_json
[
'services'
].
first
[
'properties'
]).
to
eq
(
'one'
=>
'value'
)
end
it
'has project feature'
do
project_feature
=
saved_project_json
[
'project_feature'
]
expect
(
project_feature
).
not_to
be_empty
...
...
@@ -279,7 +283,7 @@ describe Gitlab::ImportExport::ProjectTreeSaver do
commit_id:
ci_build
.
pipeline
.
sha
)
create
(
:event
,
:created
,
target:
milestone
,
project:
project
,
author:
user
)
create
(
:service
,
project:
project
,
type:
'CustomIssueTrackerService'
,
category:
'issue_tracker'
)
create
(
:service
,
project:
project
,
type:
'CustomIssueTrackerService'
,
category:
'issue_tracker'
,
properties:
{
one:
'value'
}
)
create
(
:project_custom_attribute
,
project:
project
)
create
(
:project_custom_attribute
,
project:
project
)
...
...
spec/requests/api/issues_spec.rb
View file @
d77181d5
...
...
@@ -1441,7 +1441,7 @@ describe API::Issues, :mailer do
context
'when source project does not exist'
do
it
'returns 404 when trying to move an issue'
do
post
api
(
"/projects/123/issues/
#{
issue
.
iid
}
/move"
,
user
),
post
api
(
"/projects/123
45
/issues/
#{
issue
.
iid
}
/move"
,
user
),
to_project_id:
target_project
.
id
expect
(
response
).
to
have_gitlab_http_status
(
404
)
...
...
@@ -1452,7 +1452,7 @@ describe API::Issues, :mailer do
context
'when target project does not exist'
do
it
'returns 404 when trying to move an issue'
do
post
api
(
"/projects/
#{
project
.
id
}
/issues/
#{
issue
.
iid
}
/move"
,
user
),
to_project_id:
123
to_project_id:
123
45
expect
(
response
).
to
have_gitlab_http_status
(
404
)
end
...
...
spec/workers/repository_import_worker_spec.rb
View file @
d77181d5
...
...
@@ -49,9 +49,22 @@ describe RepositoryImportWorker do
expect
do
subject
.
perform
(
project
.
id
)
end
.
to
raise_error
(
Standard
Error
,
error
)
end
.
to
raise_error
(
Runtime
Error
,
error
)
expect
(
project
.
reload
.
import_jid
).
not_to
be_nil
end
it
'updates the error on Import/Export'
do
error
=
%q{remote: Not Found fatal: repository 'https://user:pass@test.com/root/repoC.git/' not found }
project
.
update_attributes
(
import_jid:
'123'
,
import_type:
'gitlab_project'
)
expect_any_instance_of
(
Projects
::
ImportService
).
to
receive
(
:execute
).
and_return
({
status: :error
,
message:
error
})
expect
do
subject
.
perform
(
project
.
id
)
end
.
to
raise_error
(
RuntimeError
,
error
)
expect
(
project
.
reload
.
import_error
).
not_to
be_nil
end
end
context
'when using an asynchronous importer'
do
...
...
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