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
646d7c65
Commit
646d7c65
authored
May 07, 2021
by
Robert Hunt
Committed by
Natalia Tepluhina
May 07, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add listing app to show status checks
parent
474cbba8
Changes
25
Hide whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
644 additions
and
0 deletions
+644
-0
ee/app/assets/javascripts/pages/projects/edit/index.js
ee/app/assets/javascripts/pages/projects/edit/index.js
+2
-0
ee/app/assets/javascripts/status_checks/components/actions.vue
...p/assets/javascripts/status_checks/components/actions.vue
+23
-0
ee/app/assets/javascripts/status_checks/components/branch.vue
...pp/assets/javascripts/status_checks/components/branch.vue
+25
-0
ee/app/assets/javascripts/status_checks/components/status_checks.vue
...ts/javascripts/status_checks/components/status_checks.vue
+79
-0
ee/app/assets/javascripts/status_checks/mount.js
ee/app/assets/javascripts/status_checks/mount.js
+33
-0
ee/app/assets/javascripts/status_checks/store/actions.js
ee/app/assets/javascripts/status_checks/store/actions.js
+12
-0
ee/app/assets/javascripts/status_checks/store/index.js
ee/app/assets/javascripts/status_checks/store/index.js
+14
-0
ee/app/assets/javascripts/status_checks/store/mutation_types.js
.../assets/javascripts/status_checks/store/mutation_types.js
+2
-0
ee/app/assets/javascripts/status_checks/store/mutations.js
ee/app/assets/javascripts/status_checks/store/mutations.js
+10
-0
ee/app/assets/javascripts/status_checks/store/state.js
ee/app/assets/javascripts/status_checks/store/state.js
+4
-0
ee/app/helpers/ee/projects_helper.rb
ee/app/helpers/ee/projects_helper.rb
+8
-0
ee/app/views/projects/_merge_request_settings.html.haml
ee/app/views/projects/_merge_request_settings.html.haml
+3
-0
ee/app/views/projects/_merge_request_status_checks_settings.html.haml
.../projects/_merge_request_status_checks_settings.html.haml
+10
-0
ee/spec/frontend/status_checks/components/actions_spec.js
ee/spec/frontend/status_checks/components/actions_spec.js
+34
-0
ee/spec/frontend/status_checks/components/branch_spec.js
ee/spec/frontend/status_checks/components/branch_spec.js
+32
-0
ee/spec/frontend/status_checks/components/status_checks_spec.js
...c/frontend/status_checks/components/status_checks_spec.js
+94
-0
ee/spec/frontend/status_checks/mount_spec.js
ee/spec/frontend/status_checks/mount_spec.js
+60
-0
ee/spec/frontend/status_checks/store/actions_spec.js
ee/spec/frontend/status_checks/store/actions_spec.js
+41
-0
ee/spec/frontend/status_checks/store/index_spec.js
ee/spec/frontend/status_checks/store/index_spec.js
+10
-0
ee/spec/frontend/status_checks/store/mutations_spec.js
ee/spec/frontend/status_checks/store/mutations_spec.js
+33
-0
ee/spec/frontend/status_checks/store/state_spec.js
ee/spec/frontend/status_checks/store/state_spec.js
+10
-0
ee/spec/helpers/projects_helper_spec.rb
ee/spec/helpers/projects_helper_spec.rb
+8
-0
ee/spec/views/projects/_merge_request_status_checks_settings.html.haml_spec.rb
...s/_merge_request_status_checks_settings.html.haml_spec.rb
+33
-0
ee/spec/views/projects/edit.html.haml_spec.rb
ee/spec/views/projects/edit.html.haml_spec.rb
+43
-0
locale/gitlab.pot
locale/gitlab.pot
+21
-0
No files found.
ee/app/assets/javascripts/pages/projects/edit/index.js
View file @
646d7c65
...
...
@@ -4,6 +4,7 @@ import '~/pages/projects/edit';
import
mountApprovals
from
'
ee/approvals/mount_project_settings
'
;
import
initMergeOptionSettings
from
'
ee/pages/projects/edit/merge_options
'
;
import
initProjectAdjournedDeleteButton
from
'
ee/projects/project_adjourned_delete_button
'
;
import
mountStatusChecks
from
'
ee/status_checks/mount
'
;
import
groupsSelect
from
'
~/groups_select
'
;
import
UserCallout
from
'
~/user_callout
'
;
import
UsersSelect
from
'
~/users_select
'
;
...
...
@@ -14,6 +15,7 @@ groupsSelect();
new
UserCallout
({
className
:
'
js-mr-approval-callout
'
});
mountApprovals
(
document
.
getElementById
(
'
js-mr-approvals-settings
'
));
mountStatusChecks
(
document
.
getElementById
(
'
js-status-checks-settings
'
));
initProjectAdjournedDeleteButton
();
initMergeOptionSettings
();
ee/app/assets/javascripts/status_checks/components/actions.vue
0 → 100644
View file @
646d7c65
<
script
>
import
{
GlButton
}
from
'
@gitlab/ui
'
;
import
{
__
}
from
'
~/locale
'
;
export
default
{
components
:
{
GlButton
,
},
i18n
:
{
editButton
:
__
(
'
Edit
'
),
removeButton
:
__
(
'
Remove...
'
),
},
};
</
script
>
<
template
>
<div
class=
"gl-display-flex gl-justify-content-end"
>
<gl-button
data-testid=
"edit-btn"
>
{{
$options
.
i18n
.
editButton
}}
</gl-button>
<gl-button
class=
"gl-ml-3"
data-testid=
"remove-btn"
>
{{
$options
.
i18n
.
removeButton
}}
</gl-button>
</div>
</
template
>
ee/app/assets/javascripts/status_checks/components/branch.vue
0 → 100644
View file @
646d7c65
<
script
>
import
{
__
}
from
'
~/locale
'
;
export
default
{
props
:
{
branches
:
{
type
:
Array
,
required
:
false
,
default
:
()
=>
[],
},
},
computed
:
{
isAnyBranch
()
{
return
!
this
.
branches
?.
length
;
},
branchName
()
{
return
this
.
isAnyBranch
?
__
(
'
Any branch
'
)
:
this
.
branches
[
0
].
name
;
},
},
};
</
script
>
<
template
>
<span
:class=
"
{ monospace: isAnyBranch }">
{{
branchName
}}
</span>
</
template
>
ee/app/assets/javascripts/status_checks/components/status_checks.vue
0 → 100644
View file @
646d7c65
<
script
>
import
{
GlButton
,
GlTable
}
from
'
@gitlab/ui
'
;
import
{
mapState
}
from
'
vuex
'
;
import
{
__
,
s__
}
from
'
~/locale
'
;
import
Actions
from
'
./actions.vue
'
;
import
Branch
from
'
./branch.vue
'
;
const
DEFAULT_TH_CLASSES
=
'
gl-bg-transparent! gl-border-b-solid! gl-border-b-gray-100! gl-p-5! gl-border-b-1!
'
;
const
thWidthClass
=
(
width
)
=>
`gl-w-
${
width
}
p
${
DEFAULT_TH_CLASSES
}
`
;
export
const
i18n
=
{
addButton
:
s__
(
'
StatusCheck|Add status check
'
),
apiHeader
:
__
(
'
API
'
),
branchHeader
:
__
(
'
Target branch
'
),
emptyTableText
:
s__
(
'
StatusCheck|No status checks are defined yet.
'
),
nameHeader
:
s__
(
'
StatusCheck|Service name
'
),
};
export
default
{
components
:
{
Actions
,
Branch
,
GlButton
,
GlTable
,
},
computed
:
{
...
mapState
([
'
statusChecks
'
]),
},
fields
:
[
{
key
:
'
name
'
,
label
:
i18n
.
nameHeader
,
thClass
:
thWidthClass
(
20
),
},
{
key
:
'
externalUrl
'
,
label
:
i18n
.
apiHeader
,
thClass
:
thWidthClass
(
40
),
},
{
key
:
'
protectedBranches
'
,
label
:
i18n
.
branchHeader
,
thClass
:
thWidthClass
(
20
),
},
{
key
:
'
actions
'
,
label
:
''
,
thClass
:
DEFAULT_TH_CLASSES
,
tdClass
:
'
gl-text-right
'
,
},
],
i18n
,
};
</
script
>
<
template
>
<div>
<gl-table
:items=
"statusChecks"
:fields=
"$options.fields"
primary-key=
"id"
:empty-text=
"$options.i18n.emptyTableText"
show-empty
stacked=
"md"
>
<template
#cell(protectedBranches)=
"
{ item }">
<branch
:branches=
"item.protectedBranches"
/>
</
template
>
<
template
#cell
(
actions
)
>
<actions
/>
</
template
>
</gl-table>
<gl-button
category=
"secondary"
variant=
"confirm"
size=
"small"
>
{{ $options.i18n.addButton }}
</gl-button>
</div>
</template>
ee/app/assets/javascripts/status_checks/mount.js
0 → 100644
View file @
646d7c65
import
Vue
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
createFlash
from
'
~/flash
'
;
import
{
s__
}
from
'
~/locale
'
;
import
StatusChecks
from
'
./components/status_checks.vue
'
;
import
createStore
from
'
./store
'
;
Vue
.
use
(
Vuex
);
export
default
function
mountProjectSettingsApprovals
(
el
)
{
if
(
!
el
)
{
return
null
;
}
const
store
=
createStore
();
const
{
statusChecksPath
}
=
el
.
dataset
;
store
.
dispatch
(
'
fetchStatusChecks
'
,
{
statusChecksPath
}).
catch
((
error
)
=>
{
createFlash
({
message
:
s__
(
'
StatusCheck|An error occurred fetching the status checks.
'
),
captureError
:
true
,
error
,
});
});
return
new
Vue
({
el
,
store
,
render
(
h
)
{
return
h
(
StatusChecks
);
},
});
}
ee/app/assets/javascripts/status_checks/store/actions.js
0 → 100644
View file @
646d7c65
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
{
convertObjectPropsToCamelCase
}
from
'
~/lib/utils/common_utils
'
;
import
*
as
types
from
'
./mutation_types
'
;
export
const
fetchStatusChecks
=
({
commit
},
{
statusChecksPath
})
=>
{
commit
(
types
.
SET_LOADING
,
true
);
return
axios
.
get
(
statusChecksPath
).
then
(({
data
})
=>
{
commit
(
types
.
SET_STATUS_CHECKS
,
convertObjectPropsToCamelCase
(
data
,
{
deep
:
true
}));
commit
(
types
.
SET_LOADING
,
false
);
});
};
ee/app/assets/javascripts/status_checks/store/index.js
0 → 100644
View file @
646d7c65
import
Vue
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
*
as
actions
from
'
./actions
'
;
import
mutations
from
'
./mutations
'
;
import
createState
from
'
./state
'
;
Vue
.
use
(
Vuex
);
export
default
()
=>
new
Vuex
.
Store
({
actions
,
mutations
,
state
:
createState
(),
});
ee/app/assets/javascripts/status_checks/store/mutation_types.js
0 → 100644
View file @
646d7c65
export
const
SET_LOADING
=
'
SET_LOADING
'
;
export
const
SET_STATUS_CHECKS
=
'
SET_STATUS_CHECKS
'
;
ee/app/assets/javascripts/status_checks/store/mutations.js
0 → 100644
View file @
646d7c65
import
*
as
types
from
'
./mutation_types
'
;
export
default
{
[
types
.
SET_LOADING
](
state
,
isLoading
)
{
state
.
isLoading
=
isLoading
;
},
[
types
.
SET_STATUS_CHECKS
](
state
,
statusChecks
)
{
state
.
statusChecks
=
statusChecks
;
},
};
ee/app/assets/javascripts/status_checks/store/state.js
0 → 100644
View file @
646d7c65
export
default
()
=>
({
isLoading
:
false
,
statusChecks
:
[],
});
ee/app/helpers/ee/projects_helper.rb
View file @
646d7c65
...
...
@@ -118,6 +118,14 @@ module EE
{
data:
data
}
end
def
status_checks_app_data
(
project
)
{
data:
{
status_checks_path:
expose_path
(
api_v4_projects_external_approval_rules_path
(
id:
project
.
id
))
}
}
end
def
can_modify_approvers
(
project
=
@project
)
can?
(
current_user
,
:modify_approvers_rules
,
project
)
end
...
...
ee/app/views/projects/_merge_request_settings.html.haml
View file @
646d7c65
...
...
@@ -8,6 +8,9 @@
=
render_ce
'projects/merge_request_merge_checks_settings'
,
project:
@project
,
form:
form
-
if
::
Feature
.
enabled?
(
:ff_compliance_approval_gates
,
@project
,
default_enabled: :yaml
)
=
render_if_exists
'projects/merge_request_status_checks_settings'
=
render
'projects/merge_request_merge_suggestions_settings'
,
project:
@project
,
form:
form
-
if
@project
.
forked?
...
...
ee/app/views/projects/_merge_request_status_checks_settings.html.haml
0 → 100644
View file @
646d7c65
.form-group
%b
=
s_
(
'StatusCheck|Status checks'
)
%p
.text-secondary
// Update the documentation link once https://gitlab.com/gitlab-org/gitlab/-/issues/329517 is complete
-
link_start
=
'<a href="%{url}" target="_blank" rel="noopener noreferrer">'
.
html_safe
%
{
url:
''
}
=
s_
(
'StatusCheck|Check for a status response in Merge Requests. Failures do not block merges. %{link_start}Learn more%{link_end}.'
).
html_safe
%
{
link_start:
link_start
,
link_end:
'</a>'
.
html_safe
}
#js-status-checks-settings
{
status_checks_app_data
(
@project
)
}
.text-center.gl-mt-3
=
sprite_icon
(
'spinner'
,
size:
24
,
css_class:
'gl-spinner'
)
ee/spec/frontend/status_checks/components/actions_spec.js
0 → 100644
View file @
646d7c65
import
{
GlButton
}
from
'
@gitlab/ui
'
;
import
Actions
from
'
ee/status_checks/components/actions.vue
'
;
import
{
shallowMountExtended
}
from
'
helpers/vue_test_utils_helper
'
;
describe
(
'
Status checks actions
'
,
()
=>
{
let
wrapper
;
const
createWrapper
=
()
=>
{
wrapper
=
shallowMountExtended
(
Actions
,
{
stubs
:
{
GlButton
,
},
});
};
afterEach
(()
=>
{
wrapper
.
destroy
();
});
const
findEditBtn
=
()
=>
wrapper
.
findByTestId
(
'
edit-btn
'
);
const
findRemoveBtn
=
()
=>
wrapper
.
findByTestId
(
'
remove-btn
'
);
it
(
'
renders the edit button
'
,
()
=>
{
createWrapper
();
expect
(
findEditBtn
().
text
()).
toBe
(
'
Edit
'
);
});
it
(
'
renders the remove button
'
,
()
=>
{
createWrapper
();
expect
(
findRemoveBtn
().
text
()).
toBe
(
'
Remove...
'
);
});
});
ee/spec/frontend/status_checks/components/branch_spec.js
0 → 100644
View file @
646d7c65
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
Branch
from
'
ee/status_checks/components/branch.vue
'
;
describe
(
'
Status checks branch
'
,
()
=>
{
let
wrapper
;
const
createWrapper
=
(
props
=
{})
=>
{
wrapper
=
shallowMount
(
Branch
,
{
propsData
:
props
,
});
};
afterEach
(()
=>
{
wrapper
.
destroy
();
});
const
findBranch
=
()
=>
wrapper
.
find
(
'
span
'
);
it
(
'
renders "Any branch" if no branch is given
'
,
()
=>
{
createWrapper
();
expect
(
findBranch
().
text
()).
toBe
(
'
Any branch
'
);
expect
(
findBranch
().
classes
(
'
monospace
'
)).
toBe
(
true
);
});
it
(
'
renders the first branch name when branches are given
'
,
()
=>
{
createWrapper
({
branches
:
[{
name
:
'
Foo
'
},
{
name
:
'
Bar
'
}]
});
expect
(
findBranch
().
text
()).
toBe
(
'
Foo
'
);
expect
(
findBranch
().
classes
(
'
monospace
'
)).
toBe
(
false
);
});
});
ee/spec/frontend/status_checks/components/status_checks_spec.js
0 → 100644
View file @
646d7c65
import
{
GlButton
,
GlTable
}
from
'
@gitlab/ui
'
;
import
{
mount
,
shallowMount
}
from
'
@vue/test-utils
'
;
import
Vue
from
'
vue
'
;
import
Vuex
from
'
vuex
'
;
import
Actions
from
'
ee/status_checks/components/actions.vue
'
;
import
Branch
from
'
ee/status_checks/components/branch.vue
'
;
import
StatusChecks
,
{
i18n
}
from
'
ee/status_checks/components/status_checks.vue
'
;
import
createStore
from
'
ee/status_checks/store
'
;
import
{
SET_STATUS_CHECKS
}
from
'
ee/status_checks/store/mutation_types
'
;
Vue
.
use
(
Vuex
);
describe
(
'
Status checks
'
,
()
=>
{
let
store
;
let
wrapper
;
const
createWrapper
=
(
mountFn
=
mount
)
=>
{
store
=
createStore
();
wrapper
=
mountFn
(
StatusChecks
,
{
store
});
};
afterEach
(()
=>
{
wrapper
.
destroy
();
});
const
findAddButton
=
()
=>
wrapper
.
findComponent
(
GlButton
);
const
findTable
=
()
=>
wrapper
.
findComponent
(
GlTable
);
const
findHeaders
=
()
=>
findTable
().
find
(
'
thead
'
).
find
(
'
tr
'
).
findAll
(
'
th
'
);
const
findBranch
=
(
trIdx
)
=>
wrapper
.
findAllComponents
(
Branch
).
at
(
trIdx
);
const
findActions
=
(
trIdx
)
=>
wrapper
.
findAllComponents
(
Actions
).
at
(
trIdx
);
const
findCell
=
(
trIdx
,
tdIdx
)
=>
{
return
findTable
().
find
(
'
tbody
'
).
findAll
(
'
tr
'
).
at
(
trIdx
).
findAll
(
'
td
'
).
at
(
tdIdx
);
};
describe
(
'
Initially
'
,
()
=>
{
it
(
'
renders the table
'
,
()
=>
{
createWrapper
(
shallowMount
);
expect
(
findTable
().
exists
()).
toBe
(
true
);
});
it
(
'
renders the empty state when no status checks exist
'
,
()
=>
{
createWrapper
();
expect
(
findCell
(
0
,
0
).
text
()).
toBe
(
i18n
.
emptyTableText
);
});
it
(
'
renders the add button
'
,
()
=>
{
createWrapper
(
shallowMount
);
expect
(
findAddButton
().
text
()).
toBe
(
i18n
.
addButton
);
});
});
describe
(
'
Filled table
'
,
()
=>
{
const
statusChecks
=
[
{
name
:
'
Foo
'
,
externalUrl
:
'
http://foo.com/api
'
,
protectedBranches
:
[]
},
{
name
:
'
Bar
'
,
externalUrl
:
'
http://bar.com/api
'
,
protectedBranches
:
[{
name
:
'
main
'
}]
},
];
beforeEach
(()
=>
{
createWrapper
();
store
.
commit
(
SET_STATUS_CHECKS
,
statusChecks
);
});
it
(
'
renders the headers
'
,
()
=>
{
expect
(
findHeaders
()).
toHaveLength
(
4
);
expect
(
findHeaders
().
at
(
0
).
text
()).
toBe
(
i18n
.
nameHeader
);
expect
(
findHeaders
().
at
(
1
).
text
()).
toBe
(
i18n
.
apiHeader
);
expect
(
findHeaders
().
at
(
2
).
text
()).
toBe
(
i18n
.
branchHeader
);
expect
(
findHeaders
().
at
(
3
).
text
()).
toBe
(
''
);
});
describe
.
each
(
statusChecks
)(
'
status check %#
'
,
(
statusCheck
)
=>
{
const
index
=
statusChecks
.
indexOf
(
statusCheck
);
it
(
'
renders the name
'
,
()
=>
{
expect
(
findCell
(
index
,
0
).
text
()).
toBe
(
statusCheck
.
name
);
});
it
(
'
renders the URL
'
,
()
=>
{
expect
(
findCell
(
index
,
1
).
text
()).
toBe
(
statusCheck
.
externalUrl
);
});
it
(
'
renders the branch
'
,
()
=>
{
expect
(
findBranch
(
index
,
1
).
props
(
'
branches
'
)).
toBe
(
statusCheck
.
protectedBranches
);
});
it
(
'
renders the actions
'
,
()
=>
{
expect
(
findActions
(
index
,
1
).
exists
()).
toBe
(
true
);
});
});
});
});
ee/spec/frontend/status_checks/mount_spec.js
0 → 100644
View file @
646d7c65
import
{
createWrapper
}
from
'
@vue/test-utils
'
;
import
mountStatusChecks
from
'
ee/status_checks/mount
'
;
import
createStore
from
'
ee/status_checks/store
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
import
createFlash
from
'
~/flash
'
;
jest
.
mock
(
'
ee/status_checks/store
'
);
jest
.
mock
(
'
~/flash
'
);
describe
(
'
mountStatusChecks
'
,
()
=>
{
const
statusChecksPath
=
'
/api/v4/projects/1/external_approval_rules
'
;
const
dispatch
=
jest
.
fn
();
let
el
;
const
setUpDocument
=
()
=>
{
el
=
document
.
createElement
(
'
div
'
);
el
.
setAttribute
(
'
data-status-checks-path
'
,
statusChecksPath
);
document
.
body
.
appendChild
(
el
);
return
el
;
};
beforeEach
(()
=>
{
createStore
.
mockReturnValue
({
dispatch
,
state
:
{
statusChecks
:
[]
}
});
setUpDocument
();
});
afterEach
(()
=>
{
el
.
remove
();
el
=
null
;
});
it
(
'
returns null if no element is given
'
,
()
=>
{
expect
(
mountStatusChecks
()).
toBeNull
();
});
it
(
'
returns the Vue component
'
,
async
()
=>
{
dispatch
.
mockResolvedValue
({});
const
wrapper
=
createWrapper
(
mountStatusChecks
(
el
));
expect
(
dispatch
).
toHaveBeenCalledWith
(
'
fetchStatusChecks
'
,
{
statusChecksPath
});
expect
(
wrapper
.
exists
()).
toBe
(
true
);
});
it
(
'
returns the Vue component with an error if fetchStatusChecks fails
'
,
async
()
=>
{
const
error
=
new
Error
(
'
Something went wrong
'
);
dispatch
.
mockRejectedValueOnce
(
error
);
const
wrapper
=
createWrapper
(
mountStatusChecks
(
el
));
await
waitForPromises
();
expect
(
createFlash
).
toHaveBeenCalledWith
({
message
:
'
An error occurred fetching the status checks.
'
,
captureError
:
true
,
error
,
});
expect
(
wrapper
.
exists
()).
toBe
(
true
);
});
});
ee/spec/frontend/status_checks/store/actions_spec.js
0 → 100644
View file @
646d7c65
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
*
as
actions
from
'
ee/status_checks/store/actions
'
;
import
*
as
types
from
'
ee/status_checks/store/mutation_types
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
httpStatusCodes
from
'
~/lib/utils/http_status
'
;
const
statusChecksPath
=
'
/api/v4/projects/1/external_approval_rules
'
;
const
commit
=
jest
.
fn
();
let
mockAxios
;
describe
(
'
Status checks actions
'
,
()
=>
{
beforeEach
(()
=>
{
mockAxios
=
new
MockAdapter
(
axios
);
});
afterEach
(()
=>
{
mockAxios
.
restore
();
});
it
(
`should commit the API response`
,
async
()
=>
{
const
data
=
[{
name
:
'
Foo
'
},
{
name
:
'
Bar
'
}];
mockAxios
.
onGet
(
statusChecksPath
).
replyOnce
(
httpStatusCodes
.
OK
,
data
);
await
actions
.
fetchStatusChecks
({
commit
},
{
statusChecksPath
});
expect
(
commit
).
toHaveBeenCalledWith
(
types
.
SET_LOADING
,
true
);
expect
(
commit
).
toHaveBeenCalledWith
(
types
.
SET_STATUS_CHECKS
,
data
);
expect
(
commit
).
toHaveBeenCalledWith
(
types
.
SET_LOADING
,
false
);
});
it
(
'
should error with a failed API response
'
,
async
()
=>
{
mockAxios
.
onGet
(
statusChecksPath
).
networkError
();
await
expect
(
actions
.
fetchStatusChecks
({
commit
},
{
statusChecksPath
})).
rejects
.
toThrow
(
new
Error
(
'
Network Error
'
),
);
expect
(
commit
).
toHaveBeenCalledWith
(
types
.
SET_LOADING
,
true
);
expect
(
commit
).
toHaveBeenCalledTimes
(
1
);
});
});
ee/spec/frontend/status_checks/store/index_spec.js
0 → 100644
View file @
646d7c65
import
createStore
from
'
ee/status_checks/store
'
;
describe
(
'
createStore
'
,
()
=>
{
it
(
'
creates a new store
'
,
()
=>
{
expect
(
createStore
().
state
).
toStrictEqual
({
isLoading
:
false
,
statusChecks
:
[],
});
});
});
ee/spec/frontend/status_checks/store/mutations_spec.js
0 → 100644
View file @
646d7c65
import
*
as
types
from
'
ee/status_checks/store/mutation_types
'
;
import
mutations
from
'
ee/status_checks/store/mutations
'
;
import
initialState
from
'
ee/status_checks/store/state
'
;
describe
(
'
Status checks mutations
'
,
()
=>
{
let
state
;
beforeEach
(()
=>
{
state
=
initialState
();
});
describe
(
types
.
SET_LOADING
,
()
=>
{
it
(
'
sets isLoading
'
,
()
=>
{
expect
(
state
.
isLoading
).
toBe
(
false
);
mutations
[
types
.
SET_LOADING
](
state
,
true
);
expect
(
state
.
isLoading
).
toBe
(
true
);
});
});
describe
(
types
.
SET_STATUS_CHECKS
,
()
=>
{
it
(
'
sets the statusChecks
'
,
()
=>
{
const
statusChecks
=
[{
name
:
'
Foo
'
},
{
name
:
'
Bar
'
}];
expect
(
state
.
statusChecks
).
toStrictEqual
([]);
mutations
[
types
.
SET_STATUS_CHECKS
](
state
,
statusChecks
);
expect
(
state
.
statusChecks
).
toStrictEqual
(
statusChecks
);
});
});
});
ee/spec/frontend/status_checks/store/state_spec.js
0 → 100644
View file @
646d7c65
import
initialState
from
'
ee/status_checks/store/state
'
;
describe
(
'
state
'
,
()
=>
{
it
(
'
returns the expected default state
'
,
()
=>
{
expect
(
initialState
()).
toStrictEqual
({
isLoading
:
false
,
statusChecks
:
[],
});
});
});
ee/spec/helpers/projects_helper_spec.rb
View file @
646d7c65
...
...
@@ -378,4 +378,12 @@ RSpec.describe ProjectsHelper do
end
end
end
describe
'#status_checks_app_data'
do
subject
{
helper
.
status_checks_app_data
(
project
)
}
it
'returns the correct data'
do
expect
(
subject
[
:data
]).
to
eq
({
status_checks_path:
expose_path
(
api_v4_projects_external_approval_rules_path
(
id:
project
.
id
))
})
end
end
end
ee/spec/views/projects/_merge_request_status_checks_settings.html.haml_spec.rb
0 → 100644
View file @
646d7c65
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
'projects/_merge_request_status_checks_settings'
do
let
(
:project
)
{
build
(
:project
)
}
before
do
assign
(
:project
,
project
)
allow
(
view
).
to
receive
(
:status_checks_app_data
).
and_return
({
data:
{
status_checks_path:
'status-checks/path'
}
})
render
partial:
'projects/merge_request_status_checks_settings'
end
it
'renders the settings title'
do
expect
(
rendered
).
to
have_content
'Status checks'
end
it
'renders the settings description'
,
:aggregate_failures
do
expect
(
rendered
).
to
have_content
'Check for a status response in Merge Requests. Failures do not block merges.'
expect
(
rendered
).
to
have_link
'Learn more'
,
href:
''
end
it
'renders the settings app element'
,
:aggregate_failures
do
expect
(
rendered
).
to
have_selector
'#js-status-checks-settings'
expect
(
rendered
).
to
have_selector
"[data-status-checks-path='status-checks/path']"
end
it
'renders the loading spinner'
do
expect
(
rendered
).
to
have_selector
'.gl-spinner'
end
end
ee/spec/views/projects/edit.html.haml_spec.rb
0 → 100644
View file @
646d7c65
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
'projects/edit'
do
let
(
:project
)
{
create
(
:project
)
}
let
(
:user
)
{
create
(
:admin
)
}
before
do
assign
(
:project
,
project
)
allow
(
controller
).
to
receive
(
:current_user
).
and_return
(
user
)
allow
(
view
).
to
receive_messages
(
current_user:
user
,
can?:
true
,
current_application_settings:
Gitlab
::
CurrentSettings
.
current_application_settings
)
end
context
'status checks'
do
context
'feature enabled'
do
before
do
stub_feature_flags
(
ff_compliance_approval_gates:
true
)
render
end
it
'shows the status checks area'
do
expect
(
rendered
).
to
have_content
(
'Status check'
)
end
end
context
'feature disabled'
do
before
do
stub_feature_flags
(
ff_compliance_approval_gates:
false
)
render
end
it
'hides the status checks area'
do
expect
(
rendered
).
not_to
have_content
(
'Status check'
)
end
end
end
end
locale/gitlab.pot
View file @
646d7c65
...
...
@@ -26984,6 +26984,9 @@ msgstr ""
msgid "Remove user from project"
msgstr ""
msgid "Remove..."
msgstr ""
msgid "Removed"
msgstr ""
...
...
@@ -30641,15 +30644,33 @@ msgstr ""
msgid "StatusCheck|API to check"
msgstr ""
msgid "StatusCheck|Add status check"
msgstr ""
msgid "StatusCheck|An error occurred fetching the status checks."
msgstr ""
msgid "StatusCheck|Check for a status response in Merge Requests. Failures do not block merges. %{link_start}Learn more%{link_end}."
msgstr ""
msgid "StatusCheck|Invoke an external API as part of the approvals"
msgstr ""
msgid "StatusCheck|No status checks are defined yet."
msgstr ""
msgid "StatusCheck|Remove status check"
msgstr ""
msgid "StatusCheck|Remove status check?"
msgstr ""
msgid "StatusCheck|Service name"
msgstr ""
msgid "StatusCheck|Status checks"
msgstr ""
msgid "StatusCheck|Status to check"
msgstr ""
...
...
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