Commit d1085ef8 authored by GitLab Bot's avatar GitLab Bot

Merge remote-tracking branch 'upstream/master' into ce-to-ee-2018-01-18

# Conflicts:
#	app/models/hooks/project_hook.rb

[ci skip]
parents 4431246d 8e9c073a
......@@ -180,6 +180,11 @@ import initLDAPGroupsSelect from 'ee/ldap_groups_select'; // eslint-disable-line
case 'dashboard:todos:index':
import('./pages/dashboard/todos/index').then(callDefault).catch(fail);
break;
case 'admin:jobs:index':
import('./pages/admin/jobs/index')
.then(callDefault)
.catch(fail);
break;
case 'dashboard:projects:index':
case 'dashboard:projects:starred':
import('./pages/dashboard/projects')
......
<script>
import axios from '~/lib/utils/axios_utils';
import Flash from '~/flash';
import modal from '~/vue_shared/components/modal.vue';
import { s__ } from '~/locale';
import { redirectTo } from '~/lib/utils/url_utility';
export default {
components: {
modal,
},
props: {
url: {
type: String,
required: true,
},
},
computed: {
text() {
return s__('AdminArea|You’re about to stop all jobs. This will halt all current jobs that are running.');
},
},
methods: {
onSubmit() {
return axios.post(this.url)
.then((response) => {
// follow the rediect to refresh the page
redirectTo(response.request.responseURL);
})
.catch((error) => {
Flash(s__('AdminArea|Stopping jobs failed'));
throw error;
});
},
},
};
</script>
<template>
<modal
id="stop-jobs-modal"
:title="s__('AdminArea|Stop all jobs?')"
:text="text"
kind="danger"
:primary-button-label="s__('AdminArea|Stop jobs')"
@submit="onSubmit" />
</template>
import Vue from 'vue';
import Translate from '~/vue_shared/translate';
import stopJobsModal from './components/stop_jobs_modal.vue';
Vue.use(Translate);
export default () => {
const stopJobsButton = document.getElementById('stop-jobs-button');
// eslint-disable-next-line no-new
new Vue({
el: '#stop-jobs-modal',
components: {
stopJobsModal,
},
mounted() {
stopJobsButton.classList.remove('disabled');
},
render(createElement) {
return createElement('stop-jobs-modal', {
props: {
url: stopJobsButton.dataset.url,
},
});
},
});
};
......@@ -12,6 +12,7 @@
min-height: $modal-body-height;
position: relative;
padding: #{3 * $grid-size} #{2 * $grid-size};
text-align: left;
.form-actions {
margin: #{2 * $grid-size} #{-2 * $grid-size} #{-2 * $grid-size};
......
......@@ -20,6 +20,6 @@ class Admin::JobsController < Admin::ApplicationController
def cancel_all
Ci::Build.running_or_pending.each(&:cancel)
redirect_to admin_jobs_path
redirect_to admin_jobs_path, status: 303
end
end
class ProjectHook < WebHook
<<<<<<< HEAD
include CustomModelNaming
include TriggerableHooks
self.singular_route_key = :hook
=======
include TriggerableHooks
>>>>>>> upstream/master
triggerable_hooks [
:push_hooks,
:tag_push_hooks,
......
......@@ -9,7 +9,12 @@
.nav-controls
- if @all_builds.running_or_pending.any?
= link_to 'Cancel all', cancel_all_admin_jobs_path, data: { confirm: 'Are you sure?' }, class: 'btn btn-danger', method: :post
#stop-jobs-modal
%button#stop-jobs-button.btn.btn-danger{ data: { toggle: 'modal',
target: '#stop-jobs-modal',
url: cancel_all_admin_jobs_path } }
= s_('AdminArea|Stop all jobs')
.row-content-block.second-block
#{(@scope || 'all').capitalize} jobs
......
......@@ -131,12 +131,13 @@ Available only for admins.
GET /projects/:id/snippets/:snippet_id/user_agent_detail
```
| Attribute | Type | Required | Description |
|-------------|---------|----------|--------------------------------------|
| `id` | Integer | yes | The ID of a snippet |
| Attribute | Type | Required | Description |
|---------------|---------|----------|--------------------------------------|
| `id` | Integer | yes | The ID of a project |
| `snippet_id` | Integer | yes | The ID of a snippet |
```bash
curl --request GET --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/1/snippets/1/user_agent_detail
curl --request GET --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/projects/1/snippets/2/user_agent_detail
```
Example response:
......
......@@ -53,4 +53,3 @@ If you do not have any migrations yet, you will need to create an empty
## Sources
- https://medium.com/@nahtnam/using-phoenix-on-gitlab-ci-5a51eec81142
- https://davejlong.com/ci-with-phoenix-and-gitlab/
......@@ -7,6 +7,7 @@
- Ubuntu
- Debian
- CentOS
- openSUSE
- Red Hat Enterprise Linux (please use the CentOS packages and instructions)
- Scientific Linux (please use the CentOS packages and instructions)
- Oracle Linux (please use the CentOS packages and instructions)
......
......@@ -143,7 +143,7 @@ module API
get ":id/snippets/:snippet_id/user_agent_detail" do
authenticated_as_admin!
snippet = Snippet.find_by!(id: params[:id])
snippet = Snippet.find_by!(id: params[:snippet_id], project_id: params[:id])
return not_found!('UserAgentDetail') unless snippet.user_agent_detail
......
......@@ -21,7 +21,7 @@ describe 'Admin Builds' do
expect(page).to have_selector('.nav-links li.active', text: 'All')
expect(page).to have_selector('.row-content-block', text: 'All jobs')
expect(page.all('.build-link').size).to eq(4)
expect(page).to have_link 'Cancel all'
expect(page).to have_button 'Stop all jobs'
end
end
......@@ -31,7 +31,7 @@ describe 'Admin Builds' do
expect(page).to have_selector('.nav-links li.active', text: 'All')
expect(page).to have_content 'No jobs to show'
expect(page).not_to have_link 'Cancel all'
expect(page).not_to have_button 'Stop all jobs'
end
end
end
......@@ -51,7 +51,7 @@ describe 'Admin Builds' do
expect(page.find('.build-link')).not_to have_content(build2.id)
expect(page.find('.build-link')).not_to have_content(build3.id)
expect(page.find('.build-link')).not_to have_content(build4.id)
expect(page).to have_link 'Cancel all'
expect(page).to have_button 'Stop all jobs'
end
end
......@@ -63,7 +63,7 @@ describe 'Admin Builds' do
expect(page).to have_selector('.nav-links li.active', text: 'Pending')
expect(page).to have_content 'No jobs to show'
expect(page).not_to have_link 'Cancel all'
expect(page).not_to have_button 'Stop all jobs'
end
end
end
......@@ -83,7 +83,7 @@ describe 'Admin Builds' do
expect(page.find('.build-link')).not_to have_content(build2.id)
expect(page.find('.build-link')).not_to have_content(build3.id)
expect(page.find('.build-link')).not_to have_content(build4.id)
expect(page).to have_link 'Cancel all'
expect(page).to have_button 'Stop all jobs'
end
end
......@@ -95,7 +95,7 @@ describe 'Admin Builds' do
expect(page).to have_selector('.nav-links li.active', text: 'Running')
expect(page).to have_content 'No jobs to show'
expect(page).not_to have_link 'Cancel all'
expect(page).not_to have_button 'Stop all jobs'
end
end
end
......@@ -113,7 +113,7 @@ describe 'Admin Builds' do
expect(page.find('.build-link')).not_to have_content(build1.id)
expect(page.find('.build-link')).not_to have_content(build2.id)
expect(page.find('.build-link')).to have_content(build3.id)
expect(page).to have_link 'Cancel all'
expect(page).to have_button 'Stop all jobs'
end
end
......@@ -125,7 +125,7 @@ describe 'Admin Builds' do
expect(page).to have_selector('.nav-links li.active', text: 'Finished')
expect(page).to have_content 'No jobs to show'
expect(page).to have_link 'Cancel all'
expect(page).to have_button 'Stop all jobs'
end
end
end
......
import Vue from 'vue';
import axios from '~/lib/utils/axios_utils';
import stopJobsModal from '~/pages/admin/jobs/index/components/stop_jobs_modal.vue';
import * as urlUtility from '~/lib/utils/url_utility';
import mountComponent from '../../../../../helpers/vue_mount_component_helper';
describe('stop_jobs_modal.vue', () => {
const props = {
url: `${gl.TEST_HOST}/stop_jobs_modal.vue/stopAll`,
};
let vm;
afterEach(() => {
vm.$destroy();
});
beforeEach(() => {
const Component = Vue.extend(stopJobsModal);
vm = mountComponent(Component, props);
});
describe('onSubmit', () => {
it('stops jobs and redirects to overview page', (done) => {
const responseURL = `${gl.TEST_HOST}/stop_jobs_modal.vue/jobs`;
const redirectSpy = spyOn(urlUtility, 'redirectTo');
spyOn(axios, 'post').and.callFake((url) => {
expect(url).toBe(props.url);
return Promise.resolve({
request: {
responseURL,
},
});
});
vm.onSubmit()
.then(() => {
expect(redirectSpy).toHaveBeenCalledWith(responseURL);
})
.then(done)
.catch(done.fail);
});
it('displays error if stopping jobs failed', (done) => {
const dummyError = new Error('stopping jobs failed');
const redirectSpy = spyOn(urlUtility, 'redirectTo');
spyOn(axios, 'post').and.callFake((url) => {
expect(url).toBe(props.url);
return Promise.reject(dummyError);
});
vm.onSubmit()
.then(done.fail)
.catch((error) => {
expect(error).toBe(dummyError);
expect(redirectSpy).not.toHaveBeenCalled();
})
.then(done)
.catch(done.fail);
});
});
});
require 'rails_helper'
describe API::ProjectSnippets do
let(:project) { create(:project, :public) }
let(:user) { create(:user) }
let(:admin) { create(:admin) }
set(:project) { create(:project, :public) }
set(:user) { create(:user) }
set(:admin) { create(:admin) }
describe "GET /projects/:project_id/snippets/:id/user_agent_detail" do
let(:snippet) { create(:project_snippet, :public, project: project) }
......@@ -18,6 +18,13 @@ describe API::ProjectSnippets do
expect(json_response['akismet_submitted']).to eq(user_agent_detail.submitted)
end
it 'respects project scoping' do
other_project = create(:project)
get api("/projects/#{other_project.id}/snippets/#{snippet.id}/user_agent_detail", admin)
expect(response).to have_gitlab_http_status(404)
end
it "returns unautorized for non-admin users" do
get api("/projects/#{snippet.project.id}/snippets/#{snippet.id}/user_agent_detail", user)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment