Commit fcf944a9 authored by GitLab Bot's avatar GitLab Bot

Merge remote-tracking branch 'upstream/master' into ce-to-ee-2018-02-09

parents e0e03b98 721fab66
import { __ } from './locale';
import axios from './lib/utils/axios_utils';
import flash from './flash';
class ImporterStatus { class ImporterStatus {
constructor(jobsUrl, importUrl) { constructor(jobsUrl, importUrl) {
this.jobsUrl = jobsUrl; this.jobsUrl = jobsUrl;
...@@ -9,29 +13,7 @@ class ImporterStatus { ...@@ -9,29 +13,7 @@ class ImporterStatus {
initStatusPage() { initStatusPage() {
$('.js-add-to-import') $('.js-add-to-import')
.off('click') .off('click')
.on('click', (event) => { .on('click', this.addToImport.bind(this));
const $btn = $(event.currentTarget);
const $tr = $btn.closest('tr');
const $targetField = $tr.find('.import-target');
const $namespaceInput = $targetField.find('.js-select-namespace option:selected');
const id = $tr.attr('id').replace('repo_', '');
let targetNamespace;
let newName;
if ($namespaceInput.length > 0) {
targetNamespace = $namespaceInput[0].innerHTML;
newName = $targetField.find('#path').prop('value');
$targetField.empty().append(`${targetNamespace}/${newName}`);
}
$btn.disable().addClass('is-loading');
return $.post(this.importUrl, {
repo_id: id,
target_namespace: targetNamespace,
new_name: newName,
}, {
dataType: 'script',
});
});
$('.js-import-all') $('.js-import-all')
.off('click') .off('click')
...@@ -44,6 +26,39 @@ class ImporterStatus { ...@@ -44,6 +26,39 @@ class ImporterStatus {
}); });
} }
addToImport(event) {
const $btn = $(event.currentTarget);
const $tr = $btn.closest('tr');
const $targetField = $tr.find('.import-target');
const $namespaceInput = $targetField.find('.js-select-namespace option:selected');
const id = $tr.attr('id').replace('repo_', '');
let targetNamespace;
let newName;
if ($namespaceInput.length > 0) {
targetNamespace = $namespaceInput[0].innerHTML;
newName = $targetField.find('#path').prop('value');
$targetField.empty().append(`${targetNamespace}/${newName}`);
}
$btn.disable().addClass('is-loading');
return axios.post(this.importUrl, {
repo_id: id,
target_namespace: targetNamespace,
new_name: newName,
})
.then(({ data }) => {
const job = $(`tr#repo_${id}`);
job.attr('id', `project_${data.id}`);
job.find('.import-target').html(`<a href="${data.full_path}">${data.full_path}</a>`);
$('table.import-jobs tbody').prepend(job);
job.addClass('active');
job.find('.import-actions').html('<i class="fa fa-spinner fa-spin" aria-label="importing"></i> started');
})
.catch(() => flash(__('An error occurred while importing project')));
}
setAutoUpdate() { setAutoUpdate() {
return setInterval(() => $.get(this.jobsUrl, data => $.each(data, (i, job) => { return setInterval(() => $.get(this.jobsUrl, data => $.each(data, (i, job) => {
const jobItem = $(`#project_${job.id}`); const jobItem = $(`#project_${job.id}`);
...@@ -71,7 +86,7 @@ class ImporterStatus { ...@@ -71,7 +86,7 @@ class ImporterStatus {
} }
// eslint-disable-next-line consistent-return // eslint-disable-next-line consistent-return
export default function initImporterStatus() { function initImporterStatus() {
const importerStatus = document.querySelector('.js-importer-status'); const importerStatus = document.querySelector('.js-importer-status');
if (importerStatus) { if (importerStatus) {
...@@ -79,3 +94,8 @@ export default function initImporterStatus() { ...@@ -79,3 +94,8 @@ export default function initImporterStatus() {
return new ImporterStatus(data.jobsImportPath, data.importPath); return new ImporterStatus(data.jobsImportPath, data.importPath);
} }
} }
export {
initImporterStatus as default,
ImporterStatus,
};
import statusIcon from '../mr_widget_status_icon.vue';
import tooltip from '../../../vue_shared/directives/tooltip';
import mrWidgetMergeHelp from '../../components/mr_widget_merge_help.vue';
export default {
name: 'MRWidgetMissingBranch',
props: {
mr: { type: Object, required: true },
},
directives: {
tooltip,
},
components: {
'mr-widget-merge-help': mrWidgetMergeHelp,
statusIcon,
},
computed: {
missingBranchName() {
return this.mr.sourceBranchRemoved ? 'source' : 'target';
},
message() {
return `If the ${this.missingBranchName} branch exists in your local repository, you can merge this merge request manually using the command line`;
},
},
template: `
<div class="mr-widget-body media">
<status-icon status="warning" :show-disabled-button="true" />
<div class="media-body space-children">
<span class="bold js-branch-text">
<span class="capitalize">
{{missingBranchName}}
</span> branch does not exist.
Please restore it or use a different {{missingBranchName}} branch
<i
v-tooltip
class="fa fa-question-circle"
:title="message"
:aria-label="message"></i>
</span>
</div>
</div>
`,
};
<script>
import { sprintf, s__ } from '~/locale';
import tooltip from '~/vue_shared/directives/tooltip';
import statusIcon from '../mr_widget_status_icon.vue';
import mrWidgetMergeHelp from '../../components/mr_widget_merge_help.vue';
export default {
name: 'MRWidgetMissingBranch',
directives: {
tooltip,
},
components: {
mrWidgetMergeHelp,
statusIcon,
},
props: {
mr: {
type: Object,
required: true,
},
},
computed: {
missingBranchName() {
return this.mr.sourceBranchRemoved ? 'source' : 'target';
},
missingBranchNameMessage() {
return sprintf(s__('mrWidget| Please restore it or use a different %{missingBranchName} branch'), {
missingBranchName: this.missingBranchName,
});
},
message() {
return sprintf(s__('mrWidget|If the %{missingBranchName} branch exists in your local repository, you can merge this merge request manually using the command line'), {
missingBranchName: this.missingBranchName,
});
},
},
};
</script>
<template>
<div class="mr-widget-body media">
<status-icon
status="warning"
:show-disabled-button="true"
/>
<div class="media-body space-children">
<span class="bold js-branch-text">
<span class="capitalize">
{{ missingBranchName }}
</span> {{ s__("mrWidget|branch does not exist.") }}
{{ missingBranchNameMessage }}
<i
v-tooltip
class="fa fa-question-circle"
:title="message"
:aria-label="message"
>
</i>
</span>
</div>
</div>
</template>
...@@ -24,7 +24,7 @@ export { default as WipState } from './components/states/mr_widget_wip'; ...@@ -24,7 +24,7 @@ export { default as WipState } from './components/states/mr_widget_wip';
export { default as ArchivedState } from './components/states/mr_widget_archived.vue'; export { default as ArchivedState } from './components/states/mr_widget_archived.vue';
export { default as ConflictsState } from './components/states/mr_widget_conflicts.vue'; export { default as ConflictsState } from './components/states/mr_widget_conflicts.vue';
export { default as NothingToMergeState } from './components/states/mr_widget_nothing_to_merge'; export { default as NothingToMergeState } from './components/states/mr_widget_nothing_to_merge';
export { default as MissingBranchState } from './components/states/mr_widget_missing_branch'; export { default as MissingBranchState } from './components/states/mr_widget_missing_branch.vue';
export { default as NotAllowedState } from './components/states/mr_widget_not_allowed'; export { default as NotAllowedState } from './components/states/mr_widget_not_allowed';
export { default as ReadyToMergeState } from 'ee/vue_merge_request_widget/components/states/mr_widget_ready_to_merge'; export { default as ReadyToMergeState } from 'ee/vue_merge_request_widget/components/states/mr_widget_ready_to_merge';
export { default as SHAMismatchState } from './components/states/mr_widget_sha_mismatch'; export { default as SHAMismatchState } from './components/states/mr_widget_sha_mismatch';
......
...@@ -37,24 +37,30 @@ class Import::BitbucketController < Import::BaseController ...@@ -37,24 +37,30 @@ class Import::BitbucketController < Import::BaseController
def create def create
bitbucket_client = Bitbucket::Client.new(credentials) bitbucket_client = Bitbucket::Client.new(credentials)
@repo_id = params[:repo_id].to_s repo_id = params[:repo_id].to_s
name = @repo_id.gsub('___', '/') name = repo_id.gsub('___', '/')
repo = bitbucket_client.repo(name) repo = bitbucket_client.repo(name)
@project_name = params[:new_name].presence || repo.name project_name = params[:new_name].presence || repo.name
repo_owner = repo.owner repo_owner = repo.owner
repo_owner = current_user.username if repo_owner == bitbucket_client.user.username repo_owner = current_user.username if repo_owner == bitbucket_client.user.username
namespace_path = params[:new_namespace].presence || repo_owner namespace_path = params[:new_namespace].presence || repo_owner
target_namespace = find_or_create_namespace(namespace_path, current_user)
@target_namespace = find_or_create_namespace(namespace_path, current_user) if current_user.can?(:create_projects, target_namespace)
if current_user.can?(:create_projects, @target_namespace)
# The token in a session can be expired, we need to get most recent one because # The token in a session can be expired, we need to get most recent one because
# Bitbucket::Connection class refreshes it. # Bitbucket::Connection class refreshes it.
session[:bitbucket_token] = bitbucket_client.connection.token session[:bitbucket_token] = bitbucket_client.connection.token
@project = Gitlab::BitbucketImport::ProjectCreator.new(repo, @project_name, @target_namespace, current_user, credentials).execute
project = Gitlab::BitbucketImport::ProjectCreator.new(repo, project_name, target_namespace, current_user, credentials).execute
if project.persisted?
render json: ProjectSerializer.new.represent(project)
else
render json: { errors: project.errors.full_messages }, status: :unprocessable_entity
end
else else
render 'unauthorized' render json: { errors: 'This namespace has already been taken! Please choose another one.' }, status: :unprocessable_entity
end end
end end
......
...@@ -58,17 +58,17 @@ class Import::FogbugzController < Import::BaseController ...@@ -58,17 +58,17 @@ class Import::FogbugzController < Import::BaseController
end end
def create def create
@repo_id = params[:repo_id] repo = client.repo(params[:repo_id])
repo = client.repo(@repo_id)
fb_session = { uri: session[:fogbugz_uri], token: session[:fogbugz_token] } fb_session = { uri: session[:fogbugz_uri], token: session[:fogbugz_token] }
@target_namespace = current_user.namespace
@project_name = repo.name
namespace = @target_namespace
umap = session[:fogbugz_user_map] || client.user_map umap = session[:fogbugz_user_map] || client.user_map
@project = Gitlab::FogbugzImport::ProjectCreator.new(repo, fb_session, namespace, current_user, umap).execute project = Gitlab::FogbugzImport::ProjectCreator.new(repo, fb_session, current_user.namespace, current_user, umap).execute
if project.persisted?
render json: ProjectSerializer.new.represent(project)
else
render json: { errors: project.errors.full_messages }, status: :unprocessable_entity
end
end end
private private
......
...@@ -36,16 +36,21 @@ class Import::GithubController < Import::BaseController ...@@ -36,16 +36,21 @@ class Import::GithubController < Import::BaseController
end end
def create def create
@repo_id = params[:repo_id].to_i repo = client.repo(params[:repo_id].to_i)
repo = client.repo(@repo_id) project_name = params[:new_name].presence || repo.name
@project_name = params[:new_name].presence || repo.name
namespace_path = params[:target_namespace].presence || current_user.namespace_path namespace_path = params[:target_namespace].presence || current_user.namespace_path
@target_namespace = find_or_create_namespace(namespace_path, current_user.namespace_path) target_namespace = find_or_create_namespace(namespace_path, current_user.namespace_path)
if can?(current_user, :create_projects, @target_namespace) if can?(current_user, :create_projects, target_namespace)
@project = Gitlab::LegacyGithubImport::ProjectCreator.new(repo, @project_name, @target_namespace, current_user, access_params, type: provider).execute project = Gitlab::LegacyGithubImport::ProjectCreator.new(repo, project_name, target_namespace, current_user, access_params, type: provider).execute
if project.persisted?
render json: ProjectSerializer.new.represent(project)
else
render json: { errors: project.errors.full_messages }, status: :unprocessable_entity
end
else else
render 'unauthorized' render json: { errors: 'This namespace has already been taken! Please choose another one.' }, status: :unprocessable_entity
end end
end end
......
...@@ -24,15 +24,19 @@ class Import::GitlabController < Import::BaseController ...@@ -24,15 +24,19 @@ class Import::GitlabController < Import::BaseController
end end
def create def create
@repo_id = params[:repo_id].to_i repo = client.project(params[:repo_id].to_i)
repo = client.project(@repo_id) target_namespace = find_or_create_namespace(repo['namespace']['path'], client.user['username'])
@project_name = repo['name']
@target_namespace = find_or_create_namespace(repo['namespace']['path'], client.user['username'])
if current_user.can?(:create_projects, @target_namespace) if current_user.can?(:create_projects, target_namespace)
@project = Gitlab::GitlabImport::ProjectCreator.new(repo, @target_namespace, current_user, access_params).execute project = Gitlab::GitlabImport::ProjectCreator.new(repo, target_namespace, current_user, access_params).execute
if project.persisted?
render json: ProjectSerializer.new.represent(project)
else
render json: { errors: project.errors.full_messages }, status: :unprocessable_entity
end
else else
render 'unauthorized' render json: { errors: 'This namespace has already been taken! Please choose another one.' }, status: :unprocessable_entity
end end
end end
......
...@@ -85,16 +85,16 @@ class Import::GoogleCodeController < Import::BaseController ...@@ -85,16 +85,16 @@ class Import::GoogleCodeController < Import::BaseController
end end
def create def create
@repo_id = params[:repo_id] repo = client.repo(params[:repo_id])
repo = client.repo(@repo_id)
@target_namespace = current_user.namespace
@project_name = repo.name
namespace = @target_namespace
user_map = session[:google_code_user_map] user_map = session[:google_code_user_map]
@project = Gitlab::GoogleCodeImport::ProjectCreator.new(repo, namespace, current_user, user_map).execute project = Gitlab::GoogleCodeImport::ProjectCreator.new(repo, current_user.namespace, current_user, user_map).execute
if project.persisted?
render json: ProjectSerializer.new.represent(project)
else
render json: { errors: project.errors.full_messages }, status: :unprocessable_entity
end
end end
private private
......
class ProjectSerializer < BaseSerializer
entity ProjectEntity
end
- if @project.persisted?
:plain
job = $("tr#repo_#{@repo_id}")
job.attr("id", "project_#{@project.id}")
target_field = job.find(".import-target")
target_field.empty()
target_field.append('#{link_to @project.full_path, project_path(@project)}')
$("table.import-jobs tbody").prepend(job)
job.addClass("active").find(".import-actions").html("<i class='fa fa-spinner fa-spin'></i> started")
- else
:plain
job = $("tr#repo_#{@repo_id}")
job.find(".import-actions").html("<i class='fa fa-exclamation-circle'></i> Error saving project: #{escape_javascript(h(@project.errors.full_messages.join(',')))}")
:plain
tr = $("tr#repo_#{@repo_id}")
target_field = tr.find(".import-target")
import_button = tr.find(".btn-import")
origin_target = target_field.text()
project_name = "#{@project_name}"
origin_namespace = "#{@target_namespace.full_path}"
target_field.empty()
target_field.append("<p class='alert alert-danger'>This namespace has already been taken! Please choose another one.</p>")
target_field.append("<input type='text' name='target_namespace' />")
target_field.append("/" + project_name)
target_field.data("project_name", project_name)
target_field.find('input').prop("value", origin_namespace)
import_button.enable().removeClass('is-loading')
---
title: Update vue component naming guidelines
merge_request: 17018
author: George Tsiolis
type: other
...@@ -207,10 +207,39 @@ Do not use them anymore and feel free to remove them when refactoring legacy cod ...@@ -207,10 +207,39 @@ Do not use them anymore and feel free to remove them when refactoring legacy cod
var c = pureFunction(values.foo); var c = pureFunction(values.foo);
``` ```
1. Avoid constructors with side-effects 1. Avoid constructors with side-effects.
Although we aim for code without side-effects we need some side-effects for our code to run.
If the class won't do anything if we only instantiate it, it's ok to add side effects into the constructor (_Note:_ The following is just an example. If the only purpose of the class is to add an event listener and handle the callback a function will be more suitable.)
```javascript
// Bad
export class Foo {
constructor() {
this.init();
}
init() {
document.addEventListener('click', this.handleCallback)
},
handleCallback() {
}
}
// Good
export class Foo {
constructor() {
document.addEventListener()
}
handleCallback() {
}
}
```
On the other hand, if a class only needs to extend a third party/add event listeners in some specific cases, they should be initialized oustside of the constructor.
1. Prefer `.map`, `.reduce` or `.filter` over `.forEach` 1. Prefer `.map`, `.reduce` or `.filter` over `.forEach`
A forEach will cause side effects, it will be mutating the array being iterated. Prefer using `.map`, A forEach will most likely cause side effects, it will be mutating the array being iterated. Prefer using `.map`,
`.reduce` or `.filter` `.reduce` or `.filter`
```javascript ```javascript
const users = [ { name: 'Foo' }, { name: 'Bar' } ]; const users = [ { name: 'Foo' }, { name: 'Bar' } ];
...@@ -302,20 +331,20 @@ Please check this [rules][eslint-plugin-vue-rules] for more documentation. ...@@ -302,20 +331,20 @@ Please check this [rules][eslint-plugin-vue-rules] for more documentation.
#### Naming #### Naming
1. **Extensions**: Use `.vue` extension for Vue components. 1. **Extensions**: Use `.vue` extension for Vue components.
1. **Reference Naming**: Use camelCase for their instances: 1. **Reference Naming**: Use PascalCase for their instances:
```javascript ```javascript
// bad // bad
import CardBoard from 'cardBoard' import cardBoard from 'cardBoard.vue'
components: { components: {
CardBoard: cardBoard,
}; };
// good // good
import cardBoard from 'cardBoard' import CardBoard from 'cardBoard.vue'
components: { components: {
cardBoard: CardBoard,
}; };
``` ```
......
...@@ -70,6 +70,24 @@ If you need to authenticate as a different user, you can provide the ...@@ -70,6 +70,24 @@ If you need to authenticate as a different user, you can provide the
GITLAB_USERNAME=jsmith GITLAB_PASSWORD=password bin/qa Test::Instance https://gitlab.example.com GITLAB_USERNAME=jsmith GITLAB_PASSWORD=password bin/qa Test::Instance https://gitlab.example.com
``` ```
If your user doesn't have permission to default sandbox group
`gitlab-qa-sandbox`, you could also use another sandbox group by giving
`GITLAB_SANDBOX_NAME`:
```
GITLAB_USERNAME=jsmith GITLAB_PASSWORD=password GITLAB_SANDBOX_NAME=jsmith-qa-sandbox bin/qa Test::Instance https://gitlab.example.com
```
All [supported environment variables are here](https://gitlab.com/gitlab-org/gitlab-qa#supported-environment-variables). All [supported environment variables are here](https://gitlab.com/gitlab-org/gitlab-qa#supported-environment-variables).
### Building a Docker image to test
Once you have made changes to the CE/EE repositories, you may want to build a
Docker image to test locally instead of waiting for the `gitlab-ce-qa` or
`gitlab-ee-qa` nightly builds. To do that, you can run from this directory:
```sh
docker build -t gitlab/gitlab-ce-qa:nightly .
```
[GDK]: https://gitlab.com/gitlab-org/gitlab-development-kit/ [GDK]: https://gitlab.com/gitlab-org/gitlab-development-kit/
...@@ -31,22 +31,29 @@ module QA ...@@ -31,22 +31,29 @@ module QA
end end
end end
def set_initial_password_if_present
if page.has_content?('Change your password')
fill_in :user_password, with: Runtime::User.password
fill_in :user_password_confirmation, with: Runtime::User.password
click_button 'Change your password'
end
end
def sign_in_using_ldap_credentials def sign_in_using_ldap_credentials
click_link 'LDAP' using_wait_time 0 do
set_initial_password_if_present
fill_in :username, with: Runtime::User.name click_link 'LDAP'
fill_in :password, with: Runtime::User.password
click_button 'Sign in' fill_in :username, with: Runtime::User.name
fill_in :password, with: Runtime::User.password
click_button 'Sign in'
end
end end
def sign_in_using_credentials def sign_in_using_credentials
using_wait_time 0 do using_wait_time 0 do
if page.has_content?('Change your password') set_initial_password_if_present
fill_in :user_password, with: Runtime::User.password
fill_in :user_password_confirmation, with: Runtime::User.password
click_button 'Change your password'
end
click_link 'Standard' if page.has_content?('LDAP') click_link 'Standard' if page.has_content?('LDAP')
......
...@@ -16,6 +16,18 @@ module QA ...@@ -16,6 +16,18 @@ module QA
def personal_access_token def personal_access_token
ENV['PERSONAL_ACCESS_TOKEN'] ENV['PERSONAL_ACCESS_TOKEN']
end end
def user_username
ENV['GITLAB_USERNAME']
end
def user_password
ENV['GITLAB_PASSWORD']
end
def sandbox_name
ENV['GITLAB_SANDBOX_NAME']
end
end end
end end
end end
...@@ -16,7 +16,7 @@ module QA ...@@ -16,7 +16,7 @@ module QA
end end
def sandbox_name def sandbox_name
'gitlab-qa-sandbox' Runtime::Env.sandbox_name || 'gitlab-qa-sandbox'
end end
end end
end end
......
...@@ -4,11 +4,11 @@ module QA ...@@ -4,11 +4,11 @@ module QA
extend self extend self
def name def name
ENV['GITLAB_USERNAME'] || 'root' Runtime::Env.user_username || 'root'
end end
def password def password
ENV['GITLAB_PASSWORD'] || '5iveL!fe' Runtime::Env.user_password || '5iveL!fe'
end end
end end
end end
......
...@@ -15,6 +15,14 @@ module QA ...@@ -15,6 +15,14 @@ module QA
@tags = %w[qa test] @tags = %w[qa test]
end end
def network
shell "docker network inspect #{@network}"
rescue CommandError
'bridge'
else
@network
end
def pull def pull
shell "docker pull #{@image}" shell "docker pull #{@image}"
end end
...@@ -22,7 +30,7 @@ module QA ...@@ -22,7 +30,7 @@ module QA
def register! def register!
shell <<~CMD.tr("\n", ' ') shell <<~CMD.tr("\n", ' ')
docker run -d --rm --entrypoint=/bin/sh docker run -d --rm --entrypoint=/bin/sh
--network #{@network} --name #{@name} --network #{network} --name #{@name}
-e CI_SERVER_URL=#{@address} -e CI_SERVER_URL=#{@address}
-e REGISTER_NON_INTERACTIVE=true -e REGISTER_NON_INTERACTIVE=true
-e REGISTRATION_TOKEN=#{@token} -e REGISTRATION_TOKEN=#{@token}
......
...@@ -3,6 +3,8 @@ require 'open3' ...@@ -3,6 +3,8 @@ require 'open3'
module QA module QA
module Service module Service
module Shellout module Shellout
CommandError = Class.new(StandardError)
## ##
# TODO, make it possible to use generic QA framework classes # TODO, make it possible to use generic QA framework classes
# as a library - gitlab-org/gitlab-qa#94 # as a library - gitlab-org/gitlab-qa#94
...@@ -14,7 +16,7 @@ module QA ...@@ -14,7 +16,7 @@ module QA
out.each { |line| puts line } out.each { |line| puts line }
if wait.value.exited? && wait.value.exitstatus.nonzero? if wait.value.exited? && wait.value.exitstatus.nonzero?
raise "Command `#{command}` failed!" raise CommandError, "Command `#{command}` failed!"
end end
end end
end end
......
...@@ -84,20 +84,42 @@ describe Import::BitbucketController do ...@@ -84,20 +84,42 @@ describe Import::BitbucketController do
double(slug: "vim", owner: bitbucket_username, name: 'vim') double(slug: "vim", owner: bitbucket_username, name: 'vim')
end end
let(:project) { create(:project) }
before do before do
allow_any_instance_of(Bitbucket::Client).to receive(:repo).and_return(bitbucket_repo) allow_any_instance_of(Bitbucket::Client).to receive(:repo).and_return(bitbucket_repo)
allow_any_instance_of(Bitbucket::Client).to receive(:user).and_return(bitbucket_user) allow_any_instance_of(Bitbucket::Client).to receive(:user).and_return(bitbucket_user)
assign_session_tokens assign_session_tokens
end end
it 'returns 200 response when the project is imported successfully' do
allow(Gitlab::BitbucketImport::ProjectCreator)
.to receive(:new).with(bitbucket_repo, bitbucket_repo.name, user.namespace, user, access_params)
.and_return(double(execute: project))
post :create, format: :json
expect(response).to have_gitlab_http_status(200)
end
it 'returns 422 response when the project could not be imported' do
allow(Gitlab::BitbucketImport::ProjectCreator)
.to receive(:new).with(bitbucket_repo, bitbucket_repo.name, user.namespace, user, access_params)
.and_return(double(execute: build(:project)))
post :create, format: :json
expect(response).to have_gitlab_http_status(422)
end
context "when the repository owner is the Bitbucket user" do context "when the repository owner is the Bitbucket user" do
context "when the Bitbucket user and GitLab user's usernames match" do context "when the Bitbucket user and GitLab user's usernames match" do
it "takes the current user's namespace" do it "takes the current user's namespace" do
expect(Gitlab::BitbucketImport::ProjectCreator) expect(Gitlab::BitbucketImport::ProjectCreator)
.to receive(:new).with(bitbucket_repo, bitbucket_repo.name, user.namespace, user, access_params) .to receive(:new).with(bitbucket_repo, bitbucket_repo.name, user.namespace, user, access_params)
.and_return(double(execute: true)) .and_return(double(execute: project))
post :create, format: :js post :create, format: :json
end end
end end
...@@ -107,9 +129,9 @@ describe Import::BitbucketController do ...@@ -107,9 +129,9 @@ describe Import::BitbucketController do
it "takes the current user's namespace" do it "takes the current user's namespace" do
expect(Gitlab::BitbucketImport::ProjectCreator) expect(Gitlab::BitbucketImport::ProjectCreator)
.to receive(:new).with(bitbucket_repo, bitbucket_repo.name, user.namespace, user, access_params) .to receive(:new).with(bitbucket_repo, bitbucket_repo.name, user.namespace, user, access_params)
.and_return(double(execute: true)) .and_return(double(execute: project))
post :create, format: :js post :create, format: :json
end end
end end
...@@ -120,7 +142,7 @@ describe Import::BitbucketController do ...@@ -120,7 +142,7 @@ describe Import::BitbucketController do
allow(controller).to receive(:current_user).and_return(user) allow(controller).to receive(:current_user).and_return(user)
allow(user).to receive(:can?).and_return(false) allow(user).to receive(:can?).and_return(false)
post :create, format: :js post :create, format: :json
end end
end end
end end
...@@ -143,9 +165,9 @@ describe Import::BitbucketController do ...@@ -143,9 +165,9 @@ describe Import::BitbucketController do
it "takes the existing namespace" do it "takes the existing namespace" do
expect(Gitlab::BitbucketImport::ProjectCreator) expect(Gitlab::BitbucketImport::ProjectCreator)
.to receive(:new).with(bitbucket_repo, bitbucket_repo.name, existing_namespace, user, access_params) .to receive(:new).with(bitbucket_repo, bitbucket_repo.name, existing_namespace, user, access_params)
.and_return(double(execute: true)) .and_return(double(execute: project))
post :create, format: :js post :create, format: :json
end end
end end
...@@ -154,7 +176,7 @@ describe Import::BitbucketController do ...@@ -154,7 +176,7 @@ describe Import::BitbucketController do
expect(Gitlab::BitbucketImport::ProjectCreator) expect(Gitlab::BitbucketImport::ProjectCreator)
.not_to receive(:new) .not_to receive(:new)
post :create, format: :js post :create, format: :json
end end
end end
end end
...@@ -163,17 +185,17 @@ describe Import::BitbucketController do ...@@ -163,17 +185,17 @@ describe Import::BitbucketController do
context "when current user can create namespaces" do context "when current user can create namespaces" do
it "creates the namespace" do it "creates the namespace" do
expect(Gitlab::BitbucketImport::ProjectCreator) expect(Gitlab::BitbucketImport::ProjectCreator)
.to receive(:new).and_return(double(execute: true)) .to receive(:new).and_return(double(execute: project))
expect { post :create, format: :js }.to change(Namespace, :count).by(1) expect { post :create, format: :json }.to change(Namespace, :count).by(1)
end end
it "takes the new namespace" do it "takes the new namespace" do
expect(Gitlab::BitbucketImport::ProjectCreator) expect(Gitlab::BitbucketImport::ProjectCreator)
.to receive(:new).with(bitbucket_repo, bitbucket_repo.name, an_instance_of(Group), user, access_params) .to receive(:new).with(bitbucket_repo, bitbucket_repo.name, an_instance_of(Group), user, access_params)
.and_return(double(execute: true)) .and_return(double(execute: project))
post :create, format: :js post :create, format: :json
end end
end end
...@@ -184,17 +206,17 @@ describe Import::BitbucketController do ...@@ -184,17 +206,17 @@ describe Import::BitbucketController do
it "doesn't create the namespace" do it "doesn't create the namespace" do
expect(Gitlab::BitbucketImport::ProjectCreator) expect(Gitlab::BitbucketImport::ProjectCreator)
.to receive(:new).and_return(double(execute: true)) .to receive(:new).and_return(double(execute: project))
expect { post :create, format: :js }.not_to change(Namespace, :count) expect { post :create, format: :json }.not_to change(Namespace, :count)
end end
it "takes the current user's namespace" do it "takes the current user's namespace" do
expect(Gitlab::BitbucketImport::ProjectCreator) expect(Gitlab::BitbucketImport::ProjectCreator)
.to receive(:new).with(bitbucket_repo, bitbucket_repo.name, user.namespace, user, access_params) .to receive(:new).with(bitbucket_repo, bitbucket_repo.name, user.namespace, user, access_params)
.and_return(double(execute: true)) .and_return(double(execute: project))
post :create, format: :js post :create, format: :json
end end
end end
end end
...@@ -212,9 +234,9 @@ describe Import::BitbucketController do ...@@ -212,9 +234,9 @@ describe Import::BitbucketController do
it 'takes the selected namespace and name' do it 'takes the selected namespace and name' do
expect(Gitlab::BitbucketImport::ProjectCreator) expect(Gitlab::BitbucketImport::ProjectCreator)
.to receive(:new).with(bitbucket_repo, test_name, nested_namespace, user, access_params) .to receive(:new).with(bitbucket_repo, test_name, nested_namespace, user, access_params)
.and_return(double(execute: true)) .and_return(double(execute: project))
post :create, { target_namespace: nested_namespace.full_path, new_name: test_name, format: :js } post :create, { target_namespace: nested_namespace.full_path, new_name: test_name, format: :json }
end end
end end
...@@ -224,26 +246,26 @@ describe Import::BitbucketController do ...@@ -224,26 +246,26 @@ describe Import::BitbucketController do
it 'takes the selected namespace and name' do it 'takes the selected namespace and name' do
expect(Gitlab::BitbucketImport::ProjectCreator) expect(Gitlab::BitbucketImport::ProjectCreator)
.to receive(:new).with(bitbucket_repo, test_name, kind_of(Namespace), user, access_params) .to receive(:new).with(bitbucket_repo, test_name, kind_of(Namespace), user, access_params)
.and_return(double(execute: true)) .and_return(double(execute: project))
post :create, { target_namespace: 'foo/bar', new_name: test_name, format: :js } post :create, { target_namespace: 'foo/bar', new_name: test_name, format: :json }
end end
it 'creates the namespaces' do it 'creates the namespaces' do
allow(Gitlab::BitbucketImport::ProjectCreator) allow(Gitlab::BitbucketImport::ProjectCreator)
.to receive(:new).with(bitbucket_repo, test_name, kind_of(Namespace), user, access_params) .to receive(:new).with(bitbucket_repo, test_name, kind_of(Namespace), user, access_params)
.and_return(double(execute: true)) .and_return(double(execute: project))
expect { post :create, { target_namespace: 'foo/bar', new_name: test_name, format: :js } } expect { post :create, { target_namespace: 'foo/bar', new_name: test_name, format: :json } }
.to change { Namespace.count }.by(2) .to change { Namespace.count }.by(2)
end end
it 'new namespace has the right parent' do it 'new namespace has the right parent' do
allow(Gitlab::BitbucketImport::ProjectCreator) allow(Gitlab::BitbucketImport::ProjectCreator)
.to receive(:new).with(bitbucket_repo, test_name, kind_of(Namespace), user, access_params) .to receive(:new).with(bitbucket_repo, test_name, kind_of(Namespace), user, access_params)
.and_return(double(execute: true)) .and_return(double(execute: project))
post :create, { target_namespace: 'foo/bar', new_name: test_name, format: :js } post :create, { target_namespace: 'foo/bar', new_name: test_name, format: :json }
expect(Namespace.find_by_path_or_name('bar').parent.path).to eq('foo') expect(Namespace.find_by_path_or_name('bar').parent.path).to eq('foo')
end end
...@@ -256,19 +278,29 @@ describe Import::BitbucketController do ...@@ -256,19 +278,29 @@ describe Import::BitbucketController do
it 'takes the selected namespace and name' do it 'takes the selected namespace and name' do
expect(Gitlab::BitbucketImport::ProjectCreator) expect(Gitlab::BitbucketImport::ProjectCreator)
.to receive(:new).with(bitbucket_repo, test_name, kind_of(Namespace), user, access_params) .to receive(:new).with(bitbucket_repo, test_name, kind_of(Namespace), user, access_params)
.and_return(double(execute: true)) .and_return(double(execute: project))
post :create, { target_namespace: 'foo/foobar/bar', new_name: test_name, format: :js } post :create, { target_namespace: 'foo/foobar/bar', new_name: test_name, format: :json }
end end
it 'creates the namespaces' do it 'creates the namespaces' do
allow(Gitlab::BitbucketImport::ProjectCreator) allow(Gitlab::BitbucketImport::ProjectCreator)
.to receive(:new).with(bitbucket_repo, test_name, kind_of(Namespace), user, access_params) .to receive(:new).with(bitbucket_repo, test_name, kind_of(Namespace), user, access_params)
.and_return(double(execute: true)) .and_return(double(execute: project))
expect { post :create, { target_namespace: 'foo/foobar/bar', new_name: test_name, format: :js } } expect { post :create, { target_namespace: 'foo/foobar/bar', new_name: test_name, format: :json } }
.to change { Namespace.count }.by(2) .to change { Namespace.count }.by(2)
end end
end end
context 'when user can not create projects in the chosen namespace' do
it 'returns 422 response' do
other_namespace = create(:group, name: 'other_namespace')
post :create, { target_namespace: other_namespace.name, format: :json }
expect(response).to have_gitlab_http_status(422)
end
end
end end
end end
...@@ -57,6 +57,7 @@ describe Import::GitlabController do ...@@ -57,6 +57,7 @@ describe Import::GitlabController do
end end
describe "POST create" do describe "POST create" do
let(:project) { create(:project) }
let(:gitlab_username) { user.username } let(:gitlab_username) { user.username }
let(:gitlab_user) do let(:gitlab_user) do
{ username: gitlab_username }.with_indifferent_access { username: gitlab_username }.with_indifferent_access
...@@ -75,14 +76,34 @@ describe Import::GitlabController do ...@@ -75,14 +76,34 @@ describe Import::GitlabController do
assign_session_token assign_session_token
end end
it 'returns 200 response when the project is imported successfully' do
allow(Gitlab::GitlabImport::ProjectCreator)
.to receive(:new).with(gitlab_repo, user.namespace, user, access_params)
.and_return(double(execute: project))
post :create, format: :json
expect(response).to have_gitlab_http_status(200)
end
it 'returns 422 response when the project could not be imported' do
allow(Gitlab::GitlabImport::ProjectCreator)
.to receive(:new).with(gitlab_repo, user.namespace, user, access_params)
.and_return(double(execute: build(:project)))
post :create, format: :json
expect(response).to have_gitlab_http_status(422)
end
context "when the repository owner is the GitLab.com user" do context "when the repository owner is the GitLab.com user" do
context "when the GitLab.com user and GitLab server user's usernames match" do context "when the GitLab.com user and GitLab server user's usernames match" do
it "takes the current user's namespace" do it "takes the current user's namespace" do
expect(Gitlab::GitlabImport::ProjectCreator) expect(Gitlab::GitlabImport::ProjectCreator)
.to receive(:new).with(gitlab_repo, user.namespace, user, access_params) .to receive(:new).with(gitlab_repo, user.namespace, user, access_params)
.and_return(double(execute: true)) .and_return(double(execute: project))
post :create, format: :js post :create, format: :json
end end
end end
...@@ -92,9 +113,9 @@ describe Import::GitlabController do ...@@ -92,9 +113,9 @@ describe Import::GitlabController do
it "takes the current user's namespace" do it "takes the current user's namespace" do
expect(Gitlab::GitlabImport::ProjectCreator) expect(Gitlab::GitlabImport::ProjectCreator)
.to receive(:new).with(gitlab_repo, user.namespace, user, access_params) .to receive(:new).with(gitlab_repo, user.namespace, user, access_params)
.and_return(double(execute: true)) .and_return(double(execute: project))
post :create, format: :js post :create, format: :json
end end
end end
end end
...@@ -118,9 +139,9 @@ describe Import::GitlabController do ...@@ -118,9 +139,9 @@ describe Import::GitlabController do
it "takes the existing namespace" do it "takes the existing namespace" do
expect(Gitlab::GitlabImport::ProjectCreator) expect(Gitlab::GitlabImport::ProjectCreator)
.to receive(:new).with(gitlab_repo, existing_namespace, user, access_params) .to receive(:new).with(gitlab_repo, existing_namespace, user, access_params)
.and_return(double(execute: true)) .and_return(double(execute: project))
post :create, format: :js post :create, format: :json
end end
end end
...@@ -129,7 +150,7 @@ describe Import::GitlabController do ...@@ -129,7 +150,7 @@ describe Import::GitlabController do
expect(Gitlab::GitlabImport::ProjectCreator) expect(Gitlab::GitlabImport::ProjectCreator)
.not_to receive(:new) .not_to receive(:new)
post :create, format: :js post :create, format: :json
end end
end end
end end
...@@ -138,17 +159,17 @@ describe Import::GitlabController do ...@@ -138,17 +159,17 @@ describe Import::GitlabController do
context "when current user can create namespaces" do context "when current user can create namespaces" do
it "creates the namespace" do it "creates the namespace" do
expect(Gitlab::GitlabImport::ProjectCreator) expect(Gitlab::GitlabImport::ProjectCreator)
.to receive(:new).and_return(double(execute: true)) .to receive(:new).and_return(double(execute: project))
expect { post :create, format: :js }.to change(Namespace, :count).by(1) expect { post :create, format: :json }.to change(Namespace, :count).by(1)
end end
it "takes the new namespace" do it "takes the new namespace" do
expect(Gitlab::GitlabImport::ProjectCreator) expect(Gitlab::GitlabImport::ProjectCreator)
.to receive(:new).with(gitlab_repo, an_instance_of(Group), user, access_params) .to receive(:new).with(gitlab_repo, an_instance_of(Group), user, access_params)
.and_return(double(execute: true)) .and_return(double(execute: project))
post :create, format: :js post :create, format: :json
end end
end end
...@@ -159,17 +180,17 @@ describe Import::GitlabController do ...@@ -159,17 +180,17 @@ describe Import::GitlabController do
it "doesn't create the namespace" do it "doesn't create the namespace" do
expect(Gitlab::GitlabImport::ProjectCreator) expect(Gitlab::GitlabImport::ProjectCreator)
.to receive(:new).and_return(double(execute: true)) .to receive(:new).and_return(double(execute: project))
expect { post :create, format: :js }.not_to change(Namespace, :count) expect { post :create, format: :json }.not_to change(Namespace, :count)
end end
it "takes the current user's namespace" do it "takes the current user's namespace" do
expect(Gitlab::GitlabImport::ProjectCreator) expect(Gitlab::GitlabImport::ProjectCreator)
.to receive(:new).with(gitlab_repo, user.namespace, user, access_params) .to receive(:new).with(gitlab_repo, user.namespace, user, access_params)
.and_return(double(execute: true)) .and_return(double(execute: project))
post :create, format: :js post :create, format: :json
end end
end end
end end
...@@ -185,9 +206,9 @@ describe Import::GitlabController do ...@@ -185,9 +206,9 @@ describe Import::GitlabController do
it 'takes the selected namespace and name' do it 'takes the selected namespace and name' do
expect(Gitlab::GitlabImport::ProjectCreator) expect(Gitlab::GitlabImport::ProjectCreator)
.to receive(:new).with(gitlab_repo, nested_namespace, user, access_params) .to receive(:new).with(gitlab_repo, nested_namespace, user, access_params)
.and_return(double(execute: true)) .and_return(double(execute: project))
post :create, { target_namespace: nested_namespace.full_path, format: :js } post :create, { target_namespace: nested_namespace.full_path, format: :json }
end end
end end
...@@ -197,26 +218,26 @@ describe Import::GitlabController do ...@@ -197,26 +218,26 @@ describe Import::GitlabController do
it 'takes the selected namespace and name' do it 'takes the selected namespace and name' do
expect(Gitlab::GitlabImport::ProjectCreator) expect(Gitlab::GitlabImport::ProjectCreator)
.to receive(:new).with(gitlab_repo, kind_of(Namespace), user, access_params) .to receive(:new).with(gitlab_repo, kind_of(Namespace), user, access_params)
.and_return(double(execute: true)) .and_return(double(execute: project))
post :create, { target_namespace: 'foo/bar', format: :js } post :create, { target_namespace: 'foo/bar', format: :json }
end end
it 'creates the namespaces' do it 'creates the namespaces' do
allow(Gitlab::GitlabImport::ProjectCreator) allow(Gitlab::GitlabImport::ProjectCreator)
.to receive(:new).with(gitlab_repo, kind_of(Namespace), user, access_params) .to receive(:new).with(gitlab_repo, kind_of(Namespace), user, access_params)
.and_return(double(execute: true)) .and_return(double(execute: project))
expect { post :create, { target_namespace: 'foo/bar', format: :js } } expect { post :create, { target_namespace: 'foo/bar', format: :json } }
.to change { Namespace.count }.by(2) .to change { Namespace.count }.by(2)
end end
it 'new namespace has the right parent' do it 'new namespace has the right parent' do
allow(Gitlab::GitlabImport::ProjectCreator) allow(Gitlab::GitlabImport::ProjectCreator)
.to receive(:new).with(gitlab_repo, kind_of(Namespace), user, access_params) .to receive(:new).with(gitlab_repo, kind_of(Namespace), user, access_params)
.and_return(double(execute: true)) .and_return(double(execute: project))
post :create, { target_namespace: 'foo/bar', format: :js } post :create, { target_namespace: 'foo/bar', format: :json }
expect(Namespace.find_by_path_or_name('bar').parent.path).to eq('foo') expect(Namespace.find_by_path_or_name('bar').parent.path).to eq('foo')
end end
...@@ -229,20 +250,30 @@ describe Import::GitlabController do ...@@ -229,20 +250,30 @@ describe Import::GitlabController do
it 'takes the selected namespace and name' do it 'takes the selected namespace and name' do
expect(Gitlab::GitlabImport::ProjectCreator) expect(Gitlab::GitlabImport::ProjectCreator)
.to receive(:new).with(gitlab_repo, kind_of(Namespace), user, access_params) .to receive(:new).with(gitlab_repo, kind_of(Namespace), user, access_params)
.and_return(double(execute: true)) .and_return(double(execute: project))
post :create, { target_namespace: 'foo/foobar/bar', format: :js } post :create, { target_namespace: 'foo/foobar/bar', format: :json }
end end
it 'creates the namespaces' do it 'creates the namespaces' do
allow(Gitlab::GitlabImport::ProjectCreator) allow(Gitlab::GitlabImport::ProjectCreator)
.to receive(:new).with(gitlab_repo, kind_of(Namespace), user, access_params) .to receive(:new).with(gitlab_repo, kind_of(Namespace), user, access_params)
.and_return(double(execute: true)) .and_return(double(execute: project))
expect { post :create, { target_namespace: 'foo/foobar/bar', format: :js } } expect { post :create, { target_namespace: 'foo/foobar/bar', format: :json } }
.to change { Namespace.count }.by(2) .to change { Namespace.count }.by(2)
end end
end end
context 'when user can not create projects in the chosen namespace' do
it 'returns 422 response' do
other_namespace = create(:group, name: 'other_namespace')
post :create, { target_namespace: other_namespace.name, format: :json }
expect(response).to have_gitlab_http_status(422)
end
end
end end
end end
end end
import { ImporterStatus } from '~/importer_status';
import axios from '~/lib/utils/axios_utils';
import MockAdapter from 'axios-mock-adapter';
describe('Importer Status', () => {
describe('addToImport', () => {
let instance;
let mock;
const importUrl = '/import_url';
beforeEach(() => {
setFixtures(`
<tr id="repo_123">
<td class="import-target"></td>
<td class="import-actions job-status">
<button name="button" type="submit" class="btn btn-import js-add-to-import">
</button>
</td>
</tr>
`);
spyOn(ImporterStatus.prototype, 'initStatusPage').and.callFake(() => {});
spyOn(ImporterStatus.prototype, 'setAutoUpdate').and.callFake(() => {});
instance = new ImporterStatus('', importUrl);
mock = new MockAdapter(axios);
});
afterEach(() => {
mock.restore();
});
it('sets table row to active after post request', (done) => {
mock.onPost(importUrl).reply(200, {
id: 1,
full_path: '/full_path',
});
instance.addToImport({
currentTarget: document.querySelector('.js-add-to-import'),
})
.then(() => {
expect(document.querySelector('tr').classList.contains('active')).toEqual(true);
done();
})
.catch(done.fail);
});
});
});
import Vue from 'vue'; import Vue from 'vue';
import missingBranchComponent from '~/vue_merge_request_widget/components/states/mr_widget_missing_branch'; import missingBranchComponent from '~/vue_merge_request_widget/components/states/mr_widget_missing_branch.vue';
import mountComponent from '../../../helpers/vue_mount_component_helper';
const createComponent = () => {
const Component = Vue.extend(missingBranchComponent);
const mr = {
sourceBranchRemoved: true,
};
return new Component({
el: document.createElement('div'),
propsData: { mr },
});
};
describe('MRWidgetMissingBranch', () => { describe('MRWidgetMissingBranch', () => {
describe('props', () => { let vm;
it('should have props', () => {
const mrProp = missingBranchComponent.props.mr;
expect(mrProp.type instanceof Object).toBeTruthy(); beforeEach(() => {
expect(mrProp.required).toBeTruthy(); const Component = Vue.extend(missingBranchComponent);
}); vm = mountComponent(Component, { mr: { sourceBranchRemoved: true } });
}); });
describe('components', () => { afterEach(() => {
it('should have components added', () => { vm.$destroy();
expect(missingBranchComponent.components['mr-widget-merge-help']).toBeDefined();
});
}); });
describe('computed', () => { describe('computed', () => {
describe('missingBranchName', () => { describe('missingBranchName', () => {
it('should return proper branch name', () => { it('should return proper branch name', () => {
const vm = createComponent();
expect(vm.missingBranchName).toEqual('source'); expect(vm.missingBranchName).toEqual('source');
vm.mr.sourceBranchRemoved = false; vm.mr.sourceBranchRemoved = false;
...@@ -43,7 +27,7 @@ describe('MRWidgetMissingBranch', () => { ...@@ -43,7 +27,7 @@ describe('MRWidgetMissingBranch', () => {
describe('template', () => { describe('template', () => {
it('should have correct elements', () => { it('should have correct elements', () => {
const el = createComponent().$el; const el = vm.$el;
const content = el.textContent.replace(/\n(\s)+/g, ' ').trim(); const content = el.textContent.replace(/\n(\s)+/g, ' ').trim();
expect(el.classList.contains('mr-widget-body')).toBeTruthy(); expect(el.classList.contains('mr-widget-body')).toBeTruthy();
......
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