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
fbd8cf89
Commit
fbd8cf89
authored
Sep 15, 2020
by
Paul Slaughter
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Handle different commit errors in IDE
Currently parses for: - CODEOWNERS violation - Branch changed
parent
49d7ee1e
Changes
15
Show whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
315 additions
and
53 deletions
+315
-53
app/assets/javascripts/ide/components/commit_sidebar/form.vue
...assets/javascripts/ide/components/commit_sidebar/form.vue
+28
-13
app/assets/javascripts/ide/lib/errors.js
app/assets/javascripts/ide/lib/errors.js
+39
-0
app/assets/javascripts/ide/stores/modules/commit/actions.js
app/assets/javascripts/ide/stores/modules/commit/actions.js
+8
-20
app/assets/javascripts/ide/stores/modules/commit/mutation_types.js
...s/javascripts/ide/stores/modules/commit/mutation_types.js
+3
-0
app/assets/javascripts/ide/stores/modules/commit/mutations.js
...assets/javascripts/ide/stores/modules/commit/mutations.js
+6
-0
app/assets/javascripts/ide/stores/modules/commit/state.js
app/assets/javascripts/ide/stores/modules/commit/state.js
+1
-0
app/assets/javascripts/lib/utils/text_utility.js
app/assets/javascripts/lib/utils/text_utility.js
+21
-0
changelogs/unreleased/212595-ide-commit-errors.yml
changelogs/unreleased/212595-ide-commit-errors.yml
+5
-0
ee/spec/features/ide/user_commits_changes_spec.rb
ee/spec/features/ide/user_commits_changes_spec.rb
+34
-0
locale/gitlab.pot
locale/gitlab.pot
+13
-7
spec/frontend/ide/components/commit_sidebar/form_spec.js
spec/frontend/ide/components/commit_sidebar/form_spec.js
+39
-12
spec/frontend/ide/lib/errors_spec.js
spec/frontend/ide/lib/errors_spec.js
+63
-0
spec/frontend/ide/stores/modules/commit/actions_spec.js
spec/frontend/ide/stores/modules/commit/actions_spec.js
+21
-1
spec/frontend/ide/stores/modules/commit/mutations_spec.js
spec/frontend/ide/stores/modules/commit/mutations_spec.js
+21
-0
spec/frontend/lib/utils/text_utility_spec.js
spec/frontend/lib/utils/text_utility_spec.js
+13
-0
No files found.
app/assets/javascripts/ide/components/commit_sidebar/form.vue
View file @
fbd8cf89
...
@@ -8,6 +8,7 @@ import Actions from './actions.vue';
...
@@ -8,6 +8,7 @@ import Actions from './actions.vue';
import
SuccessMessage
from
'
./success_message.vue
'
;
import
SuccessMessage
from
'
./success_message.vue
'
;
import
{
leftSidebarViews
,
MAX_WINDOW_HEIGHT_COMPACT
}
from
'
../../constants
'
;
import
{
leftSidebarViews
,
MAX_WINDOW_HEIGHT_COMPACT
}
from
'
../../constants
'
;
import
consts
from
'
../../stores/modules/commit/constants
'
;
import
consts
from
'
../../stores/modules/commit/constants
'
;
import
{
createUnexpectedCommitError
}
from
'
../../lib/errors
'
;
export
default
{
export
default
{
components
:
{
components
:
{
...
@@ -21,11 +22,13 @@ export default {
...
@@ -21,11 +22,13 @@ export default {
return
{
return
{
isCompact
:
true
,
isCompact
:
true
,
componentHeight
:
null
,
componentHeight
:
null
,
// Keep track of "lastCommitError" so we hold onto the value even when "commitError" is cleared.
lastCommitError
:
createUnexpectedCommitError
(),
};
};
},
},
computed
:
{
computed
:
{
...
mapState
([
'
changedFiles
'
,
'
stagedFiles
'
,
'
currentActivityView
'
,
'
lastCommitMsg
'
]),
...
mapState
([
'
changedFiles
'
,
'
stagedFiles
'
,
'
currentActivityView
'
,
'
lastCommitMsg
'
]),
...
mapState
(
'
commit
'
,
[
'
commitMessage
'
,
'
submitCommitLoading
'
]),
...
mapState
(
'
commit
'
,
[
'
commitMessage
'
,
'
submitCommitLoading
'
,
'
commitError
'
]),
...
mapGetters
([
'
someUncommittedChanges
'
]),
...
mapGetters
([
'
someUncommittedChanges
'
]),
...
mapGetters
(
'
commit
'
,
[
'
discardDraftButtonDisabled
'
,
'
preBuiltCommitMessage
'
]),
...
mapGetters
(
'
commit
'
,
[
'
discardDraftButtonDisabled
'
,
'
preBuiltCommitMessage
'
]),
overviewText
()
{
overviewText
()
{
...
@@ -38,11 +41,28 @@ export default {
...
@@ -38,11 +41,28 @@ export default {
currentViewIsCommitView
()
{
currentViewIsCommitView
()
{
return
this
.
currentActivityView
===
leftSidebarViews
.
commit
.
name
;
return
this
.
currentActivityView
===
leftSidebarViews
.
commit
.
name
;
},
},
commitErrorPrimaryAction
()
{
if
(
!
this
.
lastCommitError
?.
canCreateBranch
)
{
return
undefined
;
}
return
{
text
:
__
(
'
Create new branch
'
),
};
},
},
},
watch
:
{
watch
:
{
currentActivityView
:
'
handleCompactState
'
,
currentActivityView
:
'
handleCompactState
'
,
someUncommittedChanges
:
'
handleCompactState
'
,
someUncommittedChanges
:
'
handleCompactState
'
,
lastCommitMsg
:
'
handleCompactState
'
,
lastCommitMsg
:
'
handleCompactState
'
,
commitError
(
val
)
{
if
(
!
val
)
{
return
;
}
this
.
lastCommitError
=
val
;
this
.
$refs
.
commitErrorModal
.
show
();
},
},
},
methods
:
{
methods
:
{
...
mapActions
([
'
updateActivityBarView
'
]),
...
mapActions
([
'
updateActivityBarView
'
]),
...
@@ -53,9 +73,7 @@ export default {
...
@@ -53,9 +73,7 @@ export default {
'
updateCommitAction
'
,
'
updateCommitAction
'
,
]),
]),
commit
()
{
commit
()
{
return
this
.
commitChanges
().
catch
(()
=>
{
return
this
.
commitChanges
();
this
.
$refs
.
createBranchModal
.
show
();
});
},
},
forceCreateNewBranch
()
{
forceCreateNewBranch
()
{
return
this
.
updateCommitAction
(
consts
.
COMMIT_TO_NEW_BRANCH
).
then
(()
=>
this
.
commit
());
return
this
.
updateCommitAction
(
consts
.
COMMIT_TO_NEW_BRANCH
).
then
(()
=>
this
.
commit
());
...
@@ -164,17 +182,14 @@ export default {
...
@@ -164,17 +182,14 @@ export default {
</button>
</button>
</div>
</div>
<gl-modal
<gl-modal
ref=
"c
reateBranch
Modal"
ref=
"c
ommitError
Modal"
modal-id=
"ide-c
reate-branch
-modal"
modal-id=
"ide-c
ommit-error
-modal"
:
ok-title=
"__('Create new branch')
"
:
title=
"lastCommitError.title
"
:
title=
"__('Branch has changed')
"
:
action-primary=
"commitErrorPrimaryAction
"
ok-variant=
"success
"
:action-cancel=
"
{ text: __('Cancel') }
"
@ok="forceCreateNewBranch"
@ok="forceCreateNewBranch"
>
>
{{
{{
lastCommitError
.
message
}}
__
(
`This branch has changed since you started editing.
Would you like to create a new branch?`
)
}}
</gl-modal>
</gl-modal>
</form>
</form>
</transition>
</transition>
...
...
app/assets/javascripts/ide/lib/errors.js
0 → 100644
View file @
fbd8cf89
import
{
__
}
from
'
~/locale
'
;
import
{
joinSentences
}
from
'
~/lib/utils/text_utility
'
;
const
CODEOWNERS_REGEX
=
/Push.*protected branches.*CODEOWNERS/
;
const
BRANCH_CHANGED_REGEX
=
/changed.*since.*start.*edit/
;
export
const
createUnexpectedCommitError
=
()
=>
({
title
:
__
(
'
Unexpected error
'
),
message
:
__
(
'
Could not commit. An unexpected error occurred.
'
),
canCreateBranch
:
false
,
});
export
const
createCodeownersCommitError
=
message
=>
({
title
:
__
(
'
CODEOWNERS rule violation
'
),
message
,
canCreateBranch
:
true
,
});
export
const
createBranchChangedCommitError
=
message
=>
({
title
:
__
(
'
Branch changed
'
),
message
:
joinSentences
(
message
,
__
(
'
Would you like to create a new branch?
'
)),
canCreateBranch
:
true
,
});
export
const
parseCommitError
=
e
=>
{
const
{
message
}
=
e
?.
response
?.
data
||
{};
if
(
!
message
)
{
return
createUnexpectedCommitError
();
}
if
(
CODEOWNERS_REGEX
.
test
(
message
))
{
return
createCodeownersCommitError
(
message
);
}
else
if
(
BRANCH_CHANGED_REGEX
.
test
(
message
))
{
return
createBranchChangedCommitError
(
message
);
}
return
createUnexpectedCommitError
();
};
app/assets/javascripts/ide/stores/modules/commit/actions.js
View file @
fbd8cf89
import
{
sprintf
,
__
}
from
'
~/locale
'
;
import
{
sprintf
,
__
}
from
'
~/locale
'
;
import
{
deprecatedCreateFlash
as
flash
}
from
'
~/flash
'
;
import
{
deprecatedCreateFlash
as
flash
}
from
'
~/flash
'
;
import
httpStatusCodes
from
'
~/lib/utils/http_status
'
;
import
*
as
rootTypes
from
'
../../mutation_types
'
;
import
*
as
rootTypes
from
'
../../mutation_types
'
;
import
{
createCommitPayload
,
createNewMergeRequestUrl
}
from
'
../../utils
'
;
import
{
createCommitPayload
,
createNewMergeRequestUrl
}
from
'
../../utils
'
;
import
service
from
'
../../../services
'
;
import
service
from
'
../../../services
'
;
...
@@ -8,6 +7,7 @@ import * as types from './mutation_types';
...
@@ -8,6 +7,7 @@ import * as types from './mutation_types';
import
consts
from
'
./constants
'
;
import
consts
from
'
./constants
'
;
import
{
leftSidebarViews
}
from
'
../../../constants
'
;
import
{
leftSidebarViews
}
from
'
../../../constants
'
;
import
eventHub
from
'
../../../eventhub
'
;
import
eventHub
from
'
../../../eventhub
'
;
import
{
parseCommitError
}
from
'
../../../lib/errors
'
;
export
const
updateCommitMessage
=
({
commit
},
message
)
=>
{
export
const
updateCommitMessage
=
({
commit
},
message
)
=>
{
commit
(
types
.
UPDATE_COMMIT_MESSAGE
,
message
);
commit
(
types
.
UPDATE_COMMIT_MESSAGE
,
message
);
...
@@ -113,6 +113,7 @@ export const commitChanges = ({ commit, state, getters, dispatch, rootState, roo
...
@@ -113,6 +113,7 @@ export const commitChanges = ({ commit, state, getters, dispatch, rootState, roo
?
Promise
.
resolve
()
?
Promise
.
resolve
()
:
dispatch
(
'
stageAllChanges
'
,
null
,
{
root
:
true
});
:
dispatch
(
'
stageAllChanges
'
,
null
,
{
root
:
true
});
commit
(
types
.
CLEAR_ERROR
);
commit
(
types
.
UPDATE_LOADING
,
true
);
commit
(
types
.
UPDATE_LOADING
,
true
);
return
stageFilesPromise
return
stageFilesPromise
...
@@ -128,6 +129,12 @@ export const commitChanges = ({ commit, state, getters, dispatch, rootState, roo
...
@@ -128,6 +129,12 @@ export const commitChanges = ({ commit, state, getters, dispatch, rootState, roo
return
service
.
commit
(
rootState
.
currentProjectId
,
payload
);
return
service
.
commit
(
rootState
.
currentProjectId
,
payload
);
})
})
.
catch
(
e
=>
{
commit
(
types
.
UPDATE_LOADING
,
false
);
commit
(
types
.
SET_ERROR
,
parseCommitError
(
e
));
throw
e
;
})
.
then
(({
data
})
=>
{
.
then
(({
data
})
=>
{
commit
(
types
.
UPDATE_LOADING
,
false
);
commit
(
types
.
UPDATE_LOADING
,
false
);
...
@@ -214,24 +221,5 @@ export const commitChanges = ({ commit, state, getters, dispatch, rootState, roo
...
@@ -214,24 +221,5 @@ export const commitChanges = ({ commit, state, getters, dispatch, rootState, roo
{
root
:
true
},
{
root
:
true
},
),
),
);
);
})
.
catch
(
err
=>
{
commit
(
types
.
UPDATE_LOADING
,
false
);
// don't catch bad request errors, let the view handle them
if
(
err
.
response
.
status
===
httpStatusCodes
.
BAD_REQUEST
)
throw
err
;
dispatch
(
'
setErrorMessage
'
,
{
text
:
__
(
'
An error occurred while committing your changes.
'
),
action
:
()
=>
dispatch
(
'
commitChanges
'
).
then
(()
=>
dispatch
(
'
setErrorMessage
'
,
null
,
{
root
:
true
})),
actionText
:
__
(
'
Please try again
'
),
},
{
root
:
true
},
);
window
.
dispatchEvent
(
new
Event
(
'
resize
'
));
});
});
};
};
app/assets/javascripts/ide/stores/modules/commit/mutation_types.js
View file @
fbd8cf89
...
@@ -3,3 +3,6 @@ export const UPDATE_COMMIT_ACTION = 'UPDATE_COMMIT_ACTION';
...
@@ -3,3 +3,6 @@ export const UPDATE_COMMIT_ACTION = 'UPDATE_COMMIT_ACTION';
export
const
UPDATE_NEW_BRANCH_NAME
=
'
UPDATE_NEW_BRANCH_NAME
'
;
export
const
UPDATE_NEW_BRANCH_NAME
=
'
UPDATE_NEW_BRANCH_NAME
'
;
export
const
UPDATE_LOADING
=
'
UPDATE_LOADING
'
;
export
const
UPDATE_LOADING
=
'
UPDATE_LOADING
'
;
export
const
TOGGLE_SHOULD_CREATE_MR
=
'
TOGGLE_SHOULD_CREATE_MR
'
;
export
const
TOGGLE_SHOULD_CREATE_MR
=
'
TOGGLE_SHOULD_CREATE_MR
'
;
export
const
CLEAR_ERROR
=
'
CLEAR_ERROR
'
;
export
const
SET_ERROR
=
'
SET_ERROR
'
;
app/assets/javascripts/ide/stores/modules/commit/mutations.js
View file @
fbd8cf89
...
@@ -24,4 +24,10 @@ export default {
...
@@ -24,4 +24,10 @@ export default {
shouldCreateMR
:
shouldCreateMR
===
undefined
?
!
state
.
shouldCreateMR
:
shouldCreateMR
,
shouldCreateMR
:
shouldCreateMR
===
undefined
?
!
state
.
shouldCreateMR
:
shouldCreateMR
,
});
});
},
},
[
types
.
CLEAR_ERROR
](
state
)
{
state
.
commitError
=
null
;
},
[
types
.
SET_ERROR
](
state
,
error
)
{
state
.
commitError
=
error
;
},
};
};
app/assets/javascripts/ide/stores/modules/commit/state.js
View file @
fbd8cf89
...
@@ -4,4 +4,5 @@ export default () => ({
...
@@ -4,4 +4,5 @@ export default () => ({
newBranchName
:
''
,
newBranchName
:
''
,
submitCommitLoading
:
false
,
submitCommitLoading
:
false
,
shouldCreateMR
:
true
,
shouldCreateMR
:
true
,
commitError
:
null
,
});
});
app/assets/javascripts/lib/utils/text_utility.js
View file @
fbd8cf89
...
@@ -399,3 +399,24 @@ export const truncateNamespace = (string = '') => {
...
@@ -399,3 +399,24 @@ export const truncateNamespace = (string = '') => {
* @returns {Boolean}
* @returns {Boolean}
*/
*/
export
const
hasContent
=
obj
=>
isString
(
obj
)
&&
obj
.
trim
()
!==
''
;
export
const
hasContent
=
obj
=>
isString
(
obj
)
&&
obj
.
trim
()
!==
''
;
/**
* Joins the given sentences by adding periods if necessary.
*
* @param {...string} sentences
*/
export
const
joinSentences
=
(...
sentences
)
=>
sentences
.
reduce
((
acc
,
sentence
)
=>
{
if
(
!
sentence
?.
trim
())
{
return
acc
;
}
else
if
(
!
acc
)
{
return
sentence
;
}
else
if
(
/
[
.!?
]\s
*$/
.
test
(
acc
))
{
const
endsWithSpace
=
/
\s
$/
.
test
(
acc
);
const
sep
=
endsWithSpace
?
''
:
'
'
;
return
`
${
acc
}${
sep
}${
sentence
}
`
;
}
return
`
${
acc
}
.
${
sentence
}
`
;
},
''
);
changelogs/unreleased/212595-ide-commit-errors.yml
0 → 100644
View file @
fbd8cf89
---
title
:
Fix error reporting for Web IDE commits
merge_request
:
42383
author
:
type
:
fixed
ee/spec/features/ide/user_commits_changes_spec.rb
0 → 100644
View file @
fbd8cf89
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
'EE IDE user commits changes'
,
:js
do
include
WebIdeSpecHelpers
let
(
:project
)
{
create
(
:project
,
:custom_repo
,
files:
{
'docs/CODEOWNERS'
=>
"[Backend]
\n
*.rb @ruby-owner"
})
}
let
(
:ruby_owner
)
{
create
(
:user
,
username:
'ruby-owner'
)
}
let
(
:user
)
{
project
.
owner
}
before
do
stub_licensed_features
(
code_owners:
true
,
code_owner_approval_required:
true
)
project
.
add_developer
(
ruby_owner
)
create
(
:protected_branch
,
name:
'master'
,
code_owner_approval_required:
true
,
project:
project
)
sign_in
(
user
)
ide_visit
(
project
)
end
it
'shows error message'
do
ide_create_new_file
(
'test.rb'
,
content:
'# A ruby file'
)
ide_commit
expect
(
page
).
to
have_content
(
'CODEOWNERS rule violation'
)
end
end
locale/gitlab.pot
View file @
fbd8cf89
...
@@ -2673,9 +2673,6 @@ msgstr ""
...
@@ -2673,9 +2673,6 @@ msgstr ""
msgid "An error occurred while checking group path. Please refresh and try again."
msgid "An error occurred while checking group path. Please refresh and try again."
msgstr ""
msgstr ""
msgid "An error occurred while committing your changes."
msgstr ""
msgid "An error occurred while creating the issue. Please try again."
msgid "An error occurred while creating the issue. Please try again."
msgstr ""
msgstr ""
...
@@ -4106,7 +4103,7 @@ msgstr ""
...
@@ -4106,7 +4103,7 @@ msgstr ""
msgid "Branch %{branch_name} was created. To set up auto deploy, choose a GitLab CI Yaml template and commit your changes. %{link_to_autodeploy_doc}"
msgid "Branch %{branch_name} was created. To set up auto deploy, choose a GitLab CI Yaml template and commit your changes. %{link_to_autodeploy_doc}"
msgstr ""
msgstr ""
msgid "Branch
has
changed"
msgid "Branch changed"
msgstr ""
msgstr ""
msgid "Branch is already taken"
msgid "Branch is already taken"
...
@@ -4412,6 +4409,9 @@ msgstr ""
...
@@ -4412,6 +4409,9 @@ msgstr ""
msgid "CLOSED (MOVED)"
msgid "CLOSED (MOVED)"
msgstr ""
msgstr ""
msgid "CODEOWNERS rule violation"
msgstr ""
msgid "CONTRIBUTING"
msgid "CONTRIBUTING"
msgstr ""
msgstr ""
...
@@ -7126,6 +7126,9 @@ msgstr ""
...
@@ -7126,6 +7126,9 @@ msgstr ""
msgid "Could not change HEAD: branch '%{branch}' does not exist"
msgid "Could not change HEAD: branch '%{branch}' does not exist"
msgstr ""
msgstr ""
msgid "Could not commit. An unexpected error occurred."
msgstr ""
msgid "Could not connect to FogBugz, check your URL"
msgid "Could not connect to FogBugz, check your URL"
msgstr ""
msgstr ""
...
@@ -25643,9 +25646,6 @@ msgstr ""
...
@@ -25643,9 +25646,6 @@ msgstr ""
msgid "This board's scope is reduced"
msgid "This board's scope is reduced"
msgstr ""
msgstr ""
msgid "This branch has changed since you started editing. Would you like to create a new branch?"
msgstr ""
msgid "This chart could not be displayed"
msgid "This chart could not be displayed"
msgstr ""
msgstr ""
...
@@ -26994,6 +26994,9 @@ msgstr ""
...
@@ -26994,6 +26994,9 @@ msgstr ""
msgid "Undo ignore"
msgid "Undo ignore"
msgstr ""
msgstr ""
msgid "Unexpected error"
msgstr ""
msgid "Unfortunately, your email message to GitLab could not be processed."
msgid "Unfortunately, your email message to GitLab could not be processed."
msgstr ""
msgstr ""
...
@@ -28653,6 +28656,9 @@ msgstr ""
...
@@ -28653,6 +28656,9 @@ msgstr ""
msgid "Workflow Help"
msgid "Workflow Help"
msgstr ""
msgstr ""
msgid "Would you like to create a new branch?"
msgstr ""
msgid "Write"
msgid "Write"
msgstr ""
msgstr ""
...
...
spec/frontend/ide/components/commit_sidebar/form_spec.js
View file @
fbd8cf89
import
Vue
from
'
vue
'
;
import
Vue
from
'
vue
'
;
import
{
getByText
}
from
'
@testing-library/dom
'
;
import
{
createComponentWithStore
}
from
'
helpers/vue_mount_component_helper
'
;
import
{
createComponentWithStore
}
from
'
helpers/vue_mount_component_helper
'
;
import
{
projectData
}
from
'
jest/ide/mock_data
'
;
import
{
projectData
}
from
'
jest/ide/mock_data
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
import
{
createStore
}
from
'
~/ide/stores
'
;
import
{
createStore
}
from
'
~/ide/stores
'
;
import
consts
from
'
~/ide/stores/modules/commit/constants
'
;
import
CommitForm
from
'
~/ide/components/commit_sidebar/form.vue
'
;
import
CommitForm
from
'
~/ide/components/commit_sidebar/form.vue
'
;
import
{
leftSidebarViews
}
from
'
~/ide/constants
'
;
import
{
leftSidebarViews
}
from
'
~/ide/constants
'
;
import
{
createCodeownersCommitError
,
createUnexpectedCommitError
}
from
'
~/ide/lib/errors
'
;
describe
(
'
IDE commit form
'
,
()
=>
{
describe
(
'
IDE commit form
'
,
()
=>
{
const
Component
=
Vue
.
extend
(
CommitForm
);
const
Component
=
Vue
.
extend
(
CommitForm
);
...
@@ -259,21 +262,45 @@ describe('IDE commit form', () => {
...
@@ -259,21 +262,45 @@ describe('IDE commit form', () => {
});
});
});
});
it
(
'
opens new branch modal if commitChanges throws an error
'
,
()
=>
{
it
.
each
`
vm
.
commitChanges
.
mockRejectedValue
({
success
:
false
});
createError | props
${()
=>
createCodeownersCommitError
(
'
test message
'
)}
|
${{
actionPrimary
:
{
text
:
'
Create new branch
'
}
}}
${
createUnexpectedCommitError
}
|
${{
actionPrimary
:
null
}
}
`
(
'
opens error modal if commitError with $error
'
,
async
({
createError
,
props
})
=>
{
jest
.
spyOn
(
vm
.
$refs
.
commitErrorModal
,
'
show
'
);
jest
.
spyOn
(
vm
.
$refs
.
createBranchModal
,
'
show
'
).
mockImplementation
();
const
error
=
createError
();
vm
.
$store
.
state
.
commit
.
commitError
=
error
;
return
vm
await
vm
.
$nextTick
();
.
$nextTick
()
.
then
(()
=>
{
vm
.
$el
.
querySelector
(
'
.btn-success
'
).
click
();
return
vm
.
$nextTick
();
expect
(
vm
.
$refs
.
commitErrorModal
.
show
).
toHaveBeenCalled
();
})
expect
(
vm
.
$refs
.
commitErrorModal
).
toMatchObject
({
.
then
(()
=>
{
actionCancel
:
{
text
:
'
Cancel
'
},
expect
(
vm
.
$refs
.
createBranchModal
.
show
).
toHaveBeenCalled
();
...
props
,
});
expect
(
document
.
body
).
toHaveText
(
error
.
message
);
});
});
});
describe
(
'
with error modal with primary
'
,
()
=>
{
beforeEach
(()
=>
{
jest
.
spyOn
(
vm
.
$store
,
'
dispatch
'
).
mockReturnValue
(
Promise
.
resolve
());
});
it
(
'
updates commit action and commits
'
,
async
()
=>
{
vm
.
$store
.
state
.
commit
.
commitError
=
createCodeownersCommitError
(
'
test message
'
);
await
vm
.
$nextTick
();
getByText
(
document
.
body
,
'
Create new branch
'
).
click
();
await
waitForPromises
();
expect
(
vm
.
$store
.
dispatch
.
mock
.
calls
).
toEqual
([
[
'
commit/updateCommitAction
'
,
consts
.
COMMIT_TO_NEW_BRANCH
],
[
'
commit/commitChanges
'
,
undefined
],
]);
});
});
});
});
});
});
...
...
spec/frontend/ide/lib/errors_spec.js
0 → 100644
View file @
fbd8cf89
import
{
createUnexpectedCommitError
,
createCodeownersCommitError
,
createBranchChangedCommitError
,
parseCommitError
,
}
from
'
~/ide/lib/errors
'
;
const
TEST_MESSAGE
=
'
Test message
'
;
const
TEST_MESSAGE_WITH_SENTENCE
=
'
Test message.
'
;
const
TEST_MESSAGE_WITH_SENTENCE_AND_SPACE
=
'
Test message.
'
;
const
CODEOWNERS_MESSAGE
=
'
Push to protected branches that contain changes to files matching CODEOWNERS is not allowed
'
;
const
CHANGED_MESSAGE
=
'
Things changed since you started editing
'
;
describe
(
'
~/ide/lib/errors
'
,
()
=>
{
const
createResponseError
=
message
=>
({
response
:
{
data
:
{
message
,
},
},
});
describe
(
'
createCodeownersCommitError
'
,
()
=>
{
it
(
'
uses given message
'
,
()
=>
{
expect
(
createCodeownersCommitError
(
TEST_MESSAGE
)).
toEqual
({
title
:
'
CODEOWNERS rule violation
'
,
message
:
TEST_MESSAGE
,
canCreateBranch
:
true
,
});
});
});
describe
(
'
createBranchChangedCommitError
'
,
()
=>
{
it
.
each
`
message | expectedMessage
${
TEST_MESSAGE
}
|
${
`
${
TEST_MESSAGE
}
. Would you like to create a new branch?`
}
${
TEST_MESSAGE_WITH_SENTENCE
}
|
${
`
${
TEST_MESSAGE
}
. Would you like to create a new branch?`
}
${
TEST_MESSAGE_WITH_SENTENCE_AND_SPACE
}
|
${
`
${
TEST_MESSAGE
}
. Would you like to create a new branch?`
}
`
(
'
uses given message="$message"
'
,
({
message
,
expectedMessage
})
=>
{
expect
(
createBranchChangedCommitError
(
message
)).
toEqual
({
title
:
'
Branch changed
'
,
message
:
expectedMessage
,
canCreateBranch
:
true
,
});
});
});
describe
(
'
parseCommitError
'
,
()
=>
{
it
.
each
`
message | expectation
${
null
}
|
${
createUnexpectedCommitError
()}
${{}}
|
$
{
createUnexpectedCommitError
()}
${{
response
:
{}
}}
|
$
{
createUnexpectedCommitError
()}
${{
response
:
{
data
:
{}
}
}}
|
$
{
createUnexpectedCommitError
()}
${
createResponseError
(
'
test
'
)}
|
${
createUnexpectedCommitError
()}
${
createResponseError
(
CODEOWNERS_MESSAGE
)}
|
${
createCodeownersCommitError
(
CODEOWNERS_MESSAGE
)}
${
createResponseError
(
CHANGED_MESSAGE
)}
|
${
createBranchChangedCommitError
(
CHANGED_MESSAGE
)}
`
(
'
parses message into error object with "$message"
'
,
({
message
,
expectation
})
=>
{
expect
(
parseCommitError
(
message
)).
toEqual
(
expectation
);
});
});
});
spec/frontend/ide/stores/modules/commit/actions_spec.js
View file @
fbd8cf89
...
@@ -9,6 +9,7 @@ import eventHub from '~/ide/eventhub';
...
@@ -9,6 +9,7 @@ import eventHub from '~/ide/eventhub';
import
consts
from
'
~/ide/stores/modules/commit/constants
'
;
import
consts
from
'
~/ide/stores/modules/commit/constants
'
;
import
*
as
mutationTypes
from
'
~/ide/stores/modules/commit/mutation_types
'
;
import
*
as
mutationTypes
from
'
~/ide/stores/modules/commit/mutation_types
'
;
import
*
as
actions
from
'
~/ide/stores/modules/commit/actions
'
;
import
*
as
actions
from
'
~/ide/stores/modules/commit/actions
'
;
import
{
createUnexpectedCommitError
}
from
'
~/ide/lib/errors
'
;
import
{
commitActionTypes
,
PERMISSION_CREATE_MR
}
from
'
~/ide/constants
'
;
import
{
commitActionTypes
,
PERMISSION_CREATE_MR
}
from
'
~/ide/constants
'
;
import
testAction
from
'
../../../../helpers/vuex_action_helper
'
;
import
testAction
from
'
../../../../helpers/vuex_action_helper
'
;
...
@@ -510,7 +511,7 @@ describe('IDE commit module actions', () => {
...
@@ -510,7 +511,7 @@ describe('IDE commit module actions', () => {
});
});
});
});
describe
(
'
failed
'
,
()
=>
{
describe
(
'
success response with failed message
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(()
=>
{
jest
.
spyOn
(
service
,
'
commit
'
).
mockResolvedValue
({
jest
.
spyOn
(
service
,
'
commit
'
).
mockResolvedValue
({
data
:
{
data
:
{
...
@@ -533,6 +534,25 @@ describe('IDE commit module actions', () => {
...
@@ -533,6 +534,25 @@ describe('IDE commit module actions', () => {
});
});
});
});
describe
(
'
failed response
'
,
()
=>
{
beforeEach
(()
=>
{
jest
.
spyOn
(
service
,
'
commit
'
).
mockRejectedValue
({});
});
it
(
'
commits error updates
'
,
async
()
=>
{
jest
.
spyOn
(
store
,
'
commit
'
);
await
store
.
dispatch
(
'
commit/commitChanges
'
).
catch
(()
=>
{});
expect
(
store
.
commit
.
mock
.
calls
).
toEqual
([
expect
.
arrayContaining
([
'
commit/CLEAR_ERROR
'
]),
expect
.
arrayContaining
([
'
commit/UPDATE_LOADING
'
,
true
]),
expect
.
arrayContaining
([
'
commit/UPDATE_LOADING
'
,
false
]),
expect
.
arrayContaining
([
'
commit/SET_ERROR
'
,
createUnexpectedCommitError
()]),
]);
});
});
describe
(
'
first commit of a branch
'
,
()
=>
{
describe
(
'
first commit of a branch
'
,
()
=>
{
const
COMMIT_RESPONSE
=
{
const
COMMIT_RESPONSE
=
{
id
:
'
123456
'
,
id
:
'
123456
'
,
...
...
spec/frontend/ide/stores/modules/commit/mutations_spec.js
View file @
fbd8cf89
import
commitState
from
'
~/ide/stores/modules/commit/state
'
;
import
commitState
from
'
~/ide/stores/modules/commit/state
'
;
import
mutations
from
'
~/ide/stores/modules/commit/mutations
'
;
import
mutations
from
'
~/ide/stores/modules/commit/mutations
'
;
import
*
as
types
from
'
~/ide/stores/modules/commit/mutation_types
'
;
describe
(
'
IDE commit module mutations
'
,
()
=>
{
describe
(
'
IDE commit module mutations
'
,
()
=>
{
let
state
;
let
state
;
...
@@ -62,4 +63,24 @@ describe('IDE commit module mutations', () => {
...
@@ -62,4 +63,24 @@ describe('IDE commit module mutations', () => {
expect
(
state
.
shouldCreateMR
).
toBe
(
false
);
expect
(
state
.
shouldCreateMR
).
toBe
(
false
);
});
});
});
});
describe
(
types
.
CLEAR_ERROR
,
()
=>
{
it
(
'
should clear commitError
'
,
()
=>
{
state
.
commitError
=
{};
mutations
[
types
.
CLEAR_ERROR
](
state
);
expect
(
state
.
commitError
).
toBeNull
();
});
});
describe
(
types
.
SET_ERROR
,
()
=>
{
it
(
'
should set commitError
'
,
()
=>
{
const
error
=
{
title
:
'
foo
'
};
mutations
[
types
.
SET_ERROR
](
state
,
error
);
expect
(
state
.
commitError
).
toBe
(
error
);
});
});
});
});
spec/frontend/lib/utils/text_utility_spec.js
View file @
fbd8cf89
...
@@ -325,4 +325,17 @@ describe('text_utility', () => {
...
@@ -325,4 +325,17 @@ describe('text_utility', () => {
expect
(
textUtils
.
hasContent
(
txt
)).
toEqual
(
result
);
expect
(
textUtils
.
hasContent
(
txt
)).
toEqual
(
result
);
});
});
});
});
describe
(
'
joinSentences
'
,
()
=>
{
it
.
each
`
input | output
${[]}
|
${
''
}
${[
'
Lorem ipsum
'
]}
|
${
'
Lorem ipsum
'
}
${[
'
Lorem ipsum
'
,
null
,
'
Dolar sit
'
]}
|
${
'
Lorem ipsum. Dolar sit
'
}
${[
'
Lorem ipsum!
'
,
'
Dolar sit
'
]}
|
${
'
Lorem ipsum! Dolar sit
'
}
${[
'
Lorem ipsum?
'
,
'
Dolar sit
'
]}
|
${
'
Lorem ipsum? Dolar sit
'
}
`
(
'
joins the sentences with periods ($input)
'
,
({
input
,
output
})
=>
{
expect
(
textUtils
.
joinSentences
(...
input
)).
toBe
(
output
);
});
});
});
});
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