Commit 45fdfaa3 authored by GitLab Bot's avatar GitLab Bot

Merge remote-tracking branch 'upstream/master' into ce-to-ee-2018-08-19

# Conflicts:
#	app/services/protected_branches/legacy_api_update_service.rb
#	app/services/users/destroy_service.rb
#	db/post_migrate/20180723130817_delete_inconsistent_internal_id_records.rb
#	spec/migrations/delete_inconsistent_internal_id_records_spec.rb
#	spec/spec_helper.rb

[ci skip]
parents b8f2f711 00baed8c
<script>
import CiIcon from '~/vue_shared/components/ci_icon.vue';
import Icon from '~/vue_shared/components/icon.vue';
import tooltip from '~/vue_shared/directives/tooltip';
export default {
components: {
CiIcon,
Icon,
},
directives: {
tooltip,
},
props: {
jobs: {
type: Array,
required: true,
},
},
};
</script>
<template>
<div class="builds-container">
<div
class="build-job"
>
<a
v-tooltip
v-for="job in jobs"
:key="job.id"
:href="job.path"
:title="job.tooltip"
:class="{ active: job.active, retried: job.retried }"
>
<icon
v-if="job.active"
name="arrow-right"
class="js-arrow-right"
/>
<ci-icon :status="job.status" />
<span>
<template v-if="job.name">
{{ job.name }}
</template>
<template v-else>
{{ job.id }}
</template>
</span>
<icon
v-if="job.retried"
name="retry"
class="js-retry-icon"
/>
</a>
</div>
</div>
</template>
<script>
import CiIcon from '~/vue_shared/components/ci_icon.vue';
import Icon from '~/vue_shared/components/icon.vue';
import { sprintf, __ } from '~/locale';
export default {
components: {
CiIcon,
Icon,
},
props: {
pipelineId: {
type: Number,
required: true,
},
pipelinePath: {
type: String,
required: true,
},
pipelineRef: {
type: String,
required: true,
},
pipelineRefPath: {
type: String,
required: true,
},
stages: {
type: Array,
required: true,
},
pipelineStatus: {
type: Object,
required: true,
},
},
data() {
return {
selectedStage: this.stages.length > 0 ? this.stages[0].name : __('More'),
};
},
computed: {
pipelineLink() {
return sprintf(__('Pipeline %{pipelineLinkStart} #%{pipelineId} %{pipelineLinkEnd} from %{pipelineLinkRefStart} %{pipelineRef} %{pipelineLinkRefEnd}'), {
pipelineLinkStart: `<a href=${this.pipelinePath} class="js-pipeline-path link-commit">`,
pipelineId: this.pipelineId,
pipelineLinkEnd: '</a>',
pipelineLinkRefStart: `<a href=${this.pipelineRefPath} class="link-commit ref-name">`,
pipelineRef: this.pipelineRef,
pipelineLinkRefEnd: '</a>',
}, false);
},
},
methods: {
onStageClick(stage) {
// todo: consider moving into store
this.selectedStage = stage.name;
// update dropdown with jobs
// jobs container is a new component.
this.$emit('requestSidebarStageDropdown', stage);
},
},
};
</script>
<template>
<div class="block-last">
<ci-icon :status="pipelineStatus" />
<p v-html="pipelineLink"></p>
<div class="dropdown">
<button
type="button"
data-toggle="dropdown"
>
{{ selectedStage }}
<icon name="chevron-down" />
</button>
<ul class="dropdown-menu">
<li
v-for="(stage, index) in stages"
:key="index"
>
<button
type="button"
class="stage-item"
@click="onStageClick(stage)"
>
{{ stage.name }}
</button>
</li>
</ul>
</div>
</div>
</template>
...@@ -38,6 +38,7 @@ module ProtectedBranches ...@@ -38,6 +38,7 @@ module ProtectedBranches
def delete_redundant_access_levels def delete_redundant_access_levels
unless @developers_can_merge.nil? unless @developers_can_merge.nil?
<<<<<<< HEAD
@protected_branch.merge_access_levels.destroy_all # rubocop: disable DestroyAll # rubocop: disable DestroyAll @protected_branch.merge_access_levels.destroy_all # rubocop: disable DestroyAll # rubocop: disable DestroyAll
end end
...@@ -64,6 +65,13 @@ module ProtectedBranches ...@@ -64,6 +65,13 @@ module ProtectedBranches
when false when false
@protected_branch.push_access_levels.developer.destroy_all # rubocop: disable DestroyAll @protected_branch.push_access_levels.developer.destroy_all # rubocop: disable DestroyAll
@protected_branch.push_access_levels.maintainer.destroy_all # rubocop: disable DestroyAll @protected_branch.push_access_levels.maintainer.destroy_all # rubocop: disable DestroyAll
=======
@protected_branch.merge_access_levels.destroy_all # rubocop: disable DestroyAll
end
unless @developers_can_push.nil?
@protected_branch.push_access_levels.destroy_all # rubocop: disable DestroyAll
>>>>>>> upstream/master
end end
end end
end end
......
...@@ -2,8 +2,11 @@ ...@@ -2,8 +2,11 @@
module Users module Users
class DestroyService class DestroyService
<<<<<<< HEAD
prepend ::EE::Users::DestroyService prepend ::EE::Users::DestroyService
=======
>>>>>>> upstream/master
DestroyError = Class.new(StandardError) DestroyError = Class.new(StandardError)
attr_accessor :current_user attr_accessor :current_user
......
---
title: Creates vue components for stage dropdowns and job list container for job log
view
merge_request:
author:
type: other
---
title: Bump Gitaly to 0.117.1 for Rouge update
merge_request: 21277
author:
type: security
...@@ -20,7 +20,10 @@ class DeleteInconsistentInternalIdRecords < ActiveRecord::Migration ...@@ -20,7 +20,10 @@ class DeleteInconsistentInternalIdRecords < ActiveRecord::Migration
delete_internal_id_records('milestones', 'project_id') delete_internal_id_records('milestones', 'project_id')
delete_internal_id_records('milestones', 'namespace_id', 'group_id') delete_internal_id_records('milestones', 'namespace_id', 'group_id')
delete_internal_id_records('ci_pipelines', 'project_id') delete_internal_id_records('ci_pipelines', 'project_id')
<<<<<<< HEAD
delete_internal_id_records('epics', 'namespace_id', 'group_id') delete_internal_id_records('epics', 'namespace_id', 'group_id')
=======
>>>>>>> upstream/master
end end
end end
......
...@@ -55,14 +55,14 @@ Below is an example of an NFS mount point defined in `/etc/fstab` we use on ...@@ -55,14 +55,14 @@ Below is an example of an NFS mount point defined in `/etc/fstab` we use on
GitLab.com: GitLab.com:
``` ```
10.1.1.1:/var/opt/gitlab/git-data /var/opt/gitlab/git-data nfs4 defaults,soft,rsize=1048576,wsize=1048576,noatime,nobootwait,lookupcache=positive 0 2 10.1.1.1:/var/opt/gitlab/git-data /var/opt/gitlab/git-data nfs4 defaults,soft,rsize=1048576,wsize=1048576,noatime,nofail,lookupcache=positive 0 2
``` ```
Notice several options that you should consider using: Notice several options that you should consider using:
| Setting | Description | | Setting | Description |
| ------- | ----------- | | ------- | ----------- |
| `nobootwait` | Don't halt boot process waiting for this mount to become available | `nofail` | Don't halt boot process waiting for this mount to become available
| `lookupcache=positive` | Tells the NFS client to honor `positive` cache results but invalidates any `negative` cache results. Negative cache results cause problems with Git. Specifically, a `git push` can fail to register uniformly across all NFS clients. The negative cache causes the clients to 'remember' that the files did not exist previously. | `lookupcache=positive` | Tells the NFS client to honor `positive` cache results but invalidates any `negative` cache results. Negative cache results cause problems with Git. Specifically, a `git push` can fail to register uniformly across all NFS clients. The negative cache causes the clients to 'remember' that the files did not exist previously.
## A single NFS mount ## A single NFS mount
......
...@@ -57,7 +57,13 @@ description: 'Learn how to contribute to GitLab.' ...@@ -57,7 +57,13 @@ description: 'Learn how to contribute to GitLab.'
- [Merge request performance guidelines](merge_request_performance_guidelines.md) - [Merge request performance guidelines](merge_request_performance_guidelines.md)
for ensuring merge requests do not negatively impact GitLab performance for ensuring merge requests do not negatively impact GitLab performance
## Databases guides ## Database guides
### Tooling
- [Understanding EXPLAIN plans](understanding_explain_plans.md)
- [explain.depesz.com](https://explain.depesz.com/) for visualising the output
of `EXPLAIN`
### Migrations ### Migrations
......
...@@ -258,6 +258,31 @@ end ...@@ -258,6 +258,31 @@ end
[`extend ::Gitlab::Utils::Override`]: utilities.md#override [`extend ::Gitlab::Utils::Override`]: utilities.md#override
##### Overriding CE class methods
The same applies to class methods, except we want to use
`ActiveSupport::Concern` and put `extend ::Gitlab::Utils::Override`
within the block of `class_methods`. Here's an example:
```ruby
module EE
module Groups
module GroupMembersController
extend ActiveSupport::Concern
class_methods do
extend ::Gitlab::Utils::Override
override :admin_not_required_endpoints
def admin_not_required_endpoints
super.concat(%i[update override])
end
end
end
end
end
```
#### Use self-descriptive wrapper methods #### Use self-descriptive wrapper methods
When it's not possible/logical to modify the implementation of a When it's not possible/logical to modify the implementation of a
...@@ -665,6 +690,9 @@ module EE ...@@ -665,6 +690,9 @@ module EE
extend ActiveSupport::Concern extend ActiveSupport::Concern
class_methods do class_methods do
extend ::Gitlab::Utils::Override
override :update_params_at_least_one_of
def update_params_at_least_one_of def update_params_at_least_one_of
super.push(*%i[ super.push(*%i[
squash squash
......
This diff is collapsed.
...@@ -5206,6 +5206,9 @@ msgstr "" ...@@ -5206,6 +5206,9 @@ msgstr ""
msgid "Pipeline" msgid "Pipeline"
msgstr "" msgstr ""
msgid "Pipeline %{pipelineLinkStart} #%{pipelineId} %{pipelineLinkEnd} from %{pipelineLinkRefStart} %{pipelineRef} %{pipelineLinkRefEnd}"
msgstr ""
msgid "Pipeline Health" msgid "Pipeline Health"
msgstr "" msgstr ""
......
import Vue from 'vue';
import component from '~/jobs/components/jobs_container.vue';
import mountComponent from '../helpers/vue_mount_component_helper';
describe('Artifacts block', () => {
const Component = Vue.extend(component);
let vm;
const retried = {
status: {
details_path: '/gitlab-org/gitlab-ce/pipelines/28029444',
group: 'success',
has_details: true,
icon: 'status_success',
label: 'passed',
text: 'passed',
tooltip: 'passed',
},
path: 'job/233432756',
id: '233432756',
tooltip: 'build - passed',
retried: true,
};
const active = {
name: 'test',
status: {
details_path: '/gitlab-org/gitlab-ce/pipelines/28029444',
group: 'success',
has_details: true,
icon: 'status_success',
label: 'passed',
text: 'passed',
tooltip: 'passed',
},
path: 'job/2322756',
id: '2322756',
tooltip: 'build - passed',
active: true,
};
const job = {
name: 'build',
status: {
details_path: '/gitlab-org/gitlab-ce/pipelines/28029444',
group: 'success',
has_details: true,
icon: 'status_success',
label: 'passed',
text: 'passed',
tooltip: 'passed',
},
path: 'job/232153',
id: '232153',
tooltip: 'build - passed',
};
afterEach(() => {
vm.$destroy();
});
it('renders list of jobs', () => {
vm = mountComponent(Component, {
jobs: [job, retried, active],
});
expect(vm.$el.querySelectorAll('a').length).toEqual(3);
});
it('renders arrow right when job is active', () => {
vm = mountComponent(Component, {
jobs: [active],
});
expect(vm.$el.querySelector('a .js-arrow-right')).not.toBeNull();
});
it('does not render arrow right when job is not active', () => {
vm = mountComponent(Component, {
jobs: [job],
});
expect(vm.$el.querySelector('a .js-arrow-right')).toBeNull();
});
it('renders job name when present', () => {
vm = mountComponent(Component, {
jobs: [job],
});
expect(vm.$el.querySelector('a').textContent.trim()).toContain(job.name);
expect(vm.$el.querySelector('a').textContent.trim()).not.toContain(job.id);
});
it('renders job id when job name is not available', () => {
vm = mountComponent(Component, {
jobs: [retried],
});
expect(vm.$el.querySelector('a').textContent.trim()).toContain(retried.id);
});
it('links to the job page', () => {
vm = mountComponent(Component, {
jobs: [job],
});
expect(vm.$el.querySelector('a').getAttribute('href')).toEqual(job.path);
});
it('renders retry icon when job was retried', () => {
vm = mountComponent(Component, {
jobs: [retried],
});
expect(vm.$el.querySelector('.js-retry-icon')).not.toBeNull();
});
it('does not render retry icon when job was not retried', () => {
vm = mountComponent(Component, {
jobs: [job],
});
expect(vm.$el.querySelector('.js-retry-icon')).toBeNull();
});
});
import Vue from 'vue';
import component from '~/jobs/components/stages_dropdown.vue';
import mountComponent from '../helpers/vue_mount_component_helper';
describe('Artifacts block', () => {
const Component = Vue.extend(component);
let vm;
beforeEach(() => {
vm = mountComponent(Component, {
pipelineId: 28029444,
pipelinePath: 'pipeline/28029444',
pipelineRef: '50101-truncated-job-information',
pipelineRefPath: 'commits/50101-truncated-job-information',
stages: [
{
name: 'build',
},
{
name: 'test',
},
],
pipelineStatus: {
details_path: '/gitlab-org/gitlab-ce/pipelines/28029444',
group: 'success',
has_details: true,
icon: 'status_success',
label: 'passed',
text: 'passed',
tooltip: 'passed',
},
});
});
afterEach(() => {
vm.$destroy();
});
it('renders pipeline status', () => {
expect(vm.$el.querySelector('.js-ci-status-icon-success')).not.toBeNull();
});
it('renders pipeline link', () => {
expect(vm.$el.querySelector('.js-pipeline-path').getAttribute('href')).toEqual(
'pipeline/28029444',
);
});
it('renders dropdown with stages', () => {
expect(vm.$el.querySelector('.dropdown button').textContent).toContain('build');
});
it('updates selected stage on click', done => {
vm.$el.querySelectorAll('.stage-item')[1].click();
vm
.$nextTick()
.then(() => {
expect(vm.$el.querySelector('.dropdown button').textContent).toContain('test');
})
.then(done)
.catch(done.fail);
});
});
...@@ -542,7 +542,7 @@ describe Gitlab::Git::Repository, :seed_helper do ...@@ -542,7 +542,7 @@ describe Gitlab::Git::Repository, :seed_helper do
Gitlab::Shell.new.remove_repository('default', 'my_project') Gitlab::Shell.new.remove_repository('default', 'my_project')
end end
shared_examples 'repository mirror fecthing' do shared_examples 'repository mirror fetching' do
it 'fetches a repository as a mirror remote' do it 'fetches a repository as a mirror remote' do
subject subject
...@@ -569,11 +569,11 @@ describe Gitlab::Git::Repository, :seed_helper do ...@@ -569,11 +569,11 @@ describe Gitlab::Git::Repository, :seed_helper do
end end
context 'with gitaly enabled' do context 'with gitaly enabled' do
it_behaves_like 'repository mirror fecthing' it_behaves_like 'repository mirror fetching'
end end
context 'with gitaly enabled', :skip_gitaly_mock do context 'with gitaly enabled', :skip_gitaly_mock do
it_behaves_like 'repository mirror fecthing' it_behaves_like 'repository mirror fetching'
end end
def new_repository_path def new_repository_path
......
...@@ -79,7 +79,11 @@ describe DeleteInconsistentInternalIdRecords, :migration do ...@@ -79,7 +79,11 @@ describe DeleteInconsistentInternalIdRecords, :migration do
end end
context 'for milestones (by group)' do context 'for milestones (by group)' do
<<<<<<< HEAD
# milestones (by group) is a little different than most of the other models # milestones (by group) is a little different than most of the other models
=======
# milestones (by group) is a little different than all of the other models
>>>>>>> upstream/master
let!(:group1) { create(:group) } let!(:group1) { create(:group) }
let!(:group2) { create(:group) } let!(:group2) { create(:group) }
let!(:group3) { create(:group) } let!(:group3) { create(:group) }
...@@ -116,6 +120,7 @@ describe DeleteInconsistentInternalIdRecords, :migration do ...@@ -116,6 +120,7 @@ describe DeleteInconsistentInternalIdRecords, :migration do
expect { migrate! }.not_to change { internal_id_query.call(group3).size } expect { migrate! }.not_to change { internal_id_query.call(group3).size }
end end
end end
<<<<<<< HEAD
context 'for milestones (by group)' do context 'for milestones (by group)' do
# epics (by group) is a little different than most of the other models # epics (by group) is a little different than most of the other models
...@@ -155,4 +160,6 @@ describe DeleteInconsistentInternalIdRecords, :migration do ...@@ -155,4 +160,6 @@ describe DeleteInconsistentInternalIdRecords, :migration do
expect { migrate! }.not_to change { internal_id_query.call(group3).size } expect { migrate! }.not_to change { internal_id_query.call(group3).size }
end end
end end
=======
>>>>>>> upstream/master
end end
...@@ -83,11 +83,6 @@ describe API::ProjectHooks, 'ProjectHooks' do ...@@ -83,11 +83,6 @@ describe API::ProjectHooks, 'ProjectHooks' do
expect(response).to have_gitlab_http_status(403) expect(response).to have_gitlab_http_status(403)
end end
end end
it "returns a 404 error if hook id is not available" do
get api("/projects/#{project.id}/hooks/1234", user)
expect(response).to have_gitlab_http_status(404)
end
end end
describe "POST /projects/:id/hooks" do describe "POST /projects/:id/hooks" do
......
...@@ -42,7 +42,7 @@ describe API::ProjectImport do ...@@ -42,7 +42,7 @@ describe API::ProjectImport do
expect(response).to have_gitlab_http_status(201) expect(response).to have_gitlab_http_status(201)
end end
it 'does not shedule an import for a nampespace that does not exist' do it 'does not schedule an import for a namespace that does not exist' do
expect_any_instance_of(Project).not_to receive(:import_schedule) expect_any_instance_of(Project).not_to receive(:import_schedule)
expect(::Projects::CreateService).not_to receive(:new) expect(::Projects::CreateService).not_to receive(:new)
......
...@@ -20,7 +20,6 @@ describe API::Projects do ...@@ -20,7 +20,6 @@ describe API::Projects do
let(:admin) { create(:admin) } let(:admin) { create(:admin) }
let(:project) { create(:project, :repository, namespace: user.namespace) } let(:project) { create(:project, :repository, namespace: user.namespace) }
let(:project2) { create(:project, namespace: user.namespace) } let(:project2) { create(:project, namespace: user.namespace) }
let(:snippet) { create(:project_snippet, :public, author: user, project: project, title: 'example') }
let(:project_member) { create(:project_member, :developer, user: user3, project: project) } let(:project_member) { create(:project_member, :developer, user: user3, project: project) }
let(:user4) { create(:user) } let(:user4) { create(:user) }
let(:project3) do let(:project3) do
...@@ -575,7 +574,7 @@ describe API::Projects do ...@@ -575,7 +574,7 @@ describe API::Projects do
expect(json_response['avatar_url']).to eq("http://localhost/uploads/-/system/project/avatar/#{project_id}/banana_sample.gif") expect(json_response['avatar_url']).to eq("http://localhost/uploads/-/system/project/avatar/#{project_id}/banana_sample.gif")
end end
it 'sets a project as allowing outdated diff discussions to automatically resolve' do it 'sets a project as not allowing outdated diff discussions to automatically resolve' do
project = attributes_for(:project, resolve_outdated_diff_discussions: false) project = attributes_for(:project, resolve_outdated_diff_discussions: false)
post api('/projects', user), project post api('/projects', user), project
...@@ -583,7 +582,7 @@ describe API::Projects do ...@@ -583,7 +582,7 @@ describe API::Projects do
expect(json_response['resolve_outdated_diff_discussions']).to be_falsey expect(json_response['resolve_outdated_diff_discussions']).to be_falsey
end end
it 'sets a project as allowing outdated diff discussions to automatically resolve if resolve_outdated_diff_discussions' do it 'sets a project as allowing outdated diff discussions to automatically resolve' do
project = attributes_for(:project, resolve_outdated_diff_discussions: true) project = attributes_for(:project, resolve_outdated_diff_discussions: true)
post api('/projects', user), project post api('/projects', user), project
...@@ -698,7 +697,7 @@ describe API::Projects do ...@@ -698,7 +697,7 @@ describe API::Projects do
expect(json_response.map { |project| project['id'] }).to contain_exactly(public_project.id) expect(json_response.map { |project| project['id'] }).to contain_exactly(public_project.id)
end end
it 'returns projects filetered by minimal access level' do it 'returns projects filtered by minimal access level' do
private_project1 = create(:project, :private, name: 'private_project1', creator_id: user4.id, namespace: user4.namespace) private_project1 = create(:project, :private, name: 'private_project1', creator_id: user4.id, namespace: user4.namespace)
private_project2 = create(:project, :private, name: 'private_project2', creator_id: user4.id, namespace: user4.namespace) private_project2 = create(:project, :private, name: 'private_project2', creator_id: user4.id, namespace: user4.namespace)
private_project1.add_developer(user2) private_project1.add_developer(user2)
...@@ -789,7 +788,7 @@ describe API::Projects do ...@@ -789,7 +788,7 @@ describe API::Projects do
expect(json_response['visibility']).to eq('private') expect(json_response['visibility']).to eq('private')
end end
it 'sets a project as allowing outdated diff discussions to automatically resolve' do it 'sets a project as not allowing outdated diff discussions to automatically resolve' do
project = attributes_for(:project, resolve_outdated_diff_discussions: false) project = attributes_for(:project, resolve_outdated_diff_discussions: false)
post api("/projects/user/#{user.id}", admin), project post api("/projects/user/#{user.id}", admin), project
...@@ -1169,100 +1168,6 @@ describe API::Projects do ...@@ -1169,100 +1168,6 @@ describe API::Projects do
end end
end end
describe 'GET /projects/:id/snippets' do
before do
snippet
end
it 'returns an array of project snippets' do
get api("/projects/#{project.id}/snippets", user)
expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
expect(json_response).to be_an Array
expect(json_response.first['title']).to eq(snippet.title)
end
end
describe 'GET /projects/:id/snippets/:snippet_id' do
it 'returns a project snippet' do
get api("/projects/#{project.id}/snippets/#{snippet.id}", user)
expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq(snippet.title)
end
it 'returns a 404 error if snippet id not found' do
get api("/projects/#{project.id}/snippets/1234", user)
expect(response).to have_gitlab_http_status(404)
end
end
describe 'POST /projects/:id/snippets' do
it 'creates a new project snippet' do
post api("/projects/#{project.id}/snippets", user),
title: 'api test', file_name: 'sample.rb', code: 'test', visibility: 'private'
expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq('api test')
end
it 'returns a 400 error if invalid snippet is given' do
post api("/projects/#{project.id}/snippets", user)
expect(status).to eq(400)
end
end
describe 'PUT /projects/:id/snippets/:snippet_id' do
it 'updates an existing project snippet' do
put api("/projects/#{project.id}/snippets/#{snippet.id}", user),
code: 'updated code'
expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq('example')
expect(snippet.reload.content).to eq('updated code')
end
it 'updates an existing project snippet with new title' do
put api("/projects/#{project.id}/snippets/#{snippet.id}", user),
title: 'other api test'
expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq('other api test')
end
end
describe 'DELETE /projects/:id/snippets/:snippet_id' do
before do
snippet
end
it 'deletes existing project snippet' do
expect do
delete api("/projects/#{project.id}/snippets/#{snippet.id}", user)
expect(response).to have_gitlab_http_status(204)
end.to change { Snippet.count }.by(-1)
end
it 'returns 404 when deleting unknown snippet id' do
delete api("/projects/#{project.id}/snippets/1234", user)
expect(response).to have_gitlab_http_status(404)
end
it_behaves_like '412 response' do
let(:request) { api("/projects/#{project.id}/snippets/#{snippet.id}", user) }
end
end
describe 'GET /projects/:id/snippets/:snippet_id/raw' do
it 'gets a raw project snippet' do
get api("/projects/#{project.id}/snippets/#{snippet.id}/raw", user)
expect(response).to have_gitlab_http_status(200)
end
it 'returns a 404 error if raw project snippet not found' do
get api("/projects/#{project.id}/snippets/5555/raw", user)
expect(response).to have_gitlab_http_status(404)
end
end
describe 'fork management' do describe 'fork management' do
let(:project_fork_target) { create(:project) } let(:project_fork_target) { create(:project) }
let(:project_fork_source) { create(:project, :public) } let(:project_fork_source) { create(:project, :public) }
...@@ -1285,7 +1190,7 @@ describe API::Projects do ...@@ -1285,7 +1190,7 @@ describe API::Projects do
expect(project_fork_target.forked?).to be_truthy expect(project_fork_target.forked?).to be_truthy
end end
it 'refreshes the forks count cachce' do it 'refreshes the forks count cache' do
expect(project_fork_source.forks_count).to be_zero expect(project_fork_source.forks_count).to be_zero
post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", admin) post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", admin)
......
...@@ -30,8 +30,11 @@ end ...@@ -30,8 +30,11 @@ end
# require rainbow gem String monkeypatch, so we can test SystemChecks # require rainbow gem String monkeypatch, so we can test SystemChecks
require 'rainbow/ext/string' require 'rainbow/ext/string'
Rainbow.enabled = false Rainbow.enabled = false
<<<<<<< HEAD
require_relative '../ee/spec/spec_helper' require_relative '../ee/spec/spec_helper'
=======
>>>>>>> upstream/master
# Requires supporting ruby files with custom matchers and macros, etc, # Requires supporting ruby files with custom matchers and macros, etc,
# in spec/support/ and its subdirectories. # in spec/support/ and its subdirectories.
......
...@@ -102,14 +102,6 @@ shared_examples_for 'group and project milestones' do |route_definition| ...@@ -102,14 +102,6 @@ shared_examples_for 'group and project milestones' do |route_definition|
expect(json_response['iid']).to eq(milestone.iid) expect(json_response['iid']).to eq(milestone.iid)
end end
it 'returns a milestone by id' do
get api(resource_route, user)
expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq(milestone.title)
expect(json_response['iid']).to eq(milestone.iid)
end
it 'returns 401 error if user not authenticated' do it 'returns 401 error if user not authenticated' do
get api(resource_route) get api(resource_route)
......
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