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
d988966c
Commit
d988966c
authored
Jan 30, 2018
by
GitLab Bot
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'upstream/master' into ce-to-ee-2018-01-30
parents
f9a09067
7f647f9f
Changes
16
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
232 additions
and
183 deletions
+232
-183
app/assets/javascripts/gl_dropdown.js
app/assets/javascripts/gl_dropdown.js
+12
-19
app/assets/javascripts/graphs/graphs_show.js
app/assets/javascripts/graphs/graphs_show.js
+9
-7
app/assets/javascripts/group_label_subscription.js
app/assets/javascripts/group_label_subscription.js
+13
-14
app/assets/javascripts/integrations/integration_settings_form.js
...ets/javascripts/integrations/integration_settings_form.js
+23
-25
app/assets/javascripts/issuable_bulk_update_actions.js
app/assets/javascripts/issuable_bulk_update_actions.js
+4
-9
app/assets/javascripts/issuable_index.js
app/assets/javascripts/issuable_index.js
+19
-15
app/assets/javascripts/label_manager.js
app/assets/javascripts/label_manager.js
+14
-18
app/assets/javascripts/single_file_diff.js
app/assets/javascripts/single_file_diff.js
+15
-11
app/models/merge_request.rb
app/models/merge_request.rb
+2
-2
app/serializers/merge_request_widget_entity.rb
app/serializers/merge_request_widget_entity.rb
+12
-1
changelogs/unreleased/osw-short-circuit-mergeable-disccusions-state.yml
...eleased/osw-short-circuit-mergeable-disccusions-state.yml
+5
-0
scripts/static-analysis
scripts/static-analysis
+0
-1
spec/features/expand_collapse_diffs_spec.rb
spec/features/expand_collapse_diffs_spec.rb
+0
-7
spec/javascripts/integrations/integration_settings_form_spec.js
...avascripts/integrations/integration_settings_form_spec.js
+78
-50
spec/javascripts/issuable_spec.js
spec/javascripts/issuable_spec.js
+22
-4
spec/models/merge_request_spec.rb
spec/models/merge_request_spec.rb
+4
-0
No files found.
app/assets/javascripts/gl_dropdown.js
View file @
d988966c
...
...
@@ -2,6 +2,7 @@
/* global fuzzaldrinPlus */
import
_
from
'
underscore
'
;
import
fuzzaldrinPlus
from
'
fuzzaldrin-plus
'
;
import
axios
from
'
./lib/utils/axios_utils
'
;
import
{
visitUrl
}
from
'
./lib/utils/url_utility
'
;
import
{
isObject
}
from
'
./lib/utils/type_utility
'
;
...
...
@@ -212,25 +213,17 @@ GitLabDropdownRemote = (function() {
};
GitLabDropdownRemote
.
prototype
.
fetchData
=
function
()
{
return
$
.
ajax
({
url
:
this
.
dataEndpoint
,
dataType
:
this
.
options
.
dataType
,
beforeSend
:
(
function
(
_this
)
{
return
function
()
{
if
(
_this
.
options
.
beforeSend
)
{
return
_this
.
options
.
beforeSend
();
if
(
this
.
options
.
beforeSend
)
{
this
.
options
.
beforeSend
();
}
};
})(
this
),
success
:
(
function
(
_this
)
{
return
function
(
data
)
{
if
(
_
this
.
options
.
success
)
{
return
_
this
.
options
.
success
(
data
);
// Fetch the data through ajax if the data is a string
return
axios
.
get
(
this
.
dataEndpoint
)
.
then
(({
data
})
=>
{
if
(
this
.
options
.
success
)
{
return
this
.
options
.
success
(
data
);
}
};
})(
this
)
});
// Fetch the data through ajax if the data is a string
};
return
GitLabDropdownRemote
;
...
...
app/assets/javascripts/graphs/graphs_show.js
View file @
d988966c
import
flash
from
'
../flash
'
;
import
{
__
}
from
'
../locale
'
;
import
axios
from
'
../lib/utils/axios_utils
'
;
import
ContributorsStatGraph
from
'
./stat_graph_contributors
'
;
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
$
.
ajax
({
type
:
'
GET
'
,
url
:
document
.
querySelector
(
'
.js-graphs-show
'
).
dataset
.
projectGraphPath
,
dataType
:
'
json
'
,
success
(
data
)
{
const
url
=
document
.
querySelector
(
'
.js-graphs-show
'
).
dataset
.
projectGraphPath
;
axios
.
get
(
url
)
.
then
(({
data
})
=>
{
const
graph
=
new
ContributorsStatGraph
();
graph
.
init
(
data
);
...
...
@@ -16,6 +18,6 @@ document.addEventListener('DOMContentLoaded', () => {
$
(
'
.stat-graph
'
).
fadeIn
();
$
(
'
.loading-graph
'
).
hide
();
}
,
}
);
}
)
.
catch
(()
=>
flash
(
__
(
'
Error fetching contributors data.
'
))
);
});
app/assets/javascripts/group_label_subscription.js
View file @
d988966c
import
axios
from
'
./lib/utils/axios_utils
'
;
import
flash
from
'
./flash
'
;
import
{
__
}
from
'
./locale
'
;
export
default
class
GroupLabelSubscription
{
constructor
(
container
)
{
const
$container
=
$
(
container
);
...
...
@@ -13,14 +17,12 @@ export default class GroupLabelSubscription {
event
.
preventDefault
();
const
url
=
this
.
$unsubscribeButtons
.
attr
(
'
data-url
'
);
$
.
ajax
({
type
:
'
POST
'
,
url
,
}).
done
(()
=>
{
axios
.
post
(
url
)
.
then
(()
=>
{
this
.
toggleSubscriptionButtons
();
this
.
$unsubscribeButtons
.
removeAttr
(
'
data-url
'
);
});
})
.
catch
(()
=>
flash
(
__
(
'
There was an error when unsubscribing from this label.
'
)));
}
subscribe
(
event
)
{
...
...
@@ -31,12 +33,9 @@ export default class GroupLabelSubscription {
this
.
$unsubscribeButtons
.
attr
(
'
data-url
'
,
url
);
$
.
ajax
({
type
:
'
POST
'
,
url
,
}).
done
(()
=>
{
this
.
toggleSubscriptionButtons
();
});
axios
.
post
(
url
)
.
then
(()
=>
this
.
toggleSubscriptionButtons
())
.
catch
(()
=>
flash
(
__
(
'
There was an error when subscribing to this label.
'
)));
}
toggleSubscriptionButtons
()
{
...
...
app/assets/javascripts/integrations/integration_settings_form.js
View file @
d988966c
import
Flash
from
'
../flash
'
;
import
axios
from
'
../lib/utils/axios_utils
'
;
import
flash
from
'
../flash
'
;
export
default
class
IntegrationSettingsForm
{
constructor
(
formSelector
)
{
...
...
@@ -95,14 +96,11 @@ export default class IntegrationSettingsForm {
*/
testSettings
(
formData
)
{
this
.
toggleSubmitBtnState
(
true
);
$
.
ajax
({
type
:
'
PUT
'
,
url
:
this
.
testEndPoint
,
data
:
formData
,
})
.
done
((
res
)
=>
{
if
(
res
.
error
)
{
new
Flash
(
`
${
res
.
message
}
${
res
.
service_response
}
`
,
'
alert
'
,
document
,
{
return
axios
.
put
(
this
.
testEndPoint
,
formData
)
.
then
(({
data
})
=>
{
if
(
data
.
error
)
{
flash
(
`
${
data
.
message
}
${
data
.
service_response
}
`
,
'
alert
'
,
document
,
{
title
:
'
Save anyway
'
,
clickHandler
:
(
e
)
=>
{
e
.
preventDefault
();
...
...
@@ -112,11 +110,11 @@ export default class IntegrationSettingsForm {
}
else
{
this
.
$form
.
submit
();
}
this
.
toggleSubmitBtnState
(
false
);
})
.
fail
(()
=>
{
new
Flash
(
'
Something went wrong on our end.
'
);
})
.
always
(()
=>
{
.
catch
(()
=>
{
flash
(
'
Something went wrong on our end.
'
);
this
.
toggleSubmitBtnState
(
false
);
});
}
...
...
app/assets/javascripts/issuable_bulk_update_actions.js
View file @
d988966c
/* eslint-disable comma-dangle, quotes, consistent-return, func-names, array-callback-return, space-before-function-paren, prefer-arrow-callback, max-len, no-unused-expressions, no-sequences, no-underscore-dangle, no-unused-vars, no-param-reassign */
import
_
from
'
underscore
'
;
import
axios
from
'
./lib/utils/axios_utils
'
;
import
Flash
from
'
./flash
'
;
export
default
{
...
...
@@ -22,15 +23,9 @@ export default {
},
submit
()
{
const
_this
=
this
;
const
xhr
=
$
.
ajax
({
url
:
this
.
form
.
attr
(
'
action
'
),
method
:
this
.
form
.
attr
(
'
method
'
),
dataType
:
'
JSON
'
,
data
:
this
.
getFormDataAsObject
()
});
xhr
.
done
(()
=>
window
.
location
.
reload
());
xhr
.
fail
(()
=>
this
.
onFormSubmitFailure
());
axios
[
this
.
form
.
attr
(
'
method
'
)](
this
.
form
.
attr
(
'
action
'
),
this
.
getFormDataAsObject
())
.
then
(()
=>
window
.
location
.
reload
())
.
catch
(()
=>
this
.
onFormSubmitFailure
());
},
onFormSubmitFailure
()
{
...
...
app/assets/javascripts/issuable_index.js
View file @
d988966c
import
axios
from
'
./lib/utils/axios_utils
'
;
import
flash
from
'
./flash
'
;
import
{
__
}
from
'
./locale
'
;
import
IssuableBulkUpdateSidebar
from
'
./issuable_bulk_update_sidebar
'
;
import
IssuableBulkUpdateActions
from
'
./issuable_bulk_update_actions
'
;
...
...
@@ -20,22 +23,23 @@ export default class IssuableIndex {
}
static
resetIncomingEmailToken
()
{
$
(
'
.incoming-email-token-reset
'
).
on
(
'
click
'
,
(
e
)
=>
{
const
$resetToken
=
$
(
'
.incoming-email-token-reset
'
);
$resetToken
.
on
(
'
click
'
,
(
e
)
=>
{
e
.
preventDefault
();
$
.
ajax
({
type
:
'
PUT
'
,
url
:
$
(
'
.incoming-email-token-reset
'
).
attr
(
'
href
'
),
dataType
:
'
json
'
,
success
(
response
)
{
$
(
'
#issuable_email
'
).
val
(
response
.
new_address
).
focus
();
},
beforeSend
()
{
$
(
'
.incoming-email-token-reset
'
).
text
(
'
resetting...
'
);
},
complete
()
{
$
(
'
.incoming-email-token-reset
'
).
text
(
'
reset it
'
);
},
$resetToken
.
text
(
'
resetting...
'
);
axios
.
put
(
$resetToken
.
attr
(
'
href
'
))
.
then
(({
data
})
=>
{
$
(
'
#issuable_email
'
).
val
(
data
.
new_address
).
focus
();
$resetToken
.
text
(
'
reset it
'
);
})
.
catch
(()
=>
{
flash
(
__
(
'
There was an error when reseting email token.
'
));
$resetToken
.
text
(
'
reset it
'
);
});
});
}
...
...
app/assets/javascripts/label_manager.js
View file @
d988966c
/* eslint-disable comma-dangle, class-methods-use-this, no-underscore-dangle, no-param-reassign, no-unused-vars, consistent-return, func-names, space-before-function-paren, max-len */
import
Sortable
from
'
vendor/Sortable
'
;
import
Flash
from
'
./flash
'
;
import
flash
from
'
./flash
'
;
import
axios
from
'
./lib/utils/axios_utils
'
;
export
default
class
LabelManager
{
constructor
({
togglePriorityButton
,
prioritizedLabels
,
otherLabels
}
=
{})
{
...
...
@@ -50,11 +51,12 @@ export default class LabelManager {
if
(
persistState
==
null
)
{
persistState
=
true
;
}
let
xhr
;
const
_this
=
this
;
const
url
=
$label
.
find
(
'
.js-toggle-priority
'
).
data
(
'
url
'
);
let
$target
=
this
.
prioritizedLabels
;
let
$from
=
this
.
otherLabels
;
const
rollbackLabelPosition
=
this
.
rollbackLabelPosition
.
bind
(
this
,
$label
,
action
);
if
(
action
===
'
remove
'
)
{
$target
=
this
.
otherLabels
;
$from
=
this
.
prioritizedLabels
;
...
...
@@ -71,40 +73,34 @@ export default class LabelManager {
return
;
}
if
(
action
===
'
remove
'
)
{
xhr
=
$
.
ajax
({
url
,
type
:
'
DELETE
'
});
axios
.
delete
(
url
)
.
catch
(
rollbackLabelPosition
);
// Restore empty message
if
(
!
$from
.
find
(
'
li
'
).
length
)
{
$from
.
find
(
'
.empty-message
'
).
removeClass
(
'
hidden
'
);
}
}
else
{
xhr
=
this
.
savePrioritySort
(
$label
,
action
);
this
.
savePrioritySort
(
$label
,
action
)
.
catch
(
rollbackLabelPosition
);
}
return
xhr
.
fail
(
this
.
rollbackLabelPosition
.
bind
(
this
,
$label
,
action
));
}
onPrioritySortUpdate
()
{
const
xhr
=
this
.
savePrioritySort
();
return
xhr
.
fail
(
function
()
{
return
new
Flash
(
this
.
errorMessage
,
'
alert
'
);
});
this
.
savePrioritySort
()
.
catch
(()
=>
flash
(
this
.
errorMessage
));
}
savePrioritySort
()
{
return
$
.
post
({
url
:
this
.
prioritizedLabels
.
data
(
'
url
'
),
data
:
{
label_ids
:
this
.
getSortedLabelsIds
()
}
return
axios
.
post
(
this
.
prioritizedLabels
.
data
(
'
url
'
),
{
label_ids
:
this
.
getSortedLabelsIds
(),
});
}
rollbackLabelPosition
(
$label
,
originalAction
)
{
const
action
=
originalAction
===
'
remove
'
?
'
add
'
:
'
remove
'
;
this
.
toggleLabelPriority
(
$label
,
action
,
false
);
return
new
Flash
(
this
.
errorMessage
,
'
alert
'
);
flash
(
this
.
errorMessage
);
}
getSortedLabelsIds
()
{
...
...
app/assets/javascripts/single_file_diff.js
View file @
d988966c
/* eslint-disable func-names, prefer-arrow-callback, space-before-function-paren, no-var, prefer-rest-params, wrap-iife, one-var, one-var-declaration-per-line, consistent-return, no-param-reassign, max-len */
import
{
__
}
from
'
./locale
'
;
import
axios
from
'
./lib/utils/axios_utils
'
;
import
createFlash
from
'
./flash
'
;
import
FilesCommentButton
from
'
./files_comment_button
'
;
import
imageDiffHelper
from
'
./image_diff/helpers/index
'
;
import
syntaxHighlight
from
'
./syntax_highlight
'
;
...
...
@@ -60,30 +63,31 @@ export default class SingleFileDiff {
getContentHTML
(
cb
)
{
this
.
collapsedContent
.
hide
();
this
.
loadingContent
.
show
();
$
.
get
(
this
.
diffForPath
,
(
function
(
_this
)
{
return
function
(
data
)
{
_this
.
loadingContent
.
hide
();
axios
.
get
(
this
.
diffForPath
)
.
then
(({
data
})
=>
{
this
.
loadingContent
.
hide
();
if
(
data
.
html
)
{
_
this
.
content
=
$
(
data
.
html
);
syntaxHighlight
(
_
this
.
content
);
this
.
content
=
$
(
data
.
html
);
syntaxHighlight
(
this
.
content
);
}
else
{
_
this
.
hasError
=
true
;
_
this
.
content
=
$
(
ERROR_HTML
);
this
.
hasError
=
true
;
this
.
content
=
$
(
ERROR_HTML
);
}
_this
.
collapsedContent
.
after
(
_
this
.
content
);
this
.
collapsedContent
.
after
(
this
.
content
);
if
(
typeof
gl
.
diffNotesCompileComponents
!==
'
undefined
'
)
{
gl
.
diffNotesCompileComponents
();
}
const
$file
=
$
(
_
this
.
file
);
const
$file
=
$
(
this
.
file
);
FilesCommentButton
.
init
(
$file
);
const
canCreateNote
=
$file
.
closest
(
'
.files
'
).
is
(
'
[data-can-create-note]
'
);
imageDiffHelper
.
initImageDiff
(
$file
[
0
],
canCreateNote
);
if
(
cb
)
cb
();
}
;
})(
this
));
}
)
.
catch
(
createFlash
(
__
(
'
An error occurred while retrieving diff
'
)
));
}
}
app/models/merge_request.rb
View file @
d988966c
...
...
@@ -645,12 +645,12 @@ class MergeRequest < ActiveRecord::Base
can_be_merged?
&&
!
should_be_rebased?
end
def
mergeable_state?
(
skip_ci_check:
false
)
def
mergeable_state?
(
skip_ci_check:
false
,
skip_discussions_check:
false
)
return
false
unless
open
?
return
false
if
work_in_progress?
return
false
if
broken?
return
false
unless
skip_ci_check
||
mergeable_ci_state?
return
false
unless
mergeable_discussions_state?
return
false
unless
skip_discussions_check
||
mergeable_discussions_state?
true
end
...
...
app/serializers/merge_request_widget_entity.rb
View file @
d988966c
...
...
@@ -67,7 +67,18 @@ class MergeRequestWidgetEntity < IssuableEntity
expose
:merge_ongoing?
,
as: :merge_ongoing
expose
:work_in_progress?
,
as: :work_in_progress
expose
:source_branch_exists?
,
as: :source_branch_exists
expose
:mergeable_discussions_state?
,
as: :mergeable_discussions_state
expose
:mergeable_discussions_state?
,
as: :mergeable_discussions_state
do
|
merge_request
|
# This avoids calling MergeRequest#mergeable_discussions_state without
# considering the state of the MR first. If a MR isn't mergeable, we can
# safely short-circuit it.
if
merge_request
.
mergeable_state?
(
skip_ci_check:
true
,
skip_discussions_check:
true
)
merge_request
.
mergeable_discussions_state?
else
false
end
end
expose
:branch_missing?
,
as: :branch_missing
expose
:commits_count
expose
:cannot_be_merged?
,
as: :has_conflicts
...
...
changelogs/unreleased/osw-short-circuit-mergeable-disccusions-state.yml
0 → 100644
View file @
d988966c
---
title
:
Stop checking if discussions are in a mergeable state if the MR isn't
merge_request
:
author
:
type
:
performance
scripts/static-analysis
View file @
d988966c
...
...
@@ -35,7 +35,6 @@ tasks = [
%w[bundle exec rubocop --parallel]
,
%w[bundle exec rake gettext:lint]
,
%w[bundle exec rake lint:static_verification]
,
%w[scripts/lint-changelog-yaml]
,
%w[scripts/lint-conflicts.sh]
,
%w[scripts/lint-rugged]
]
...
...
spec/features/expand_collapse_diffs_spec.rb
View file @
d988966c
...
...
@@ -112,13 +112,6 @@ feature 'Expand and collapse diffs', :js do
wait_for_requests
end
it
'makes a request to get the content'
do
ajax_uris
=
evaluate_script
(
'ajaxUris'
)
expect
(
ajax_uris
).
not_to
be_empty
expect
(
ajax_uris
.
first
).
to
include
(
'large_diff.md'
)
end
it
'shows the diff content'
do
expect
(
large_diff
).
to
have_selector
(
'.code'
)
expect
(
large_diff
).
not_to
have_selector
(
'.nothing-here-block'
)
...
...
spec/javascripts/integrations/integration_settings_form_spec.js
View file @
d988966c
import
MockAdaptor
from
'
axios-mock-adapter
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
IntegrationSettingsForm
from
'
~/integrations/integration_settings_form
'
;
describe
(
'
IntegrationSettingsForm
'
,
()
=>
{
...
...
@@ -109,91 +111,117 @@ describe('IntegrationSettingsForm', () => {
describe
(
'
testSettings
'
,
()
=>
{
let
integrationSettingsForm
;
let
formData
;
let
mock
;
beforeEach
(()
=>
{
mock
=
new
MockAdaptor
(
axios
);
spyOn
(
axios
,
'
put
'
).
and
.
callThrough
();
integrationSettingsForm
=
new
IntegrationSettingsForm
(
'
.js-integration-settings-form
'
);
formData
=
integrationSettingsForm
.
$form
.
serialize
();
});
it
(
'
should make an ajax request with provided `formData`
'
,
()
=>
{
const
deferred
=
$
.
Deferred
();
spyOn
(
$
,
'
ajax
'
).
and
.
returnValue
(
deferred
.
promise
()
);
afterEach
(
()
=>
{
mock
.
restore
();
}
);
integrationSettingsForm
.
testSettings
(
formData
);
it
(
'
should make an ajax request with provided `formData`
'
,
(
done
)
=>
{
integrationSettingsForm
.
testSettings
(
formData
)
.
then
(()
=>
{
expect
(
axios
.
put
).
toHaveBeenCalledWith
(
integrationSettingsForm
.
testEndPoint
,
formData
);
expect
(
$
.
ajax
).
toHaveBeenCalledWith
({
type
:
'
PUT
'
,
url
:
integrationSettingsForm
.
testEndPoint
,
data
:
formData
,
});
done
();
})
.
catch
(
done
.
fail
);
});
it
(
'
should show error Flash with `Save anyway` action if ajax request responds with error in test
'
,
()
=>
{
it
(
'
should show error Flash with `Save anyway` action if ajax request responds with error in test
'
,
(
done
)
=>
{
const
errorMessage
=
'
Test failed.
'
;
const
deferred
=
$
.
Deferred
();
spyOn
(
$
,
'
ajax
'
).
and
.
returnValue
(
deferred
.
promise
());
integrationSettingsForm
.
testSettings
(
formData
);
deferred
.
resolve
({
error
:
true
,
message
:
errorMessage
,
service_response
:
'
some error
'
});
mock
.
onPut
(
integrationSettingsForm
.
testEndPoint
).
reply
(
200
,
{
error
:
true
,
message
:
errorMessage
,
service_response
:
'
some error
'
,
});
integrationSettingsForm
.
testSettings
(
formData
)
.
then
(()
=>
{
const
$flashContainer
=
$
(
'
.flash-container
'
);
expect
(
$flashContainer
.
find
(
'
.flash-text
'
).
text
().
trim
()).
toEqual
(
'
Test failed. some error
'
);
expect
(
$flashContainer
.
find
(
'
.flash-action
'
)).
toBeDefined
();
expect
(
$flashContainer
.
find
(
'
.flash-action
'
).
text
().
trim
()).
toEqual
(
'
Save anyway
'
);
});
it
(
'
should submit form if ajax request responds without any error in test
'
,
()
=>
{
const
deferred
=
$
.
Deferred
();
spyOn
(
$
,
'
ajax
'
).
and
.
returnValue
(
deferred
.
promise
());
integrationSettingsForm
.
testSettings
(
formData
);
done
();
})
.
catch
(
done
.
fail
);
});
it
(
'
should submit form if ajax request responds without any error in test
'
,
(
done
)
=>
{
spyOn
(
integrationSettingsForm
.
$form
,
'
submit
'
);
deferred
.
resolve
({
error
:
false
});
expect
(
integrationSettingsForm
.
$form
.
submit
).
toHaveBeenCalled
();
mock
.
onPut
(
integrationSettingsForm
.
testEndPoint
).
reply
(
200
,
{
error
:
false
,
});
it
(
'
should submit form when clicked on `Save anyway` action of error Flash
'
,
()
=>
{
const
errorMessage
=
'
Test failed.
'
;
const
deferred
=
$
.
Deferred
();
spyOn
(
$
,
'
ajax
'
).
and
.
returnValue
(
deferred
.
promise
());
integrationSettingsForm
.
testSettings
(
formData
)
.
then
(()
=>
{
expect
(
integrationSettingsForm
.
$form
.
submit
).
toHaveBeenCalled
();
done
();
})
.
catch
(
done
.
fail
);
});
integrationSettingsForm
.
testSettings
(
formData
);
it
(
'
should submit form when clicked on `Save anyway` action of error Flash
'
,
(
done
)
=>
{
spyOn
(
integrationSettingsForm
.
$form
,
'
submit
'
);
deferred
.
resolve
({
error
:
true
,
message
:
errorMessage
});
const
errorMessage
=
'
Test failed.
'
;
mock
.
onPut
(
integrationSettingsForm
.
testEndPoint
).
reply
(
200
,
{
error
:
true
,
message
:
errorMessage
,
});
integrationSettingsForm
.
testSettings
(
formData
)
.
then
(()
=>
{
const
$flashAction
=
$
(
'
.flash-container .flash-action
'
);
expect
(
$flashAction
).
toBeDefined
();
spyOn
(
integrationSettingsForm
.
$form
,
'
submit
'
);
$flashAction
.
get
(
0
).
click
();
})
.
then
(()
=>
{
expect
(
integrationSettingsForm
.
$form
.
submit
).
toHaveBeenCalled
();
done
();
})
.
catch
(
done
.
fail
);
});
it
(
'
should show error Flash if ajax request failed
'
,
()
=>
{
it
(
'
should show error Flash if ajax request failed
'
,
(
done
)
=>
{
const
errorMessage
=
'
Something went wrong on our end.
'
;
const
deferred
=
$
.
Deferred
();
spyOn
(
$
,
'
ajax
'
).
and
.
returnValue
(
deferred
.
promise
());
integrationSettingsForm
.
testSettings
(
formData
);
deferred
.
reject
();
mock
.
onPut
(
integrationSettingsForm
.
testEndPoint
).
networkError
();
integrationSettingsForm
.
testSettings
(
formData
)
.
then
(()
=>
{
expect
(
$
(
'
.flash-container .flash-text
'
).
text
().
trim
()).
toEqual
(
errorMessage
);
});
it
(
'
should always call `toggleSubmitBtnState` with `false` once request is completed
'
,
()
=>
{
const
deferred
=
$
.
Deferred
();
spyOn
(
$
,
'
ajax
'
).
and
.
returnValue
(
deferred
.
promise
());
done
();
})
.
catch
(
done
.
fail
);
});
integrationSettingsForm
.
testSettings
(
formData
);
it
(
'
should always call `toggleSubmitBtnState` with `false` once request is completed
'
,
(
done
)
=>
{
mock
.
onPut
(
integrationSettingsForm
.
testEndPoint
).
networkError
();
spyOn
(
integrationSettingsForm
,
'
toggleSubmitBtnState
'
);
deferred
.
reject
();
integrationSettingsForm
.
testSettings
(
formData
)
.
then
(()
=>
{
expect
(
integrationSettingsForm
.
toggleSubmitBtnState
).
toHaveBeenCalledWith
(
false
);
done
();
})
.
catch
(
done
.
fail
);
});
});
});
spec/javascripts/issuable_spec.js
View file @
d988966c
import
MockAdaptor
from
'
axios-mock-adapter
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
IssuableIndex
from
'
~/issuable_index
'
;
describe
(
'
Issuable
'
,
()
=>
{
...
...
@@ -19,6 +21,8 @@ describe('Issuable', () => {
});
describe
(
'
resetIncomingEmailToken
'
,
()
=>
{
let
mock
;
beforeEach
(()
=>
{
const
element
=
document
.
createElement
(
'
a
'
);
element
.
classList
.
add
(
'
incoming-email-token-reset
'
);
...
...
@@ -30,14 +34,28 @@ describe('Issuable', () => {
document
.
body
.
appendChild
(
input
);
Issuable
=
new
IssuableIndex
(
'
issue_
'
);
mock
=
new
MockAdaptor
(
axios
);
mock
.
onPut
(
'
foo
'
).
reply
(
200
,
{
new_address
:
'
testing123
'
,
});
});
it
(
'
should send request to reset email token
'
,
()
=>
{
spyOn
(
jQuery
,
'
ajax
'
).
and
.
callThrough
();
afterEach
(()
=>
{
mock
.
restore
();
});
it
(
'
should send request to reset email token
'
,
(
done
)
=>
{
spyOn
(
axios
,
'
put
'
).
and
.
callThrough
();
document
.
querySelector
(
'
.incoming-email-token-reset
'
).
click
();
expect
(
jQuery
.
ajax
).
toHaveBeenCalled
();
expect
(
jQuery
.
ajax
.
calls
.
argsFor
(
0
)[
0
].
url
).
toEqual
(
'
foo
'
);
setTimeout
(()
=>
{
expect
(
axios
.
put
).
toHaveBeenCalledWith
(
'
foo
'
);
expect
(
$
(
'
#issuable_email
'
).
val
()).
toBe
(
'
testing123
'
);
done
();
});
});
});
});
...
...
spec/models/merge_request_spec.rb
View file @
d988966c
...
...
@@ -1568,6 +1568,10 @@ describe MergeRequest do
it
'returns false'
do
expect
(
subject
.
mergeable_state?
).
to
be_falsey
end
it
'returns true when skipping discussions check'
do
expect
(
subject
.
mergeable_state?
(
skip_discussions_check:
true
)).
to
be
(
true
)
end
end
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