Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/blob/sketch/index.js73
-rw-r--r--app/assets/javascripts/blob/sketch_viewer.js8
-rw-r--r--app/assets/javascripts/boards/components/board.js4
-rw-r--r--app/assets/javascripts/boards/components/board_list.js286
-rw-r--r--app/assets/javascripts/boards/components/board_new_issue.js4
-rw-r--r--app/assets/javascripts/groups_select.js4
-rw-r--r--app/assets/stylesheets/framework/blocks.scss4
-rw-r--r--app/controllers/groups/application_controller.rb1
-rw-r--r--app/controllers/import/base_controller.rb28
-rw-r--r--app/models/blob.rb6
-rw-r--r--app/models/ci/build.rb6
-rw-r--r--app/models/project.rb2
-rw-r--r--app/models/project_services/mock_deployment_service.rb18
-rw-r--r--app/models/project_services/mock_monitoring_service.rb17
-rw-r--r--app/models/service.rb4
-rw-r--r--app/views/groups/merge_requests.html.haml30
-rw-r--r--app/views/projects/blob/_sketch.html.haml7
-rw-r--r--app/views/projects/boards/_show.html.haml1
-rw-r--r--app/views/projects/boards/components/_board_list.html.haml26
-rw-r--r--app/views/projects/merge_requests/_merge_requests.html.haml8
-rw-r--r--app/views/projects/merge_requests/index.html.haml25
-rw-r--r--app/views/shared/_merge_requests.html.haml2
-rw-r--r--app/views/shared/empty_states/_merge_requests.html.haml22
-rw-r--r--app/views/shared/empty_states/icons/_merge_requests.svg1
-rw-r--r--changelogs/unreleased/20841-getting-started-better-empty-state-for-merge-requests-view.yml4
-rw-r--r--changelogs/unreleased/add-mock-deployment-and-monitoring-service-for-development.yaml4
-rw-r--r--changelogs/unreleased/fix-groups-long-url.yml4
-rw-r--r--changelogs/unreleased/fix-import-namespace.yml4
-rw-r--r--config/dependency_decisions.yml18
-rw-r--r--config/webpack.config.js1
-rw-r--r--db/fixtures/development/19_environments.rb70
-rw-r--r--db/fixtures/development/20_nested_groups.rb (renamed from db/fixtures/development/19_nested_groups.rb)0
-rw-r--r--features/dashboard/dashboard.feature3
-rw-r--r--features/project/issues/issues.feature6
-rw-r--r--features/steps/project/fork.rb3
-rw-r--r--features/steps/project/forked_merge_requests.rb2
-rw-r--r--features/steps/project/merge_requests.rb2
-rw-r--r--features/steps/shared/project.rb4
-rw-r--r--lib/api/services.rb8
-rw-r--r--package.json2
-rw-r--r--spec/controllers/import/bitbucket_controller_spec.rb67
-rw-r--r--spec/controllers/import/gitlab_controller_spec.rb66
-rw-r--r--spec/features/dashboard/merge_requests_spec.rb32
-rw-r--r--spec/features/groups/empty_states_spec.rb70
-rw-r--r--spec/features/merge_requests/create_new_mr_spec.rb8
-rw-r--r--spec/features/projects/merge_requests/list_spec.rb24
-rw-r--r--spec/features/search_spec.rb2
-rw-r--r--spec/fixtures/metrics.json1
-rw-r--r--spec/javascripts/blob/sketch/index_spec.js118
-rw-r--r--spec/javascripts/boards/board_list_spec.js201
-rw-r--r--spec/javascripts/fixtures/sketch_viewer.html.haml2
-rw-r--r--spec/lib/gitlab/import_export/all_models.yml2
-rw-r--r--spec/models/blob_spec.rb22
-rw-r--r--spec/requests/api/runner_spec.rb23
-rw-r--r--spec/support/controllers/githubish_import_controller_shared_examples.rb59
-rw-r--r--yarn.lock38
56 files changed, 1259 insertions, 198 deletions
diff --git a/app/assets/javascripts/blob/sketch/index.js b/app/assets/javascripts/blob/sketch/index.js
new file mode 100644
index 00000000000..0799991aa40
--- /dev/null
+++ b/app/assets/javascripts/blob/sketch/index.js
@@ -0,0 +1,73 @@
+import JSZip from 'jszip';
+import JSZipUtils from 'jszip-utils';
+
+export default class SketchLoader {
+ constructor(container) {
+ this.container = container;
+ this.loadingIcon = this.container.querySelector('.js-loading-icon');
+
+ this.load();
+ }
+
+ load() {
+ return this.getZipFile()
+ .then(data => JSZip.loadAsync(data))
+ .then(asyncResult => asyncResult.files['previews/preview.png'].async('uint8array'))
+ .then((content) => {
+ const url = window.URL || window.webkitURL;
+ const blob = new Blob([new Uint8Array(content)], {
+ type: 'image/png',
+ });
+ const previewUrl = url.createObjectURL(blob);
+
+ this.render(previewUrl);
+ })
+ .catch(this.error.bind(this));
+ }
+
+ getZipFile() {
+ return new JSZip.external.Promise((resolve, reject) => {
+ JSZipUtils.getBinaryContent(this.container.dataset.endpoint, (err, data) => {
+ if (err) {
+ reject(err);
+ } else {
+ resolve(data);
+ }
+ });
+ });
+ }
+
+ render(previewUrl) {
+ const previewLink = document.createElement('a');
+ const previewImage = document.createElement('img');
+
+ previewLink.href = previewUrl;
+ previewLink.target = '_blank';
+ previewImage.src = previewUrl;
+ previewImage.className = 'img-responsive';
+
+ previewLink.appendChild(previewImage);
+ this.container.appendChild(previewLink);
+
+ this.removeLoadingIcon();
+ }
+
+ error() {
+ const errorMsg = document.createElement('p');
+
+ errorMsg.className = 'prepend-top-default append-bottom-default text-center';
+ errorMsg.textContent = `
+ Cannot show preview. For previews on sketch files, they must have the file format
+ introduced by Sketch version 43 and above.
+ `;
+ this.container.appendChild(errorMsg);
+
+ this.removeLoadingIcon();
+ }
+
+ removeLoadingIcon() {
+ if (this.loadingIcon) {
+ this.loadingIcon.remove();
+ }
+ }
+}
diff --git a/app/assets/javascripts/blob/sketch_viewer.js b/app/assets/javascripts/blob/sketch_viewer.js
new file mode 100644
index 00000000000..0640dd26855
--- /dev/null
+++ b/app/assets/javascripts/blob/sketch_viewer.js
@@ -0,0 +1,8 @@
+/* eslint-disable no-new */
+import SketchLoader from './sketch';
+
+document.addEventListener('DOMContentLoaded', () => {
+ const el = document.getElementById('js-sketch-viewer');
+
+ new SketchLoader(el);
+});
diff --git a/app/assets/javascripts/boards/components/board.js b/app/assets/javascripts/boards/components/board.js
index 35b3205cca7..93b8960da2e 100644
--- a/app/assets/javascripts/boards/components/board.js
+++ b/app/assets/javascripts/boards/components/board.js
@@ -1,7 +1,7 @@
/* eslint-disable comma-dangle, space-before-function-paren, one-var */
/* global Sortable */
-
import Vue from 'vue';
+import boardList from './board_list';
import boardBlankState from './board_blank_state';
require('./board_delete');
@@ -16,7 +16,7 @@ require('./board_list');
gl.issueBoards.Board = Vue.extend({
template: '#js-board-template',
components: {
- 'board-list': gl.issueBoards.BoardList,
+ boardList,
'board-delete': gl.issueBoards.BoardDelete,
boardBlankState,
},
diff --git a/app/assets/javascripts/boards/components/board_list.js b/app/assets/javascripts/boards/components/board_list.js
index 86e6c26e570..adbd82cb687 100644
--- a/app/assets/javascripts/boards/components/board_list.js
+++ b/app/assets/javascripts/boards/components/board_list.js
@@ -1,131 +1,197 @@
-/* eslint-disable comma-dangle, space-before-function-paren, max-len */
/* global Sortable */
-
-import Vue from 'vue';
import boardNewIssue from './board_new_issue';
import boardCard from './board_card';
+import eventHub from '../eventhub';
-(() => {
- const Store = gl.issueBoards.BoardsStore;
-
- window.gl = window.gl || {};
- window.gl.issueBoards = window.gl.issueBoards || {};
+const Store = gl.issueBoards.BoardsStore;
- gl.issueBoards.BoardList = Vue.extend({
- template: '#js-board-list-template',
- components: {
- boardCard,
- boardNewIssue,
+export default {
+ name: 'BoardList',
+ props: {
+ disabled: {
+ type: Boolean,
+ required: true,
},
- props: {
- disabled: Boolean,
- list: Object,
- issues: Array,
- loading: Boolean,
- issueLinkBase: String,
- rootPath: String,
+ list: {
+ type: Object,
+ required: true,
},
- data () {
- return {
- scrollOffset: 250,
- filters: Store.state.filters,
- showCount: false,
- showIssueForm: false
- };
+ issues: {
+ type: Array,
+ required: true,
},
- watch: {
- filters: {
- handler () {
- this.list.loadingMore = false;
- this.$refs.list.scrollTop = 0;
- },
- deep: true
- },
- issues () {
- this.$nextTick(() => {
- if (this.scrollHeight() <= this.listHeight() && this.list.issuesSize > this.list.issues.length) {
- this.list.page += 1;
- this.list.getIssues(false);
- }
+ loading: {
+ type: Boolean,
+ required: true,
+ },
+ issueLinkBase: {
+ type: String,
+ required: true,
+ },
+ rootPath: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ scrollOffset: 250,
+ filters: Store.state.filters,
+ showCount: false,
+ showIssueForm: false,
+ };
+ },
+ components: {
+ boardCard,
+ boardNewIssue,
+ },
+ methods: {
+ listHeight() {
+ return this.$refs.list.getBoundingClientRect().height;
+ },
+ scrollHeight() {
+ return this.$refs.list.scrollHeight;
+ },
+ scrollTop() {
+ return this.$refs.list.scrollTop + this.listHeight();
+ },
+ loadNextPage() {
+ const getIssues = this.list.nextPage();
- if (this.scrollHeight() > Math.ceil(this.listHeight())) {
- this.showCount = true;
- } else {
- this.showCount = false;
- }
+ if (getIssues) {
+ this.list.loadingMore = true;
+ getIssues.then(() => {
+ this.list.loadingMore = false;
});
}
},
- methods: {
- listHeight () {
- return this.$refs.list.getBoundingClientRect().height;
- },
- scrollHeight () {
- return this.$refs.list.scrollHeight;
- },
- scrollTop () {
- return this.$refs.list.scrollTop + this.listHeight();
+ toggleForm() {
+ this.showIssueForm = !this.showIssueForm;
+ },
+ onScroll() {
+ if ((this.scrollTop() > this.scrollHeight() - this.scrollOffset) && !this.list.loadingMore) {
+ this.loadNextPage();
+ }
+ },
+ },
+ watch: {
+ filters: {
+ handler() {
+ this.list.loadingMore = false;
+ this.$refs.list.scrollTop = 0;
},
- loadNextPage () {
- const getIssues = this.list.nextPage();
+ deep: true,
+ },
+ issues() {
+ this.$nextTick(() => {
+ if (this.scrollHeight() <= this.listHeight() &&
+ this.list.issuesSize > this.list.issues.length) {
+ this.list.page += 1;
+ this.list.getIssues(false);
+ }
- if (getIssues) {
- this.list.loadingMore = true;
- getIssues.then(() => {
- this.list.loadingMore = false;
- });
+ if (this.scrollHeight() > Math.ceil(this.listHeight())) {
+ this.showCount = true;
+ } else {
+ this.showCount = false;
}
- },
- toggleForm() {
- this.showIssueForm = !this.showIssueForm;
- },
- },
- created() {
- gl.IssueBoardsApp.$on(`hide-issue-form-${this.list.id}`, this.toggleForm);
+ });
},
- mounted () {
- const options = gl.issueBoards.getBoardSortableDefaultOptions({
- scroll: document.querySelectorAll('.boards-list')[0],
- group: 'issues',
- disabled: this.disabled,
- filter: '.board-list-count, .is-disabled',
- dataIdAttr: 'data-issue-id',
- onStart: (e) => {
- const card = this.$refs.issue[e.oldIndex];
+ },
+ created() {
+ eventHub.$on(`hide-issue-form-${this.list.id}`, this.toggleForm);
+ },
+ mounted() {
+ const options = gl.issueBoards.getBoardSortableDefaultOptions({
+ scroll: document.querySelectorAll('.boards-list')[0],
+ group: 'issues',
+ disabled: this.disabled,
+ filter: '.board-list-count, .is-disabled',
+ dataIdAttr: 'data-issue-id',
+ onStart: (e) => {
+ const card = this.$refs.issue[e.oldIndex];
- card.showDetail = false;
- Store.moving.list = card.list;
- Store.moving.issue = Store.moving.list.findIssue(+e.item.dataset.issueId);
+ card.showDetail = false;
+ Store.moving.list = card.list;
+ Store.moving.issue = Store.moving.list.findIssue(+e.item.dataset.issueId);
- gl.issueBoards.onStart();
- },
- onAdd: (e) => {
- gl.issueBoards.BoardsStore.moveIssueToList(Store.moving.list, this.list, Store.moving.issue, e.newIndex);
+ gl.issueBoards.onStart();
+ },
+ onAdd: (e) => {
+ gl.issueBoards.BoardsStore
+ .moveIssueToList(Store.moving.list, this.list, Store.moving.issue, e.newIndex);
- this.$nextTick(() => {
- e.item.remove();
- });
- },
- onUpdate: (e) => {
- const sortedArray = this.sortable.toArray().filter(id => id !== '-1');
- gl.issueBoards.BoardsStore.moveIssueInList(this.list, Store.moving.issue, e.oldIndex, e.newIndex, sortedArray);
- },
- onMove(e) {
- return !e.related.classList.contains('board-list-count');
- }
- });
+ this.$nextTick(() => {
+ e.item.remove();
+ });
+ },
+ onUpdate: (e) => {
+ const sortedArray = this.sortable.toArray().filter(id => id !== '-1');
+ gl.issueBoards.BoardsStore
+ .moveIssueInList(this.list, Store.moving.issue, e.oldIndex, e.newIndex, sortedArray);
+ },
+ onMove(e) {
+ return !e.related.classList.contains('board-list-count');
+ },
+ });
- this.sortable = Sortable.create(this.$refs.list, options);
+ this.sortable = Sortable.create(this.$refs.list, options);
- // Scroll event on list to load more
- this.$refs.list.onscroll = () => {
- if ((this.scrollTop() > this.scrollHeight() - this.scrollOffset) && !this.list.loadingMore) {
- this.loadNextPage();
- }
- };
- },
- beforeDestroy() {
- gl.IssueBoardsApp.$off(`hide-issue-form-${this.list.id}`, this.toggleForm);
- },
- });
-})();
+ // Scroll event on list to load more
+ this.$refs.list.addEventListener('scroll', this.onScroll);
+ },
+ beforeDestroy() {
+ eventHub.$off(`hide-issue-form-${this.list.id}`, this.toggleForm);
+ this.$refs.list.removeEventListener('scroll', this.onScroll);
+ },
+ template: `
+ <div class="board-list-component">
+ <div
+ class="board-list-loading text-center"
+ aria-label="Loading issues"
+ v-if="loading">
+ <i
+ class="fa fa-spinner fa-spin"
+ aria-hidden="true">
+ </i>
+ </div>
+ <board-new-issue
+ :list="list"
+ v-if="list.type !== 'closed' && showIssueForm"/>
+ <ul
+ class="board-list"
+ v-show="!loading"
+ ref="list"
+ :data-board="list.id"
+ :class="{ 'is-smaller': showIssueForm }">
+ <board-card
+ v-for="(issue, index) in issues"
+ ref="issue"
+ :index="index"
+ :list="list"
+ :issue="issue"
+ :issue-link-base="issueLinkBase"
+ :root-path="rootPath"
+ :disabled="disabled"
+ :key="issue.id" />
+ <li
+ class="board-list-count text-center"
+ v-if="showCount"
+ data-id="-1">
+ <i
+ class="fa fa-spinner fa-spin"
+ aria-label="Loading more issues"
+ aria-hidden="true"
+ v-show="list.loadingMore">
+ </i>
+ <span v-if="list.issues.length === list.issuesSize">
+ Showing all issues
+ </span>
+ <span v-else>
+ Showing {{ list.issues.length }} of {{ list.issuesSize }} issues
+ </span>
+ </li>
+ </ul>
+ </div>
+ `,
+};
diff --git a/app/assets/javascripts/boards/components/board_new_issue.js b/app/assets/javascripts/boards/components/board_new_issue.js
index b88f59dd6d4..0fa85b6fe14 100644
--- a/app/assets/javascripts/boards/components/board_new_issue.js
+++ b/app/assets/javascripts/boards/components/board_new_issue.js
@@ -1,4 +1,6 @@
/* global ListIssue */
+import eventHub from '../eventhub';
+
const Store = gl.issueBoards.BoardsStore;
export default {
@@ -49,7 +51,7 @@ export default {
},
cancel() {
this.title = '';
- gl.IssueBoardsApp.$emit(`hide-issue-form-${this.list.id}`);
+ eventHub.$emit(`hide-issue-form-${this.list.id}`);
},
},
mounted() {
diff --git a/app/assets/javascripts/groups_select.js b/app/assets/javascripts/groups_select.js
index 602a3b78189..10363c16bae 100644
--- a/app/assets/javascripts/groups_select.js
+++ b/app/assets/javascripts/groups_select.js
@@ -45,14 +45,14 @@ window.GroupsSelect = (function() {
page,
per_page: GroupsSelect.PER_PAGE,
all_available,
- skip_groups,
};
},
results: function (data, page) {
if (data.length) return { results: [] };
- const results = data.length ? data : data.results || [];
+ const groups = data.length ? data : data.results || [];
const more = data.pagination ? data.pagination.more : false;
+ const results = groups.filter(group => skip_groups.indexOf(group.id) === -1);
return {
results,
diff --git a/app/assets/stylesheets/framework/blocks.scss b/app/assets/stylesheets/framework/blocks.scss
index 9a4129cdc8d..52425262925 100644
--- a/app/assets/stylesheets/framework/blocks.scss
+++ b/app/assets/stylesheets/framework/blocks.scss
@@ -292,6 +292,10 @@
}
@media(min-width: $screen-xs-max) {
+ &.merge-requests .text-content {
+ margin-top: 40px;
+ }
+
&.labels .text-content {
margin-top: 70px;
}
diff --git a/app/controllers/groups/application_controller.rb b/app/controllers/groups/application_controller.rb
index c411c21bb80..8b69c18d689 100644
--- a/app/controllers/groups/application_controller.rb
+++ b/app/controllers/groups/application_controller.rb
@@ -10,6 +10,7 @@ class Groups::ApplicationController < ApplicationController
unless @group
id = params[:group_id] || params[:id]
@group = Group.find_by_full_path(id)
+ @group_merge_requests = MergeRequestsFinder.new(current_user, group_id: @group.id).execute
unless @group && can?(current_user, :read_group, @group)
@group = nil
diff --git a/app/controllers/import/base_controller.rb b/app/controllers/import/base_controller.rb
index eeee027ef2d..9de0297ecfd 100644
--- a/app/controllers/import/base_controller.rb
+++ b/app/controllers/import/base_controller.rb
@@ -1,17 +1,27 @@
class Import::BaseController < ApplicationController
private
- def find_or_create_namespace(name, owner)
- return current_user.namespace if name == owner
+ def find_or_create_namespace(names, owner)
+ return current_user.namespace if names == owner
return current_user.namespace unless current_user.can_create_group?
- begin
- name = params[:target_namespace].presence || name
- namespace = Group.create!(name: name, path: name, owner: current_user)
- namespace.add_owner(current_user)
- namespace
- rescue ActiveRecord::RecordNotUnique, ActiveRecord::RecordInvalid
- Namespace.find_by_full_path(name)
+ names = params[:target_namespace].presence || names
+ full_path_namespace = Namespace.find_by_full_path(names)
+
+ return full_path_namespace if full_path_namespace
+
+ names.split('/').inject(nil) do |parent, name|
+ begin
+ namespace = Group.create!(name: name,
+ path: name,
+ owner: current_user,
+ parent: parent)
+ namespace.add_owner(current_user)
+
+ namespace
+ rescue ActiveRecord::RecordNotUnique, ActiveRecord::RecordInvalid
+ Namespace.where(parent: parent).find_by_path_or_name(name)
+ end
end
end
end
diff --git a/app/models/blob.rb b/app/models/blob.rb
index 95d2111a992..1c451a3976f 100644
--- a/app/models/blob.rb
+++ b/app/models/blob.rb
@@ -50,6 +50,10 @@ class Blob < SimpleDelegator
text? && language&.name == 'Jupyter Notebook'
end
+ def sketch?
+ binary? && extname.downcase.delete('.') == 'sketch'
+ end
+
def size_within_svg_limits?
size <= MAXIMUM_SVG_SIZE
end
@@ -69,6 +73,8 @@ class Blob < SimpleDelegator
'image'
elsif ipython_notebook?
'notebook'
+ elsif sketch?
+ 'sketch'
elsif text?
'text'
else
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index ad0be70c32a..8431c5f228c 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -540,6 +540,8 @@ module Ci
end
def dependencies
+ return [] if empty_dependencies?
+
depended_jobs = depends_on_builds
return depended_jobs unless options[:dependencies].present?
@@ -549,6 +551,10 @@ module Ci
end
end
+ def empty_dependencies?
+ options[:dependencies]&.empty?
+ end
+
private
def update_artifacts_size
diff --git a/app/models/project.rb b/app/models/project.rb
index 83660d8c431..12fd0668ff8 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -114,6 +114,8 @@ class Project < ActiveRecord::Base
has_one :kubernetes_service, dependent: :destroy, inverse_of: :project
has_one :prometheus_service, dependent: :destroy, inverse_of: :project
has_one :mock_ci_service, dependent: :destroy
+ has_one :mock_deployment_service, dependent: :destroy
+ has_one :mock_monitoring_service, dependent: :destroy
has_one :forked_project_link, dependent: :destroy, foreign_key: "forked_to_project_id"
has_one :forked_from_project, through: :forked_project_link
diff --git a/app/models/project_services/mock_deployment_service.rb b/app/models/project_services/mock_deployment_service.rb
new file mode 100644
index 00000000000..59a3811ce5d
--- /dev/null
+++ b/app/models/project_services/mock_deployment_service.rb
@@ -0,0 +1,18 @@
+class MockDeploymentService < DeploymentService
+ def title
+ 'Mock deployment'
+ end
+
+ def description
+ 'Mock deployment service'
+ end
+
+ def self.to_param
+ 'mock_deployment'
+ end
+
+ # No terminals support
+ def terminals(environment)
+ []
+ end
+end
diff --git a/app/models/project_services/mock_monitoring_service.rb b/app/models/project_services/mock_monitoring_service.rb
new file mode 100644
index 00000000000..dd04e04e198
--- /dev/null
+++ b/app/models/project_services/mock_monitoring_service.rb
@@ -0,0 +1,17 @@
+class MockMonitoringService < MonitoringService
+ def title
+ 'Mock monitoring'
+ end
+
+ def description
+ 'Mock monitoring service'
+ end
+
+ def self.to_param
+ 'mock_monitoring'
+ end
+
+ def metrics(environment)
+ JSON.parse(File.read(Rails.root + 'spec/fixtures/metrics.json'))
+ end
+end
diff --git a/app/models/service.rb b/app/models/service.rb
index 54550177744..5a0ec58d193 100644
--- a/app/models/service.rb
+++ b/app/models/service.rb
@@ -238,7 +238,9 @@ class Service < ActiveRecord::Base
slack
teamcity
]
- service_names << 'mock_ci' if Rails.env.development?
+ if Rails.env.development?
+ service_names += %w[mock_ci mock_deployment mock_monitoring]
+ end
service_names.sort_by(&:downcase)
end
diff --git a/app/views/groups/merge_requests.html.haml b/app/views/groups/merge_requests.html.haml
index 6ad76d23df5..8fe0bd149f3 100644
--- a/app/views/groups/merge_requests.html.haml
+++ b/app/views/groups/merge_requests.html.haml
@@ -1,18 +1,22 @@
- page_title "Merge Requests"
-.top-area
- = render 'shared/issuable/nav', type: :merge_requests
- - if current_user
- .nav-controls
- = render 'shared/new_project_item_select', path: 'merge_requests/new', label: "New Merge Request"
+- if @group_merge_requests.empty?
+ = render 'shared/empty_states/merge_requests', project_select_button: true
+- else
+ .top-area
+ = render 'shared/issuable/nav', type: :merge_requests
+ - if current_user
+ .nav-controls
+ = render 'shared/new_project_item_select', path: 'merge_requests/new', label: "New merge request"
-= render 'shared/issuable/filter', type: :merge_requests
+ = render 'shared/issuable/filter', type: :merge_requests
-.row-content-block.second-block
- Only merge requests from
- %strong= @group.name
- group are listed here.
- - if current_user
- To see all merge requests you should visit #{link_to 'dashboard', merge_requests_dashboard_path} page.
+ .row-content-block.second-block
+ Only merge requests from
+ %strong= @group.name
+ group are listed here.
+ - if current_user
+ To see all merge requests you should visit #{link_to 'dashboard', merge_requests_dashboard_path} page.
-= render 'shared/merge_requests'
+ .prepend-top-default
+ = render 'shared/merge_requests'
diff --git a/app/views/projects/blob/_sketch.html.haml b/app/views/projects/blob/_sketch.html.haml
new file mode 100644
index 00000000000..dad9369cb2a
--- /dev/null
+++ b/app/views/projects/blob/_sketch.html.haml
@@ -0,0 +1,7 @@
+- content_for :page_specific_javascripts do
+ = page_specific_javascript_bundle_tag('common_vue')
+ = page_specific_javascript_bundle_tag('sketch_viewer')
+
+.file-content#js-sketch-viewer{ data: { endpoint: namespace_project_raw_path(@project.namespace, @project, @id) } }
+ .js-loading-icon.text-center.prepend-top-default.append-bottom-default.js-loading-icon{ 'aria-label' => 'Loading Sketch preview' }
+ = icon('spinner spin 2x', 'aria-hidden' => 'true');
diff --git a/app/views/projects/boards/_show.html.haml b/app/views/projects/boards/_show.html.haml
index d93eac63bd3..7ca0ec8ed2b 100644
--- a/app/views/projects/boards/_show.html.haml
+++ b/app/views/projects/boards/_show.html.haml
@@ -8,7 +8,6 @@
= page_specific_javascript_bundle_tag('boards')
%script#js-board-template{ type: "text/x-template" }= render "projects/boards/components/board"
- %script#js-board-list-template{ type: "text/x-template" }= render "projects/boards/components/board_list"
%script#js-board-modal-filter{ type: "text/x-template" }= render "shared/issuable/search_bar", type: :boards_modal
= render "projects/issues/head"
diff --git a/app/views/projects/boards/components/_board_list.html.haml b/app/views/projects/boards/components/_board_list.html.haml
deleted file mode 100644
index 4a0b2110601..00000000000
--- a/app/views/projects/boards/components/_board_list.html.haml
+++ /dev/null
@@ -1,26 +0,0 @@
-.board-list-component
- .board-list-loading.text-center{ "v-if" => "loading" }
- = icon("spinner spin")
- - if can? current_user, :create_issue, @project
- %board-new-issue{ ":list" => "list",
- "v-if" => 'list.type !== "closed" && showIssueForm' }
- %ul.board-list{ "ref" => "list",
- "v-show" => "!loading",
- ":data-board" => "list.id",
- ":class" => '{ "is-smaller": showIssueForm }' }
- %board-card{ "v-for" => "(issue, index) in issues",
- "ref" => "issue",
- ":index" => "index",
- ":list" => "list",
- ":issue" => "issue",
- ":issue-link-base" => "issueLinkBase",
- ":root-path" => "rootPath",
- ":disabled" => "disabled",
- ":key" => "issue.id" }
- %li.board-list-count.text-center{ "v-if" => "showCount",
- "data-issue-id" => "-1" }
- = icon("spinner spin", "v-show" => "list.loadingMore" )
- %span{ "v-if" => "list.issues.length === list.issuesSize" }
- Showing all issues
- %span{ "v-else" => true }
- Showing {{ list.issues.length }} of {{ list.issuesSize }} issues
diff --git a/app/views/projects/merge_requests/_merge_requests.html.haml b/app/views/projects/merge_requests/_merge_requests.html.haml
index fe82f751f53..4e97f74dd6a 100644
--- a/app/views/projects/merge_requests/_merge_requests.html.haml
+++ b/app/views/projects/merge_requests/_merge_requests.html.haml
@@ -1,8 +1,8 @@
%ul.content-list.mr-list.issuable-list
- = render @merge_requests
- - if @merge_requests.blank?
- %li
- .nothing-here-block No merge requests to show
+ - if @merge_requests.exists?
+ = render @merge_requests
+ - else
+ = render 'shared/empty_states/merge_requests'
- if @merge_requests.present?
= paginate @merge_requests, theme: "gitlab"
diff --git a/app/views/projects/merge_requests/index.html.haml b/app/views/projects/merge_requests/index.html.haml
index 8a96c8dacf6..64f17ab34b1 100644
--- a/app/views/projects/merge_requests/index.html.haml
+++ b/app/views/projects/merge_requests/index.html.haml
@@ -7,16 +7,19 @@
- content_for :page_specific_javascripts do
= page_specific_javascript_bundle_tag('filtered_search')
-%div{ class: container_class }
- .top-area
- = render 'shared/issuable/nav', type: :merge_requests
- .nav-controls
- - merge_project = can?(current_user, :create_merge_request, @project) ? @project : (current_user && current_user.fork_of(@project))
- - if merge_project
- = link_to new_namespace_project_merge_request_path(merge_project.namespace, merge_project), class: "btn btn-new", title: "New Merge Request" do
- New Merge Request
+- if @project.merge_requests.exists?
+ %div{ class: container_class }
+ .top-area
+ = render 'shared/issuable/nav', type: :merge_requests
+ .nav-controls
+ - merge_project = can?(current_user, :create_merge_request, @project) ? @project : (current_user && current_user.fork_of(@project))
+ - if merge_project
+ = link_to new_namespace_project_merge_request_path(merge_project.namespace, merge_project), class: "btn btn-new", title: "New merge request" do
+ New merge request
- = render 'shared/issuable/search_bar', type: :merge_requests
+ = render 'shared/issuable/search_bar', type: :merge_requests
- .merge-requests-holder
- = render 'merge_requests'
+ .merge-requests-holder
+ = render 'merge_requests'
+- else
+ = render 'shared/empty_states/merge_requests', button_path: new_namespace_project_merge_request_path(@project.namespace, @project)
diff --git a/app/views/shared/_merge_requests.html.haml b/app/views/shared/_merge_requests.html.haml
index b7982b7fe9b..eecbb32e90e 100644
--- a/app/views/shared/_merge_requests.html.haml
+++ b/app/views/shared/_merge_requests.html.haml
@@ -6,4 +6,4 @@
= paginate @merge_requests, theme: "gitlab"
- else
- .nothing-here-block No merge requests to show
+ = render 'shared/empty_states/merge_requests'
diff --git a/app/views/shared/empty_states/_merge_requests.html.haml b/app/views/shared/empty_states/_merge_requests.html.haml
new file mode 100644
index 00000000000..7f2f99f3406
--- /dev/null
+++ b/app/views/shared/empty_states/_merge_requests.html.haml
@@ -0,0 +1,22 @@
+- button_path = local_assigns.fetch(:button_path, false)
+- project_select_button = local_assigns.fetch(:project_select_button, false)
+- has_button = button_path || project_select_button
+
+.row.empty-state.merge-requests
+ .col-xs-12{ class: "#{'col-sm-6 pull-right' if has_button}" }
+ .svg-content
+ = render 'shared/empty_states/icons/merge_requests.svg'
+ .col-xs-12{ class: "#{'col-sm-6' if has_button}" }
+ .text-content
+ - if has_button
+ %h4
+ Merge requests are a place to propose changes you've made to a project and discuss those changes with others.
+ %p
+ Interested parties can even contribute by pushing commits if they want to.
+ - if project_select_button
+ = render 'shared/new_project_item_select', path: 'merge_requests/new', label: 'New merge request'
+ - else
+ = link_to 'New merge request', button_path, class: 'btn btn-new', title: 'New merge request', id: 'new_merge_request_link'
+ - else
+ %h4.text-center
+ There are no merge requests to show.
diff --git a/app/views/shared/empty_states/icons/_merge_requests.svg b/app/views/shared/empty_states/icons/_merge_requests.svg
new file mode 100644
index 00000000000..e77f6319a95
--- /dev/null
+++ b/app/views/shared/empty_states/icons/_merge_requests.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="755 221 385 225" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><rect id="a" width="278" height="179" rx="10"/><mask id="d" width="278" height="179" x="0" y="0" fill="#fff"><use xlink:href="#a"/></mask><path id="b" d="M13.6 49H57c5.5 0 10-4.5 10-10V10c0-5.5-4.5-10-10-10H10C4.5 0 0 4.5 0 10v42c0 5.5 3.2 7 7.2 3l6.4-6z"/><mask id="e" width="67" height="57.2" x="0" y="0" fill="#fff"><use xlink:href="#b"/></mask><path id="c" d="M13.6 49H57c5.5 0 10-4.5 10-10V10c0-5.5-4.5-10-10-10H10C4.5 0 0 4.5 0 10v42c0 5.5 3.2 7 7.2 3l6.4-6z"/><mask id="f" width="67" height="57.2" x="0" y="0" fill="#fff"><use xlink:href="#c"/></mask></defs><g fill="none" fill-rule="evenodd"><g fill="#F9F9F9" transform="translate(752 227)"><rect width="120" height="22" x="30" rx="11"/><rect width="132" height="22" y="44" rx="11"/><rect width="190" height="22" x="208" y="66" rx="11"/><rect width="158" height="22" x="129" y="197" rx="11"/><rect width="158" height="22" x="66" y="154" rx="11"/><rect width="350" height="22" x="31" y="110" rx="11"/><path d="M153 22H21h21.5c6 0 11 5 11 11s-5 11-11 11H21h132-36.5c-6 0-11-5-11-11s5-11 11-11H153zm252 66H288h36.5c6 0 11 5 11 11s-5 11-11 11H288h117-36.5c-6 0-11-5-11-11s5-11 11-11H405zm-244 44H44h36.5c6 0 11 5 11 11s-5 11-11 11H44h117-36.5c-6 0-11-5-11-11s5-11 11-11H161zm75 44H119h21.5c6 0 11 5 11 11s-5 11-11 11H119h117-51.5c-6 0-11-5-11-11s5-11 11-11H236z"/></g><g transform="translate(812 240)"><use fill="#FFF" stroke="#EEE" stroke-width="8" mask="url(#d)" xlink:href="#a"/><path fill="#EEE" d="M4 29h271v4H4z"/><g transform="translate(34 60)"><rect width="6" height="2" y="1" fill="#B5A7DD" rx="1"/><rect width="15" height="4" x="15" fill="#EEE" rx="2"/><rect width="15" height="4" x="72" fill="#EEE" rx="2"/><rect width="15" height="4" x="39" y="22" fill="#EEE" rx="2"/><rect width="15" height="4" x="53" y="11" fill="#FC6D26" rx="2"/><rect width="20" height="4" x="48" fill="#FC6D26" opacity=".5" rx="2"/><rect width="20" height="4" x="15" y="22" fill="#EEE" rx="2"/><rect width="20" height="4" x="29" y="11" fill="#EEE" rx="2"/><rect width="10" height="4" x="34" fill="#FC6D26" rx="2"/><rect width="10" height="4" x="15" y="11" fill="#EEE" rx="2"/><rect width="6" height="2" y="12" fill="#B5A7DD" rx="1"/><rect width="6" height="2" y="23" fill="#B5A7DD" rx="1"/></g><g transform="translate(34 93)"><rect width="6" height="2" y="1" fill="#B5A7DD" rx="1"/><rect width="15" height="4" x="15" fill="#FC6D26" rx="2"/><rect width="15" height="4" x="72" fill="#EEE" rx="2"/><rect width="15" height="4" x="39" y="22" fill="#FC6D26" opacity=".5" rx="2"/><rect width="15" height="4" x="53" y="11" fill="#EEE" rx="2"/><rect width="20" height="4" x="48" fill="#FC6D26" rx="2"/><rect width="20" height="4" x="15" y="22" fill="#FC6D26" rx="2"/><rect width="20" height="4" x="29" y="11" fill="#EEE" rx="2"/><rect width="10" height="4" x="34" fill="#FC6D26" opacity=".5" rx="2"/><rect width="10" height="4" x="15" y="11" fill="#EEE" rx="2"/><rect width="6" height="2" y="12" fill="#B5A7DD" rx="1"/><rect width="6" height="2" y="23" fill="#B5A7DD" rx="1"/></g><g transform="translate(34 126)"><rect width="6" height="2" y="1" fill="#B5A7DD" rx="1"/><rect width="15" height="4" x="15" fill="#EEE" rx="2"/><rect width="15" height="4" x="72" fill="#EEE" rx="2"/><rect width="15" height="4" x="39" y="22" fill="#EEE" rx="2"/><rect width="15" height="4" x="53" y="11" fill="#EEE" rx="2"/><rect width="20" height="4" x="48" fill="#FC6D26" rx="2"/><rect width="20" height="4" x="15" y="22" fill="#EEE" rx="2"/><rect width="20" height="4" x="29" y="11" fill="#EEE" rx="2"/><rect width="10" height="4" x="34" fill="#FC6D26" opacity=".5" rx="2"/><rect width="10" height="4" x="15" y="11" fill="#EEE" rx="2"/><rect width="6" height="2" y="12" fill="#B5A7DD" rx="1"/><rect width="6" height="2" y="23" fill="#B5A7DD" rx="1"/></g><g transform="translate(157 59)"><rect width="6" height="2" y="1" fill="#FDE5D8" rx="1"/><rect width="15" height="4" x="15" fill="#EEE" rx="2"/><rect width="15" height="4" x="72" fill="#EEE" rx="2"/><rect width="15" height="4" x="39" y="22" fill="#6B4FBB" opacity=".5" rx="2"/><rect width="15" height="4" x="53" y="11" fill="#6B4FBB" rx="2"/><rect width="20" height="4" x="48" fill="#6B4FBB" opacity=".5" rx="2"/><rect width="20" height="4" x="15" y="22" fill="#6B4FBB" rx="2"/><rect width="20" height="4" x="29" y="11" fill="#EEE" rx="2"/><rect width="10" height="4" x="34" fill="#6B4FBB" rx="2"/><rect width="10" height="4" x="15" y="11" fill="#EEE" rx="2"/><rect width="6" height="2" y="12" fill="#FDE5D8" rx="1"/><rect width="6" height="2" y="23" fill="#FDE5D8" rx="1"/><rect width="6" height="2" y="34" fill="#FDE5D8" rx="1"/><rect width="15" height="4" x="15" y="33" fill="#EEE" rx="2"/><rect width="15" height="4" x="58" y="22" fill="#EEE" rx="2"/><rect width="15" height="4" x="39" y="55" fill="#6B4FBB" opacity=".5" rx="2"/><rect width="15" height="4" x="29" y="44" fill="#6B4FBB" rx="2"/><rect width="20" height="4" x="48" y="33" fill="#6B4FBB" rx="2"/><rect width="20" height="4" x="15" y="55" fill="#EEE" rx="2"/><rect width="10" height="4" x="34" y="33" fill="#EEE" rx="2"/><rect width="10" height="4" x="15" y="44" fill="#EEE" rx="2"/><rect width="10" height="4" x="48" y="44" fill="#EEE" rx="2"/><rect width="10" height="4" x="62" y="44" fill="#EEE" rx="2"/><rect width="10" height="4" x="77" y="22" fill="#EEE" rx="2"/><rect width="6" height="2" y="45" fill="#FDE5D8" rx="1"/><rect width="6" height="2" y="56" fill="#FDE5D8" rx="1"/><rect width="6" height="2" y="67" fill="#FDE5D8" rx="1"/><rect width="15" height="4" x="15" y="66" fill="#6B4FBB" rx="2"/><rect width="15" height="4" x="39" y="88" fill="#EEE" rx="2"/><rect width="15" height="4" x="53" y="77" fill="#6B4FBB" opacity=".5" rx="2"/><rect width="20" height="4" x="15" y="88" fill="#EEE" rx="2"/><rect width="20" height="4" x="29" y="77" fill="#6B4FBB" rx="2"/><rect width="10" height="4" x="34" y="66" fill="#EEE" rx="2"/><rect width="10" height="4" x="72" y="77" fill="#EEE" rx="2"/><rect width="10" height="4" x="15" y="77" fill="#EEE" rx="2"/><rect width="6" height="2" y="78" fill="#FDE5D8" rx="1"/><rect width="6" height="2" y="89" fill="#FDE5D8" rx="1"/></g></g><g transform="translate(1057 221)"><use fill="#FFF" stroke="#FDE5D8" stroke-width="8" mask="url(#e)" xlink:href="#b"/><rect width="29" height="3" x="14" y="14" fill="#FDB692" rx="1.5"/><rect width="39" height="3" x="14" y="23" fill="#FDB692" rx="1.5"/><rect width="29" height="3" x="14" y="32" fill="#FDB692" rx="1.5"/></g><g transform="translate(1046 285)"><circle cx="16" cy="15" r="15" fill="#FFF7F4" stroke="#FC6D26" stroke-width="3"/><path stroke="#FC6D26" stroke-width="2" d="M0 14h1c5 0 9.2-2.7 11.4-6.7M14 1V0"/><path stroke="#FC6D26" stroke-width="2" d="M7.8 3c3 4.3 7.8 7 13.2 7 3.3 0 6.3-1 9-2.7"/><circle cx="10.5" cy="17.5" r="1.5" fill="#FC6D26"/><circle cx="21.5" cy="17.5" r="1.5" fill="#FC6D26"/></g><g transform="translate(825 370)"><circle cx="15" cy="16" r="15" fill="#F4F1FA" stroke="#6B4FBB" stroke-width="3"/><path fill="#6B4FBB" d="M25 7h2.7C25 2.8 20.4 0 15 0 9.6 0 5 2.8 2.3 7H5l2.5-3L10 7l2.5-3L15 7l2.5-3L20 7l2.5-3L25 7z"/><circle cx="9.5" cy="17.5" r="1.5" fill="#6B4FBB"/><circle cx="20.5" cy="17.5" r="1.5" fill="#6B4FBB"/></g><g transform="matrix(-1 0 0 1 840 306)"><use fill="#FFF" stroke="#E2DCF2" stroke-width="8" mask="url(#f)" xlink:href="#c"/><rect width="29" height="3" x="24" y="14" fill="#6B4FBB" opacity=".5" rx="1.5"/><rect width="19" height="3" x="34" y="23" fill="#6B4FBB" opacity=".5" rx="1.5"/><rect width="19" height="3" x="34" y="32" fill="#6B4FBB" opacity=".5" rx="1.5"/></g></g></svg>
diff --git a/changelogs/unreleased/20841-getting-started-better-empty-state-for-merge-requests-view.yml b/changelogs/unreleased/20841-getting-started-better-empty-state-for-merge-requests-view.yml
new file mode 100644
index 00000000000..34909c06df3
--- /dev/null
+++ b/changelogs/unreleased/20841-getting-started-better-empty-state-for-merge-requests-view.yml
@@ -0,0 +1,4 @@
+---
+title: Added merge requests empty state
+merge_request: 7342
+author:
diff --git a/changelogs/unreleased/add-mock-deployment-and-monitoring-service-for-development.yaml b/changelogs/unreleased/add-mock-deployment-and-monitoring-service-for-development.yaml
new file mode 100644
index 00000000000..4c81d21a94b
--- /dev/null
+++ b/changelogs/unreleased/add-mock-deployment-and-monitoring-service-for-development.yaml
@@ -0,0 +1,4 @@
+---
+title: Added mock deployment and monitoring service with environments fixtures
+merge_request:
+author:
diff --git a/changelogs/unreleased/fix-groups-long-url.yml b/changelogs/unreleased/fix-groups-long-url.yml
new file mode 100644
index 00000000000..f0f1296ad40
--- /dev/null
+++ b/changelogs/unreleased/fix-groups-long-url.yml
@@ -0,0 +1,4 @@
+---
+title: Skip groups validation on the client
+merge_request:
+author:
diff --git a/changelogs/unreleased/fix-import-namespace.yml b/changelogs/unreleased/fix-import-namespace.yml
new file mode 100644
index 00000000000..9a2fa5e425f
--- /dev/null
+++ b/changelogs/unreleased/fix-import-namespace.yml
@@ -0,0 +1,4 @@
+---
+title: Create subgroups if they don't exist while importing projects
+merge_request:
+author:
diff --git a/config/dependency_decisions.yml b/config/dependency_decisions.yml
index 072ed8a3864..fdba1f6541e 100644
--- a/config/dependency_decisions.yml
+++ b/config/dependency_decisions.yml
@@ -326,3 +326,21 @@
:why: https://github.com/domenic/opener/blob/1.4.3/LICENSE.txt
:versions: []
:when: 2017-02-21 22:33:41.729629000 Z
+- - :approve
+ - jszip
+ - :who: Phil Hughes
+ :why: https://github.com/Stuk/jszip/blob/master/LICENSE.markdown
+ :versions: []
+ :when: 2017-04-05 10:38:46.275721000 Z
+- - :approve
+ - jszip-utils
+ - :who: Phil Hughes
+ :why: https://github.com/Stuk/jszip-utils/blob/master/LICENSE.markdown
+ :versions: []
+ :when: 2017-04-05 10:39:32.676232000 Z
+- - :approve
+ - pako
+ - :who: Phil Hughes
+ :why: https://github.com/nodeca/pako/blob/master/LICENSE
+ :versions: []
+ :when: 2017-04-05 10:43:45.897720000 Z
diff --git a/config/webpack.config.js b/config/webpack.config.js
index 36c09c14d56..99596ce2197 100644
--- a/config/webpack.config.js
+++ b/config/webpack.config.js
@@ -37,6 +37,7 @@ var config = {
monitoring: './monitoring/monitoring_bundle.js',
network: './network/network_bundle.js',
notebook_viewer: './blob/notebook_viewer.js',
+ sketch_viewer: './blob/sketch_viewer.js',
profile: './profile/profile_bundle.js',
protected_branches: './protected_branches/protected_branches_bundle.js',
snippet: './snippet/snippet_bundle.js',
diff --git a/db/fixtures/development/19_environments.rb b/db/fixtures/development/19_environments.rb
new file mode 100644
index 00000000000..93214b9d3e7
--- /dev/null
+++ b/db/fixtures/development/19_environments.rb
@@ -0,0 +1,70 @@
+require './spec/support/sidekiq'
+
+class Gitlab::Seeder::Environments
+ def initialize(project)
+ @project = project
+ end
+
+ def seed!
+ @project.create_mock_deployment_service!(active: true)
+ @project.create_mock_monitoring_service!(active: true)
+
+ create_master_deployments!('production')
+ create_master_deployments!('staging')
+ create_merge_request_review_deployments!
+ end
+
+ private
+
+ def create_master_deployments!(name)
+ @project.repository.commits('master', limit: 4).map do |commit|
+ create_deployment!(
+ @project,
+ name,
+ 'master',
+ commit.id
+ )
+ end
+ end
+
+ def create_merge_request_review_deployments!
+ @project.merge_requests.sample(4).map do |merge_request|
+ next unless merge_request.diff_head_sha
+
+ create_deployment!(
+ merge_request.source_project,
+ "review/#{merge_request.source_branch}",
+ merge_request.source_branch,
+ merge_request.diff_head_sha
+ )
+ end
+ end
+
+ def create_deployment!(project, name, ref, sha)
+ environment = find_or_create_environment!(project, name)
+ environment.deployments.create!(
+ project: project,
+ ref: ref,
+ sha: sha,
+ tag: false,
+ deployable: find_deployable(project, name)
+ )
+ end
+
+ def find_or_create_environment!(project, name)
+ project.environments.find_or_create_by!(name: name).tap do |environment|
+ environment.update(external_url: "https://google.com/#{name}")
+ end
+ end
+
+ def find_deployable(project, environment)
+ project.builds.where(environment: environment).sample
+ end
+end
+
+Gitlab::Seeder.quiet do
+ Project.all.sample(5).each do |project|
+ project_environments = Gitlab::Seeder::Environments.new(project)
+ project_environments.seed!
+ end
+end
diff --git a/db/fixtures/development/19_nested_groups.rb b/db/fixtures/development/20_nested_groups.rb
index d8dddc3fee9..d8dddc3fee9 100644
--- a/db/fixtures/development/19_nested_groups.rb
+++ b/db/fixtures/development/20_nested_groups.rb
diff --git a/features/dashboard/dashboard.feature b/features/dashboard/dashboard.feature
index b1d5e4a7acb..1af4d46dec9 100644
--- a/features/dashboard/dashboard.feature
+++ b/features/dashboard/dashboard.feature
@@ -63,7 +63,8 @@ Feature: Dashboard
@javascript
Scenario: Visiting Project's merge requests after sorting
- Given I visit dashboard merge requests page
+ Given project "Shop" has a "Bugfix MR" merge request open
+ And I visit dashboard merge requests page
And I sort the list by "Oldest updated"
And I visit project "Shop" merge requests page
Then The list should be sorted by "Oldest updated"
diff --git a/features/project/issues/issues.feature b/features/project/issues/issues.feature
index b2b4fe72220..27fa67c1843 100644
--- a/features/project/issues/issues.feature
+++ b/features/project/issues/issues.feature
@@ -56,14 +56,16 @@ Feature: Project Issues
@javascript
Scenario: Visiting Merge Requests after being sorted the list
- Given I visit project "Shop" issues page
+ Given project "Shop" has a "Bugfix MR" merge request open
+ And I visit project "Shop" issues page
And I sort the list by "Oldest updated"
And I visit project "Shop" merge requests page
Then The list should be sorted by "Oldest updated"
@javascript
Scenario: Visiting Merge Requests from a differente Project after sorting
- Given I visit project "Shop" merge requests page
+ Given project "Shop" has a "Bugfix MR" merge request open
+ And I visit project "Shop" merge requests page
And I sort the list by "Oldest updated"
And I visit dashboard merge requests page
Then The list should be sorted by "Oldest updated"
diff --git a/features/steps/project/fork.rb b/features/steps/project/fork.rb
index 79db9728227..7591e7d5612 100644
--- a/features/steps/project/fork.rb
+++ b/features/steps/project/fork.rb
@@ -42,8 +42,7 @@ class Spinach::Features::ProjectFork < Spinach::FeatureSteps
end
step 'I click link "New merge request"' do
- expect(page).to have_content(/new merge request/i)
- click_link "New Merge Request"
+ page.has_link?('New Merge Request') ? click_link("New Merge Request") : click_link('New merge request')
end
step 'I should see the new merge request page for my namespace' do
diff --git a/features/steps/project/forked_merge_requests.rb b/features/steps/project/forked_merge_requests.rb
index c0827ff8fc7..ef1bb453615 100644
--- a/features/steps/project/forked_merge_requests.rb
+++ b/features/steps/project/forked_merge_requests.rb
@@ -16,7 +16,7 @@ class Spinach::Features::ProjectForkedMergeRequests < Spinach::FeatureSteps
end
step 'I click link "New Merge Request"' do
- click_link "New Merge Request"
+ page.has_link?('New Merge Request') ? click_link("New Merge Request") : click_link('New merge request')
end
step 'I should see merge request "Merge Request On Forked Project"' do
diff --git a/features/steps/project/merge_requests.rb b/features/steps/project/merge_requests.rb
index c9c4f537fad..5510c65265a 100644
--- a/features/steps/project/merge_requests.rb
+++ b/features/steps/project/merge_requests.rb
@@ -14,7 +14,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps
end
step 'I click link "New Merge Request"' do
- click_link "New Merge Request"
+ page.has_link?('New Merge Request') ? click_link("New Merge Request") : click_link('New merge request')
end
step 'I click link "Bug NS-04"' do
diff --git a/features/steps/shared/project.rb b/features/steps/shared/project.rb
index 345a28f27dc..782009a32a7 100644
--- a/features/steps/shared/project.rb
+++ b/features/steps/shared/project.rb
@@ -273,6 +273,10 @@ module SharedProject
@project.update(public_builds: false)
end
+ step 'project "Shop" has a "Bugfix MR" merge request open' do
+ create(:merge_request, title: "Bugfix MR", target_project: project, source_project: project, author: project.users.first)
+ end
+
def user_owns_project(user_name:, project_name:, visibility: :private)
user = user_exists(user_name, username: user_name.gsub(/\s/, '').underscore)
project = Project.find_by(name: project_name)
diff --git a/lib/api/services.rb b/lib/api/services.rb
index 4e0c9cb1f63..6802a99311e 100644
--- a/lib/api/services.rb
+++ b/lib/api/services.rb
@@ -562,8 +562,14 @@ module API
desc: 'URL to the mock service'
}
]
+ services['mock-deployment'] = []
+ services['mock-monitoring'] = []
- service_classes << MockCiService
+ service_classes += [
+ MockCiService,
+ MockDeploymentService,
+ MockMonitoringService,
+ ]
end
trigger_services = {
diff --git a/package.json b/package.json
index 7b6c4556e2c..2c8c4e126cd 100644
--- a/package.json
+++ b/package.json
@@ -27,6 +27,8 @@
"jquery": "^2.2.1",
"jquery-ujs": "^1.2.1",
"js-cookie": "^2.1.3",
+ "jszip": "^3.1.3",
+ "jszip-utils": "^0.0.2",
"mousetrap": "^1.4.6",
"pikaday": "^1.5.1",
"raphael": "^2.2.7",
diff --git a/spec/controllers/import/bitbucket_controller_spec.rb b/spec/controllers/import/bitbucket_controller_spec.rb
index 51f23e4eeb9..010e3180ea4 100644
--- a/spec/controllers/import/bitbucket_controller_spec.rb
+++ b/spec/controllers/import/bitbucket_controller_spec.rb
@@ -200,5 +200,72 @@ describe Import::BitbucketController do
end
end
end
+
+ context 'user has chosen an existing nested namespace and name for the project' do
+ let(:parent_namespace) { create(:namespace, name: 'foo', owner: user) }
+ let(:nested_namespace) { create(:namespace, name: 'bar', parent: parent_namespace, owner: user) }
+ let(:test_name) { 'test_name' }
+
+ it 'takes the selected namespace and name' do
+ expect(Gitlab::BitbucketImport::ProjectCreator).
+ to receive(:new).with(bitbucket_repo, test_name, nested_namespace, user, access_params).
+ and_return(double(execute: true))
+
+ post :create, { target_namespace: nested_namespace.full_path, new_name: test_name, format: :js }
+ end
+ end
+
+ context 'user has chosen a non-existent nested namespaces and name for the project' do
+ let(:test_name) { 'test_name' }
+
+ it 'takes the selected namespace and name' do
+ expect(Gitlab::BitbucketImport::ProjectCreator).
+ to receive(:new).with(bitbucket_repo, test_name, kind_of(Namespace), user, access_params).
+ and_return(double(execute: true))
+
+ post :create, { target_namespace: 'foo/bar', new_name: test_name, format: :js }
+ end
+
+ it 'creates the namespaces' do
+ allow(Gitlab::BitbucketImport::ProjectCreator).
+ to receive(:new).with(bitbucket_repo, test_name, kind_of(Namespace), user, access_params).
+ and_return(double(execute: true))
+
+ expect { post :create, { target_namespace: 'foo/bar', new_name: test_name, format: :js } }
+ .to change { Namespace.count }.by(2)
+ end
+
+ it 'new namespace has the right parent' do
+ allow(Gitlab::BitbucketImport::ProjectCreator).
+ to receive(:new).with(bitbucket_repo, test_name, kind_of(Namespace), user, access_params).
+ and_return(double(execute: true))
+
+ post :create, { target_namespace: 'foo/bar', new_name: test_name, format: :js }
+
+ expect(Namespace.find_by_path_or_name('bar').parent.path).to eq('foo')
+ end
+ end
+
+ context 'user has chosen existent and non-existent nested namespaces and name for the project' do
+ let(:test_name) { 'test_name' }
+ let!(:parent_namespace) { create(:namespace, name: 'foo', owner: user) }
+
+ it 'takes the selected namespace and name' do
+ expect(Gitlab::BitbucketImport::ProjectCreator).
+ to receive(:new).with(bitbucket_repo, test_name, kind_of(Namespace), user, access_params).
+ and_return(double(execute: true))
+
+ post :create, { target_namespace: 'foo/foobar/bar', new_name: test_name, format: :js }
+ end
+
+ it 'creates the namespaces' do
+ allow(Gitlab::BitbucketImport::ProjectCreator).
+ to receive(:new).with(bitbucket_repo, test_name, kind_of(Namespace), user, access_params).
+ and_return(double(execute: true))
+
+ expect { post :create, { target_namespace: 'foo/foobar/bar', new_name: test_name, format: :js } }
+ .to change { Namespace.count }.by(2)
+ end
+ end
end
end
diff --git a/spec/controllers/import/gitlab_controller_spec.rb b/spec/controllers/import/gitlab_controller_spec.rb
index 3f73ea000ae..2dbb89219d0 100644
--- a/spec/controllers/import/gitlab_controller_spec.rb
+++ b/spec/controllers/import/gitlab_controller_spec.rb
@@ -174,6 +174,72 @@ describe Import::GitlabController do
end
end
end
+
+ context 'user has chosen an existing nested namespace for the project' do
+ let(:parent_namespace) { create(:namespace, name: 'foo', owner: user) }
+ let(:nested_namespace) { create(:namespace, name: 'bar', parent: parent_namespace, owner: user) }
+
+ it 'takes the selected namespace and name' do
+ expect(Gitlab::GitlabImport::ProjectCreator).
+ to receive(:new).with(gitlab_repo, nested_namespace, user, access_params).
+ and_return(double(execute: true))
+
+ post :create, { target_namespace: nested_namespace.full_path, format: :js }
+ end
+ end
+
+ context 'user has chosen a non-existent nested namespaces for the project' do
+ let(:test_name) { 'test_name' }
+
+ it 'takes the selected namespace and name' do
+ expect(Gitlab::GitlabImport::ProjectCreator).
+ to receive(:new).with(gitlab_repo, kind_of(Namespace), user, access_params).
+ and_return(double(execute: true))
+
+ post :create, { target_namespace: 'foo/bar', format: :js }
+ end
+
+ it 'creates the namespaces' do
+ allow(Gitlab::GitlabImport::ProjectCreator).
+ to receive(:new).with(gitlab_repo, kind_of(Namespace), user, access_params).
+ and_return(double(execute: true))
+
+ expect { post :create, { target_namespace: 'foo/bar', format: :js } }
+ .to change { Namespace.count }.by(2)
+ end
+
+ it 'new namespace has the right parent' do
+ allow(Gitlab::GitlabImport::ProjectCreator).
+ to receive(:new).with(gitlab_repo, kind_of(Namespace), user, access_params).
+ and_return(double(execute: true))
+
+ post :create, { target_namespace: 'foo/bar', format: :js }
+
+ expect(Namespace.find_by_path_or_name('bar').parent.path).to eq('foo')
+ end
+ end
+
+ context 'user has chosen existent and non-existent nested namespaces and name for the project' do
+ let(:test_name) { 'test_name' }
+ let!(:parent_namespace) { create(:namespace, name: 'foo', owner: user) }
+
+ it 'takes the selected namespace and name' do
+ expect(Gitlab::GitlabImport::ProjectCreator).
+ to receive(:new).with(gitlab_repo, kind_of(Namespace), user, access_params).
+ and_return(double(execute: true))
+
+ post :create, { target_namespace: 'foo/foobar/bar', format: :js }
+ end
+
+ it 'creates the namespaces' do
+ allow(Gitlab::GitlabImport::ProjectCreator).
+ to receive(:new).with(gitlab_repo, kind_of(Namespace), user, access_params).
+ and_return(double(execute: true))
+
+ expect { post :create, { target_namespace: 'foo/foobar/bar', format: :js } }
+ .to change { Namespace.count }.by(2)
+ end
+ end
end
end
end
diff --git a/spec/features/dashboard/merge_requests_spec.rb b/spec/features/dashboard/merge_requests_spec.rb
new file mode 100644
index 00000000000..508ca38d7e5
--- /dev/null
+++ b/spec/features/dashboard/merge_requests_spec.rb
@@ -0,0 +1,32 @@
+require 'spec_helper'
+
+describe 'Dashboard Merge Requests' do
+ let(:current_user) { create :user }
+ let(:project) do
+ create(:empty_project) do |project|
+ project.add_master(current_user)
+ end
+ end
+
+ before do
+ login_as(current_user)
+ end
+
+ it 'should show an empty state' do
+ visit merge_requests_dashboard_path(assignee_id: current_user.id)
+
+ expect(page).to have_selector('.empty-state')
+ end
+
+ context 'if there are merge requests' do
+ before do
+ create(:merge_request, assignee: current_user, source_project: project)
+
+ visit merge_requests_dashboard_path(assignee_id: current_user.id)
+ end
+
+ it 'should not show an empty state' do
+ expect(page).not_to have_selector('.empty-state')
+ end
+ end
+end
diff --git a/spec/features/groups/empty_states_spec.rb b/spec/features/groups/empty_states_spec.rb
new file mode 100644
index 00000000000..fef8e41bffe
--- /dev/null
+++ b/spec/features/groups/empty_states_spec.rb
@@ -0,0 +1,70 @@
+require 'spec_helper'
+
+feature 'Groups Merge Requests Empty States' do
+ let(:group) { create(:group) }
+ let(:user) { create(:group_member, :developer, user: create(:user), group: group ).user }
+
+ before do
+ login_as(user)
+ end
+
+ context 'group has a project' do
+ let(:project) { create(:empty_project, namespace: group) }
+
+ before do
+ project.add_master(user)
+ end
+
+ context 'the project has a merge request' do
+ before do
+ create(:merge_request, source_project: project)
+
+ visit merge_requests_group_path(group)
+ end
+
+ it 'should not display an empty state' do
+ expect(page).not_to have_selector('.empty-state')
+ end
+ end
+
+ context 'the project has no merge requests', :js do
+ before do
+ visit merge_requests_group_path(group)
+ end
+
+ it 'should display an empty state' do
+ expect(page).to have_selector('.empty-state')
+ end
+
+ it 'should show a new merge request button' do
+ within '.empty-state' do
+ expect(page).to have_content('New merge request')
+ end
+ end
+
+ it 'the new merge request button opens a project dropdown' do
+ within '.empty-state' do
+ find('.new-project-item-select-button').click
+ end
+
+ expect(page).to have_selector('.ajax-project-dropdown')
+ end
+ end
+ end
+
+ context 'group without a project' do
+ before do
+ visit merge_requests_group_path(group)
+ end
+
+ it 'should display an empty state' do
+ expect(page).to have_selector('.empty-state')
+ end
+
+ it 'should not show a new merge request button' do
+ within '.empty-state' do
+ expect(page).not_to have_link('New merge request')
+ end
+ end
+ end
+end
diff --git a/spec/features/merge_requests/create_new_mr_spec.rb b/spec/features/merge_requests/create_new_mr_spec.rb
index f1ad4a55246..f36781167fb 100644
--- a/spec/features/merge_requests/create_new_mr_spec.rb
+++ b/spec/features/merge_requests/create_new_mr_spec.rb
@@ -15,7 +15,7 @@ feature 'Create New Merge Request', feature: true, js: true do
it 'selects the source branch sha when a tag with the same name exists' do
visit namespace_project_merge_requests_path(project.namespace, project)
- click_link 'New Merge Request'
+ click_link 'New merge request'
expect(page).to have_content('Source branch')
expect(page).to have_content('Target branch')
@@ -27,8 +27,8 @@ feature 'Create New Merge Request', feature: true, js: true do
it 'selects the target branch sha when a tag with the same name exists' do
visit namespace_project_merge_requests_path(project.namespace, project)
-
- click_link 'New Merge Request'
+
+ click_link 'New merge request'
expect(page).to have_content('Source branch')
expect(page).to have_content('Target branch')
@@ -42,7 +42,7 @@ feature 'Create New Merge Request', feature: true, js: true do
it 'generates a diff for an orphaned branch' do
visit namespace_project_merge_requests_path(project.namespace, project)
- click_link 'New Merge Request'
+ page.has_link?('New Merge Request') ? click_link("New Merge Request") : click_link('New merge request')
expect(page).to have_content('Source branch')
expect(page).to have_content('Target branch')
diff --git a/spec/features/projects/merge_requests/list_spec.rb b/spec/features/projects/merge_requests/list_spec.rb
index 5dd58ad66a7..7e8a796c55d 100644
--- a/spec/features/projects/merge_requests/list_spec.rb
+++ b/spec/features/projects/merge_requests/list_spec.rb
@@ -17,4 +17,28 @@ feature 'Merge Requests List' do
expect(page).not_to have_selector('.js-new-board-list')
end
+
+ it 'should show an empty state' do
+ visit namespace_project_merge_requests_path(project.namespace, project)
+
+ expect(page).to have_selector('.empty-state')
+ end
+
+ it 'empty state should have a create merge request button' do
+ visit namespace_project_merge_requests_path(project.namespace, project)
+
+ expect(page).to have_link 'New merge request', href: new_namespace_project_merge_request_path(project.namespace, project)
+ end
+
+ context 'if there are merge requests' do
+ before do
+ create(:merge_request, assignee: user, source_project: project)
+
+ visit namespace_project_merge_requests_path(project.namespace, project)
+ end
+
+ it 'should not show an empty state' do
+ expect(page).not_to have_selector('.empty-state')
+ end
+ end
end
diff --git a/spec/features/search_spec.rb b/spec/features/search_spec.rb
index 40ef4c098b9..e8ad28a00f0 100644
--- a/spec/features/search_spec.rb
+++ b/spec/features/search_spec.rb
@@ -164,6 +164,8 @@ describe "Search", feature: true do
end
context 'click the links in the category search dropdown', js: true do
+ let!(:merge_request) { create(:merge_request, source_project: project, author: user, assignee: user) }
+
before do
page.find('#search').click
end
diff --git a/spec/fixtures/metrics.json b/spec/fixtures/metrics.json
new file mode 100644
index 00000000000..06427adce57
--- /dev/null
+++ b/spec/fixtures/metrics.json
@@ -0,0 +1 @@
+{"success":true,"metrics":{"memory_values":[{"metric":{},"values":[[1490935421.33,"9.832775297619047"],[1490935481.33,"9.8359375"],[1490935541.33,"9.837983630952381"],[1490935601.33,"9.840401785714286"],[1490935661.33,"9.84375"],[1490935721.33,"9.846168154761905"],[1490935781.33,"9.849516369047619"],[1490935841.33,"9.85249255952381"],[1490935901.33,"9.855096726190476"],[1490935961.33,"9.845796130952381"],[1490936021.33,"9.847284226190476"],[1490936081.33,"9.84468005952381"],[1490936141.33,"9.847470238095237"],[1490936201.33,"9.850818452380953"],[1490936261.33,"9.852864583333334"],[1490936321.33,"9.854910714285714"],[1490936381.33,"9.857700892857142"],[1490936441.33,"9.865513392857142"],[1490936501.33,"9.874813988095237"],[1490936561.33,"9.866071428571429"],[1490936621.33,"9.849330357142858"],[1490936681.33,"9.841331845238095"],[1490936741.33,"9.853236607142858"],[1490936801.33,"9.839657738095237"],[1490936861.33,"9.841517857142858"],[1490936921.33,"9.852864583333334"],[1490936981.33,"9.851376488095237"],[1490937041.33,"9.837611607142858"],[1490937101.33,"9.840401785714286"],[1490937161.33,"9.843377976190476"],[1490937221.33,"9.845796130952381"],[1490937281.33,"9.84858630952381"],[1490937341.33,"9.866071428571429"],[1490937401.33,"9.852864583333334"],[1490937461.33,"9.855840773809524"],[1490937521.33,"9.837797619047619"],[1490937581.33,"9.840959821428571"],[1490937641.33,"9.848958333333334"],[1490937701.33,"9.844308035714286"],[1490937761.33,"9.845982142857142"],[1490937821.33,"9.83984375"],[1490937881.33,"9.830171130952381"],[1490937941.33,"9.83686755952381"],[1490938001.33,"9.834263392857142"],[1490938061.33,"9.836309523809524"],[1490938121.33,"9.83984375"],[1490938181.33,"9.832775297619047"],[1490938241.33,"9.818266369047619"],[1490938301.33,"9.820126488095237"],[1490938361.33,"9.824032738095237"],[1490938421.33,"9.826078869047619"],[1490938481.33,"9.817708333333334"],[1490938541.33,"9.811755952380953"],[1490938601.33,"9.811197916666666"],[1490938661.33,"9.81156994047619"],[1490938721.33,"9.812313988095237"],[1490938781.33,"9.813058035714286"],[1490938841.33,"9.81343005952381"],[1490938901.33,"9.81547619047619"],[1490938961.33,"9.818824404761905"],[1490939021.33,"9.819754464285714"],[1490939081.33,"9.820684523809524"],[1490939141.33,"9.824776785714286"],[1490939201.33,"9.826078869047619"],[1490939261.33,"9.828311011904763"],[1490939321.33,"9.820870535714286"],[1490939381.33,"9.823846726190476"],[1490939441.33,"9.824404761904763"],[1490939501.33,"9.82905505952381"],[1490939561.33,"9.832775297619047"],[1490939621.33,"9.835565476190476"],[1490939681.33,"9.833333333333334"],[1490939741.33,"9.835379464285714"],[1490939801.33,"9.837239583333334"],[1490939861.33,"9.839285714285714"],[1490939921.33,"9.829613095238095"],[1490939981.33,"9.832403273809524"],[1490940041.33,"9.835751488095237"],[1490940101.33,"9.837797619047619"],[1490940161.33,"9.840959821428571"],[1490940221.33,"9.84375"],[1490940281.33,"9.846354166666666"],[1490940341.33,"9.853980654761905"],[1490940401.33,"9.852678571428571"],[1490940461.33,"9.861979166666666"],[1490940521.33,"9.857700892857142"],[1490940581.33,"9.861793154761905"],[1490940641.33,"9.86421130952381"],[1490940701.33,"9.867001488095237"],[1490940761.33,"9.867931547619047"],[1490940821.33,"9.859933035714286"],[1490940881.33,"9.86235119047619"],[1490940941.33,"9.865141369047619"],[1490941001.33,"9.866443452380953"],[1490941061.33,"9.868861607142858"],[1490941121.33,"9.871465773809524"],[1490941181.33,"9.873511904761905"],[1490941241.33,"9.875558035714286"],[1490941301.33,"9.87797619047619"],[1490941361.33,"9.881324404761905"],[1490941421.33,"9.888392857142858"],[1490941481.33,"9.888392857142858"],[1490941541.33,"9.89546130952381"],[1490941601.33,"9.898065476190476"],[1490941661.33,"9.885044642857142"],[1490941721.33,"9.872395833333334"],[1490941781.33,"9.870349702380953"],[1490941841.33,"9.873325892857142"],[1490941901.33,"9.875558035714286"],[1490941961.33,"9.878534226190476"],[1490942021.33,"9.87983630952381"],[1490942081.33,"9.884300595238095"],[1490942141.33,"9.891927083333334"],[1490942201.33,"9.890252976190476"],[1490942261.33,"9.891927083333334"],[1490942321.33,"9.893787202380953"],[1490942381.33,"9.892113095238095"],[1490942441.33,"9.900111607142858"],[1490942501.33,"9.893415178571429"],[1490942561.33,"9.895647321428571"],[1490942621.33,"9.889322916666666"],[1490942681.33,"9.883556547619047"],[1490942741.33,"9.885602678571429"],[1490942801.33,"9.88764880952381"],[1490942861.33,"9.898623511904763"],[1490942921.33,"9.89453125"],[1490942981.33,"9.885044642857142"],[1490943041.33,"9.874813988095237"],[1490943101.33,"9.880766369047619"],[1490943161.33,"9.868675595238095"],[1490943221.33,"9.864769345238095"],[1490943281.33,"9.852864583333334"],[1490943341.33,"9.855096726190476"],[1490943401.33,"9.857514880952381"],[1490943461.33,"9.859747023809524"],[1490943521.33,"9.861793154761905"],[1490943581.33,"9.864025297619047"],[1490943641.33,"9.857514880952381"],[1490943701.33,"9.859002976190476"],[1490943761.33,"9.860677083333334"],[1490943821.33,"9.864025297619047"],[1490943881.33,"9.86625744047619"],[1490943941.33,"9.873325892857142"],[1490944001.33,"9.876674107142858"],[1490944061.33,"9.888950892857142"],[1490944121.33,"9.878534226190476"],[1490944181.33,"9.880766369047619"],[1490944241.33,"9.884858630952381"],[1490944301.33,"9.870535714285714"],[1490944361.33,"9.864769345238095"],[1490944421.33,"9.851190476190476"],[1490944481.33,"9.85249255952381"],[1490944541.33,"9.85844494047619"],[1490944601.33,"9.855840773809524"],[1490944661.33,"9.868303571428571"],[1490944721.33,"9.859188988095237"],[1490944781.33,"9.860491071428571"],[1490944841.33,"9.863467261904763"],[1490944901.33,"9.864025297619047"],[1490944961.33,"9.857514880952381"],[1490945021.33,"9.843377976190476"],[1490945081.33,"9.836123511904763"],[1490945141.33,"9.837983630952381"],[1490945201.33,"9.84077380952381"],[1490945261.33,"9.847284226190476"],[1490945321.33,"9.849702380952381"],[1490945381.33,"9.827380952380953"],[1490945441.33,"9.82124255952381"],[1490945501.33,"9.822916666666666"],[1490945561.33,"9.824962797619047"],[1490945621.33,"9.814546130952381"],[1490945681.33,"9.805989583333334"],[1490945741.33,"9.791294642857142"],[1490945801.33,"9.786458333333334"],[1490945861.33,"9.77641369047619"],[1490945921.33,"9.76655505952381"],[1490945981.33,"9.76953125"],[1490946041.33,"9.742745535714286"],[1490946101.33,"9.753162202380953"],[1490946161.33,"9.739583333333334"],[1490946221.33,"9.742931547619047"],[1490946281.33,"9.743489583333334"],[1490946341.33,"9.746837797619047"],[1490946401.33,"9.749255952380953"],[1490946461.33,"9.737165178571429"],[1490946521.33,"9.739583333333334"],[1490946581.33,"9.74311755952381"],[1490946641.33,"9.751302083333334"],[1490946701.33,"9.761346726190476"],[1490946761.33,"9.747953869047619"],[1490946821.33,"9.75093005952381"],[1490946881.33,"9.755580357142858"],[1490946941.33,"9.759858630952381"],[1490947001.33,"9.761904761904763"],[1490947061.33,"9.77641369047619"],[1490947121.33,"9.768787202380953"],[1490947181.33,"9.772879464285714"],[1490947241.33,"9.777715773809524"],[1490947301.33,"9.779947916666666"],[1490947361.33,"9.772135416666666"],[1490947421.33,"9.77641369047619"],[1490947481.33,"9.783668154761905"],[1490947541.33,"9.780505952380953"],[1490947601.33,"9.777157738095237"],[1490947661.33,"9.759114583333334"],[1490947721.33,"9.761532738095237"],[1490947781.33,"9.763392857142858"],[1490947841.33,"9.765252976190476"],[1490947901.33,"9.760602678571429"],[1490947961.33,"9.751488095238095"],[1490948021.33,"9.757998511904763"],[1490948081.33,"9.759486607142858"],[1490948141.33,"9.754650297619047"],[1490948201.33,"9.728050595238095"],[1490948261.33,"9.73530505952381"],[1490948321.33,"9.718005952380953"],[1490948381.33,"9.732142857142858"],[1490948441.33,"9.725260416666666"],[1490948501.33,"9.728422619047619"],[1490948561.33,"9.72953869047619"],[1490948621.33,"9.733072916666666"],[1490948681.33,"9.736421130952381"],[1490948741.33,"9.749627976190476"],[1490948801.33,"9.740141369047619"],[1490948861.33,"9.74311755952381"],[1490948921.33,"9.736607142857142"],[1490948981.33,"9.744233630952381"],[1490949041.33,"9.723772321428571"],[1490949101.33,"9.731956845238095"],[1490949161.33,"9.732514880952381"],[1490949221.33,"9.734747023809524"],[1490949281.33,"9.737723214285714"],[1490949341.33,"9.737909226190476"],[1490949401.33,"9.742373511904763"],[1490949461.33,"9.744977678571429"],[1490949521.33,"9.748139880952381"],[1490949581.33,"9.751302083333334"],[1490949641.33,"9.757440476190476"],[1490949701.33,"9.756324404761905"],[1490949761.33,"9.749813988095237"],[1490949821.33,"9.739025297619047"],[1490949881.33,"9.726004464285714"],[1490949941.33,"9.728236607142858"],[1490950001.33,"9.732514880952381"],[1490950061.33,"9.735119047619047"],[1490950121.33,"9.737165178571429"],[1490950181.33,"9.739025297619047"],[1490950241.33,"9.740513392857142"],[1490950301.33,"9.749441964285714"],[1490950361.33,"9.736979166666666"],[1490950421.33,"9.741629464285714"],[1490950481.33,"9.743303571428571"],[1490950541.33,"9.74609375"],[1490950601.33,"9.75093005952381"],[1490950661.33,"9.724330357142858"],[1490950721.33,"9.726748511904763"],[1490950781.33,"9.733258928571429"],[1490950841.33,"9.744233630952381"],[1490950901.33,"9.734375"],[1490950961.33,"9.737537202380953"],[1490951021.33,"9.741071428571429"],[1490951081.33,"9.757254464285714"],[1490951141.33,"9.760044642857142"],[1490951201.33,"9.755952380952381"],[1490951261.33,"9.745349702380953"],[1490951321.33,"9.746651785714286"],[1490951381.33,"9.749441964285714"],[1490951441.33,"9.751674107142858"],[1490951501.33,"9.757998511904763"],[1490951561.33,"9.756510416666666"],[1490951621.33,"9.76264880952381"],[1490951681.33,"9.765625"],[1490951741.33,"9.757254464285714"],[1490951801.33,"9.751674107142858"],[1490951861.33,"9.754278273809524"],[1490951921.33,"9.744233630952381"],[1490951981.33,"9.745349702380953"],[1490952041.33,"9.748883928571429"],[1490952101.33,"9.753162202380953"],[1490952161.33,"9.747953869047619"],[1490952221.33,"9.750186011904763"],[1490952281.33,"9.751116071428571"],[1490952341.33,"9.753162202380953"],[1490952401.33,"9.758928571428571"],[1490952461.33,"9.758928571428571"],[1490952521.33,"9.755394345238095"],[1490952581.33,"9.758928571428571"],[1490952641.33,"9.761160714285714"],[1490952701.33,"9.763206845238095"],[1490952761.33,"9.767857142857142"],[1490952821.33,"9.765438988095237"],[1490952881.33,"9.768229166666666"],[1490952941.33,"9.780877976190476"],[1490953001.33,"9.77250744047619"],[1490953061.33,"9.784412202380953"],[1490953121.33,"9.77827380952381"],[1490953181.33,"9.781063988095237"],[1490953241.33,"9.783668154761905"],[1490953301.33,"9.787016369047619"],[1490953361.33,"9.784970238095237"],[1490953421.33,"9.787946428571429"],[1490953481.33,"9.788690476190476"],[1490953541.33,"9.790922619047619"],[1490953601.33,"9.792596726190476"],[1490953661.33,"9.79594494047619"],[1490953721.33,"9.79780505952381"],[1490953781.33,"9.800223214285714"],[1490953841.33,"9.794828869047619"],[1490953901.33,"9.799293154761905"],[1490953961.33,"9.801525297619047"],[1490954021.33,"9.786458333333334"],[1490954081.33,"9.773809523809524"],[1490954141.33,"9.767485119047619"],[1490954201.33,"9.760044642857142"],[1490954261.33,"9.751116071428571"],[1490954321.33,"9.752790178571429"],[1490954381.33,"9.753162202380953"],[1490954441.33,"9.744419642857142"],[1490954501.33,"9.73921130952381"],[1490954561.33,"9.74125744047619"],[1490954621.33,"9.743303571428571"],[1490954681.33,"9.745535714285714"],[1490954741.33,"9.746837797619047"],[1490954801.33,"9.749255952380953"],[1490954861.33,"9.744419642857142"],[1490954921.33,"9.745349702380953"],[1490954981.33,"9.74702380952381"],[1490955041.33,"9.738467261904763"],[1490955101.33,"9.740141369047619"],[1490955161.33,"9.747767857142858"],[1490955221.33,"9.750372023809524"],[1490955281.33,"9.747767857142858"],[1490955341.33,"9.739025297619047"],[1490955401.33,"9.745349702380953"],[1490955461.33,"9.730282738095237"],[1490955521.33,"9.73139880952381"],[1490955581.33,"9.722842261904763"],[1490955641.33,"9.725818452380953"],[1490955701.33,"9.72749255952381"],[1490955761.33,"9.72953869047619"],[1490955821.33,"9.731956845238095"],[1490955881.33,"9.735677083333334"],[1490955941.33,"9.738467261904763"],[1490956001.33,"9.735863095238095"],[1490956061.33,"9.743675595238095"],[1490956121.33,"9.730840773809524"],[1490956181.33,"9.734747023809524"],[1490956241.33,"9.736235119047619"],[1490956301.33,"9.736607142857142"],[1490956361.33,"9.73921130952381"],[1490956421.33,"9.742001488095237"],[1490956481.33,"9.743675595238095"],[1490956541.33,"9.744977678571429"],[1490956601.33,"9.748697916666666"],[1490956661.33,"9.760602678571429"],[1490956721.33,"9.751302083333334"],[1490956781.33,"9.754278273809524"],[1490956841.33,"9.756324404761905"],[1490956901.33,"9.758370535714286"],[1490956961.33,"9.760416666666666"],[1490957021.33,"9.763020833333334"],[1490957081.33,"9.766183035714286"],[1490957141.33,"9.764508928571429"],[1490957201.33,"9.767299107142858"],[1490957261.33,"9.768787202380953"],[1490957321.33,"9.771019345238095"],[1490957381.33,"9.773623511904763"],[1490957441.33,"9.775111607142858"],[1490957501.33,"9.779389880952381"],[1490957561.33,"9.780691964285714"],[1490957621.33,"9.788690476190476"],[1490957681.33,"9.794828869047619"],[1490957741.33,"9.779203869047619"],[1490957801.33,"9.787016369047619"],[1490957861.33,"9.783854166666666"],[1490957921.33,"9.78515625"],[1490957981.33,"9.786644345238095"],[1490958041.33,"9.787946428571429"],[1490958101.33,"9.800409226190476"],[1490958161.33,"9.787202380952381"],[1490958221.33,"9.789806547619047"],[1490958281.33,"9.791852678571429"],[1490958341.33,"9.788876488095237"],[1490958401.33,"9.78515625"],[1490958461.33,"9.7890625"],[1490958521.33,"9.791108630952381"],[1490958581.33,"9.792596726190476"],[1490958641.33,"9.794828869047619"],[1490958701.33,"9.793154761904763"],[1490958761.33,"9.799293154761905"],[1490958821.33,"9.797247023809524"],[1490958881.33,"9.794084821428571"],[1490958941.33,"9.796875"],[1490959001.33,"9.763950892857142"],[1490959061.33,"9.765997023809524"],[1490959121.33,"9.767671130952381"],[1490959181.33,"9.77046130952381"],[1490959241.33,"9.773809523809524"],[1490959301.33,"9.765252976190476"],[1490959361.33,"9.767485119047619"],[1490959421.33,"9.76953125"],[1490959481.33,"9.774553571428571"],[1490959541.33,"9.77734375"],[1490959601.33,"9.778459821428571"],[1490959661.33,"9.780877976190476"],[1490959721.33,"9.783296130952381"],[1490959781.33,"9.794828869047619"],[1490959841.33,"9.787016369047619"],[1490959901.33,"9.798735119047619"],[1490959961.33,"9.803013392857142"],[1490960021.33,"9.801525297619047"],[1490960081.33,"9.804873511904763"],[1490960141.33,"9.80078125"],[1490960201.33,"9.80375744047619"],[1490960261.33,"9.805059523809524"],[1490960321.33,"9.807849702380953"],[1490960381.33,"9.810825892857142"],[1490960441.33,"9.813058035714286"],[1490960501.33,"9.813616071428571"],[1490960561.33,"9.815104166666666"],[1490960621.33,"9.81733630952381"],[1490960681.33,"9.812872023809524"],[1490960741.33,"9.814546130952381"],[1490960801.33,"9.808035714285714"],[1490960861.33,"9.810081845238095"],[1490960921.33,"9.813058035714286"],[1490960981.33,"9.825892857142858"],[1490961041.33,"9.816964285714286"],[1490961101.33,"9.82421875"],[1490961161.33,"9.80952380952381"],[1490961221.33,"9.804315476190476"],[1490961281.33,"9.797619047619047"],[1490961341.33,"9.80078125"],[1490961401.33,"9.802827380952381"],[1490961461.33,"9.803199404761905"],[1490961521.33,"9.80952380952381"],[1490961581.33,"9.806919642857142"],[1490961641.33,"9.808779761904763"],[1490961701.33,"9.811197916666666"],[1490961761.33,"9.813244047619047"],[1490961821.33,"9.815662202380953"],[1490961881.33,"9.819940476190476"],[1490961941.33,"9.822172619047619"],[1490962001.33,"9.82328869047619"],[1490962061.33,"9.826822916666666"],[1490962121.33,"9.829241071428571"],[1490962181.33,"9.832589285714286"],[1490962241.33,"9.835565476190476"],[1490962301.33,"9.839471726190476"],[1490962361.33,"9.825520833333334"],[1490962421.33,"9.829427083333334"],[1490962481.33,"9.832217261904763"],[1490962541.33,"9.839285714285714"],[1490962601.33,"9.837611607142858"],[1490962661.33,"9.841145833333334"],[1490962721.33,"9.834077380952381"],[1490962781.33,"9.837239583333334"],[1490962841.33,"9.841703869047619"],[1490962901.33,"9.844308035714286"],[1490962961.33,"9.838727678571429"],[1490963021.33,"9.840587797619047"],[1490963081.33,"9.849516369047619"],[1490963141.33,"9.845238095238095"],[1490963201.33,"9.84375"],[1490963261.33,"9.838541666666666"],[1490963321.33,"9.841889880952381"],[1490963381.33,"9.846354166666666"],[1490963441.33,"9.832403273809524"],[1490963501.33,"9.833891369047619"],[1490963561.33,"9.808221726190476"],[1490963621.33,"9.812686011904763"],[1490963681.33,"9.814918154761905"],[1490963741.33,"9.817708333333334"],[1490963801.33,"9.80561755952381"],[1490963861.33,"9.80859375"],[1490963921.33,"9.811197916666666"],[1490963981.33,"9.802269345238095"],[1490964041.33,"9.798177083333334"],[1490964101.33,"9.80078125"],[1490964161.33,"9.815104166666666"],[1490964221.33,"9.806361607142858"]]}],"memory_current":[{"metric":{},"value":[1490964221.593,"9.806361607142858"]}],"cpu_values":[{"metric":{},"values":[[1490935421.446,"0.011520035833333402"],[1490935481.446,"0.010738020634921052"],[1490935541.446,"0.011830812658730162"],[1490935601.446,"0.011666519206349292"],[1490935661.446,"0.012397734365079505"],[1490935721.446,"0.012264678253967905"],[1490935781.446,"0.011701125396825458"],[1490935841.446,"0.011413869087301435"],[1490935901.446,"0.011355704404762157"],[1490935961.446,"0.01295611777777756"],[1490936021.446,"0.012283088253968812"],[1490936081.446,"0.011711742103174674"],[1490936141.446,"0.011066851150792879"],[1490936201.446,"0.011525933611111726"],[1490936261.446,"0.012260294246031015"],[1490936321.446,"0.011917795238095285"],[1490936381.446,"0.011402582301587626"],[1490936441.446,"0.012311798253968057"],[1490936501.446,"0.011604295476191046"],[1490936561.446,"0.012329014206349137"],[1490936621.446,"0.011401263769840977"],[1490936681.446,"0.012310593492063392"],[1490936741.446,"0.01244334305555575"],[1490936801.446,"0.01176146669320973"],[1490936861.446,"0.011186474629011792"],[1490936921.446,"0.013234800079365536"],[1490936981.446,"0.01217435722222217"],[1490937041.446,"0.011211570753967583"],[1490937101.446,"0.012066252420634934"],[1490937161.446,"0.012175381944444839"],[1490937221.446,"0.011215347936507976"],[1490937281.446,"0.012909065515873003"],[1490937341.446,"0.011718783452381023"],[1490937401.446,"0.011740557499999828"],[1490937461.446,"0.012024899960317205"],[1490937521.446,"0.011518551626984471"],[1490937581.446,"0.013295429607829826"],[1490937641.446,"0.013578758822130006"],[1490937701.446,"0.01170811908668783"],[1490937761.446,"0.011867610238095478"],[1490937821.446,"0.012601599007937034"],[1490937881.446,"0.011028959285714405"],[1490937941.446,"0.011972864523808899"],[1490938001.446,"0.012236090515873134"],[1490938061.446,"0.012468855793650629"],[1490938121.446,"0.012324049999999686"],[1490938181.446,"0.012271810317460288"],[1490938241.446,"0.013109732103174912"],[1490938301.446,"0.01201708535714284"],[1490938361.446,"0.01198280035714318"],[1490938421.446,"0.011631491547618469"],[1490938481.446,"0.012698120317460778"],[1490938541.446,"0.011908042499999686"],[1490938601.446,"0.012941332460317123"],[1490938661.446,"0.012009558055555753"],[1490938721.446,"0.011749238293651211"],[1490938781.446,"0.012597720873015857"],[1490938841.446,"0.012128174365079517"],[1490938901.446,"0.013411003452380428"],[1490938961.446,"0.012712377896825132"],[1490939021.446,"0.0126730261111118"],[1490939081.446,"0.012196438134920173"],[1490939141.446,"0.011617917341270696"],[1490939201.446,"0.012271590992062863"],[1490939261.446,"0.01196238253968261"],[1490939321.446,"0.012446522619048245"],[1490939381.446,"0.013146698134919643"],[1490939441.446,"0.013160663611111774"],[1490939501.446,"0.012921960039682278"],[1490939561.446,"0.012100972380952405"],[1490939621.446,"0.01235039095238153"],[1490939681.446,"0.013303590992062684"],[1490939741.446,"0.012064513055556225"],[1490939801.446,"0.011846763531745252"],[1490939861.446,"0.012280224007936782"],[1490939921.446,"0.012305159166666833"],[1490939981.446,"0.012107076111110887"],[1490940041.446,"0.013109447341269884"],[1490940101.446,"0.011668830198412932"],[1490940161.446,"0.011757771468254286"],[1490940221.446,"0.013607426447330252"],[1490940281.446,"0.012069082212503184"],[1490940341.446,"0.012702448174603309"],[1490940401.446,"0.012915864642857006"],[1490940461.446,"0.012882558941478554"],[1490940521.446,"0.01180430288917485"],[1490940581.446,"0.012561457142856586"],[1490940641.446,"0.013117287261905215"],[1490940701.446,"0.0119707260317455"],[1490940761.446,"0.012110876587301957"],[1490940821.446,"0.012900523174603096"],[1490940881.446,"0.012405300317460836"],[1490940941.446,"0.013397718690476127"],[1490941001.446,"0.011853019404761512"],[1490941061.446,"0.011410178968254279"],[1490941121.446,"0.01385021210317412"],[1490941181.446,"0.012158262658730703"],[1490941241.446,"0.012590782142857021"],[1490941301.446,"0.011902994444444289"],[1490941361.446,"0.012597971468253468"],[1490941421.446,"0.013460530436508394"],[1490941481.446,"0.012871132936507318"],[1490941541.446,"0.012321937023810644"],[1490941601.446,"0.012861435992063004"],[1490941661.446,"0.011904687658730493"],[1490941721.446,"0.013068603849206292"],[1490941781.446,"0.011558027420635053"],[1490941841.446,"0.011785108134920095"],[1490941901.446,"0.013018491984126938"],[1490941961.446,"0.012803318611111494"],[1490942021.446,"0.011276595873015969"],[1490942081.446,"0.012407365753968128"],[1490942141.446,"0.01261537746031769"],[1490942201.446,"0.011981626507936492"],[1490942261.446,"0.011779192579364465"],[1490942321.446,"0.012944439365080001"],[1490942381.446,"0.012563845515873258"],[1490942441.446,"0.012490993809523204"],[1490942501.446,"0.011721826547619399"],[1490942561.446,"0.012376904523809195"],[1490942621.446,"0.012627997539682608"],[1490942681.446,"0.012353236984126971"],[1490942741.446,"0.012143749162511788"],[1490942801.446,"0.01210106380777602"],[1490942861.446,"0.01323092650793727"],[1490942921.446,"0.01217811805555557"],[1490942981.446,"0.011703709655399819"],[1490943041.446,"0.01140056596399108"],[1490943101.446,"0.011589462460317477"],[1490943161.446,"0.011424534784915178"],[1490943221.446,"0.011720420858480131"],[1490943281.446,"0.011956359603174035"],[1490943341.446,"0.011627974444444375"],[1490943401.446,"0.012056417142857899"],[1490943461.446,"0.012875421865079256"],[1490943521.446,"0.011447757222222438"],[1490943581.446,"0.011686728412698438"],[1490943641.446,"0.012264428214285543"],[1490943701.446,"0.011396086150793258"],[1490943761.446,"0.012637377857143453"],[1490943821.446,"0.012229487817460189"],[1490943881.446,"0.012519327516820155"],[1490943941.446,"0.011632154440677021"],[1490944001.446,"0.0127011905614214"],[1490944061.446,"0.012041664776432408"],[1490944121.446,"0.011550796183789442"],[1490944181.446,"0.012340807579364546"],[1490944241.446,"0.012514561706348858"],[1490944301.446,"0.011591095515873378"],[1490944361.446,"0.011562522896825472"],[1490944421.446,"0.012653687499999684"],[1490944481.446,"0.012597878095237767"],[1490944541.446,"0.011373836746032411"],[1490944601.446,"0.011489111309523512"],[1490944661.446,"0.012365606547618906"],[1490944721.446,"0.011246835793650788"],[1490944781.446,"0.011556645833333596"],[1490944841.446,"0.0114839880952384"],[1490944901.446,"0.011559932103174322"],[1490944961.446,"0.011456621547618827"],[1490945021.446,"0.011137903531746323"],[1490945081.446,"0.011371503134920238"],[1490945141.446,"0.01262392527777806"],[1490945201.446,"0.011231213571428417"],[1490945261.446,"0.011834045595238011"],[1490945321.446,"0.011222574087301793"],[1490945381.446,"0.01139294579365124"],[1490945441.446,"0.011876671865079205"],[1490945501.446,"0.012003088888888104"],[1490945561.446,"0.011232171746032069"],[1490945621.446,"0.01189458067460394"],[1490945681.446,"0.011593709801586787"],[1490945741.446,"0.01179023611111146"],[1490945801.446,"0.012056340952381187"],[1490945861.446,"0.011755026706348978"],[1490945921.446,"0.011906753412698057"],[1490945981.446,"0.011362850850868408"],[1490946041.446,"0.011567284784873766"],[1490946101.446,"0.01159940924603172"],[1490946161.446,"0.01169248444646143"],[1490946221.446,"0.011294826570231075"],[1490946281.446,"0.011797972936507535"],[1490946341.446,"0.011732454126984091"],[1490946401.446,"0.011992103412699077"],[1490946461.446,"0.011787900634920185"],[1490946521.446,"0.01170581265873045"],[1490946581.446,"0.011391009603175007"],[1490946641.446,"0.01205839841269773"],[1490946701.446,"0.01188169805555573"],[1490946761.446,"0.011459351746031153"],[1490946821.446,"0.012089251071429255"],[1490946881.446,"0.011159798611111122"],[1490946941.446,"0.012261993650793439"],[1490947001.446,"0.011150941865079526"],[1490947061.446,"0.011784560238095428"],[1490947121.446,"0.01146369333333352"],[1490947181.446,"0.011946112341269969"],[1490947241.446,"0.012244168452380742"],[1490947301.446,"0.01108276087301507"],[1490947361.446,"0.011391418571428976"],[1490947421.446,"0.012042411525379642"],[1490947481.446,"0.012082919141039653"],[1490947541.446,"0.011615924682540189"],[1490947601.446,"0.01218819496031727"],[1490947661.446,"0.011292488293650517"],[1490947721.446,"0.011232974365079479"],[1490947781.446,"0.011638264880952223"],[1490947841.446,"0.0115353722619047"],[1490947901.446,"0.011426710952381045"],[1490947961.446,"0.0121381246428574"],[1490948021.446,"0.011812514087301832"],[1490948081.446,"0.012050580317459442"],[1490948141.446,"0.011855329166666742"],[1490948201.446,"0.011649919960317898"],[1490948261.446,"0.01163187396825391"],[1490948321.446,"0.011266725634920935"],[1490948381.446,"0.011934722460317146"],[1490948441.446,"0.011368148333333088"],[1490948501.446,"0.011662377698413048"],[1490948561.446,"0.011039417341269188"],[1490948621.446,"0.012176113174603589"],[1490948681.446,"0.011265313531746158"],[1490948741.446,"0.01158711781746033"],[1490948801.446,"0.011557390912698215"],[1490948861.446,"0.012131684804188454"],[1490948921.446,"0.011474324082027133"],[1490948981.446,"0.011376334484127639"],[1490949041.446,"0.011627233571428175"],[1490949101.446,"0.012499916785714077"],[1490949161.446,"0.011920621706348947"],[1490949221.446,"0.011574053410790661"],[1490949281.446,"0.011837460242165967"],[1490949341.446,"0.011227153174603937"],[1490949401.446,"0.011635896944444115"],[1490949461.446,"0.011701339047618983"],[1490949521.446,"0.011847283650793895"],[1490949581.446,"0.0116057894841271"],[1490949641.446,"0.011789695753968094"],[1490949701.446,"0.011279284841269992"],[1490949761.446,"0.011470807460317041"],[1490949821.446,"0.012172255515873568"],[1490949881.446,"0.011721892103174175"],[1490949941.446,"0.010727560317460336"],[1490950001.446,"0.011509186269841303"],[1490950061.446,"0.01188623087301566"],[1490950121.446,"0.011476948452380968"],[1490950181.446,"0.01211593166666722"],[1490950241.446,"0.011757469444444444"],[1490950301.446,"0.011519936865079109"],[1490950361.446,"0.01165834781746044"],[1490950421.446,"0.010831068928571068"],[1490950481.446,"0.011977692023809912"],[1490950541.446,"0.011828264880952136"],[1490950601.446,"0.01191921916666625"],[1490950661.446,"0.011901336547619379"],[1490950721.446,"0.011776620238095158"],[1490950781.446,"0.011911536031746153"],[1490950841.446,"0.011467936309523809"],[1490950901.446,"0.012163667023809579"],[1490950961.446,"0.0116551746825399"],[1490951021.446,"0.011799408095237739"],[1490951081.446,"0.011845631309524084"],[1490951141.446,"0.011289116626983809"],[1490951201.446,"0.012258327777777984"],[1490951261.446,"0.012265819682539036"],[1490951321.446,"0.011346034166667811"],[1490951381.446,"0.011996446111110597"],[1490951441.446,"0.011511485714285046"],[1490951501.446,"0.011980616349206635"],[1490951561.446,"0.011565376031746316"],[1490951621.446,"0.010918043373016443"],[1490951681.446,"0.011479107380951632"],[1490951741.446,"0.012467024051997748"],[1490951801.446,"0.01235313125400671"],[1490951861.446,"0.012167793061507889"],[1490951921.446,"0.01249734373015914"],[1490951981.446,"0.011414617499999877"],[1490952041.446,"0.012559693849205949"],[1490952101.446,"0.012135384801587835"],[1490952161.446,"0.01195310698412663"],[1490952221.446,"0.011996730515873409"],[1490952281.446,"0.012245181626984071"],[1490952341.446,"0.01172794166666644"],[1490952401.446,"0.012153839325397124"],[1490952461.446,"0.01287662682539674"],[1490952521.446,"0.011412833611110576"],[1490952581.446,"0.0115385753968256"],[1490952641.446,"0.011953797142857927"],[1490952701.446,"0.012210606230158325"],[1490952761.446,"0.012193429836568915"],[1490952821.446,"0.01175164000191546"],[1490952881.446,"0.011686968928571266"],[1490952941.446,"0.01204885615079335"],[1490953001.446,"0.010858237182540066"],[1490953061.446,"0.012570554523809901"],[1490953121.446,"0.011606933412697877"],[1490953181.446,"0.011895175039682713"],[1490953241.446,"0.011877423888888992"],[1490953301.446,"0.01134354857142876"],[1490953361.446,"0.011999752857142089"],[1490953421.446,"0.011927079960317739"],[1490953481.446,"0.01172722273809559"],[1490953541.446,"0.0114388174999997"],[1490953601.446,"0.012584772738095138"],[1490953661.446,"0.011858990837323214"],[1490953721.446,"0.011489406427467985"],[1490953781.446,"0.011673106071428765"],[1490953841.446,"0.012389803452380168"],[1490953901.446,"0.010877735714285755"],[1490953961.446,"0.012098601984127518"],[1490954021.446,"0.011876002539682478"],[1490954081.446,"0.0119792138492057"],[1490954141.446,"0.01116768142857198"],[1490954201.446,"0.011819058452381173"],[1490954261.446,"0.011543723055555002"],[1490954321.446,"0.011877097777778114"],[1490954381.446,"0.011255818690476465"],[1490954441.446,"0.011544411269840424"],[1490954501.446,"0.011844739246031948"],[1490954561.446,"0.012498686626984624"],[1490954621.446,"0.011012790753967753"],[1490954681.446,"0.011763483769841236"],[1490954741.446,"0.011742064880952764"],[1490954801.446,"0.011329697023809454"],[1490954861.446,"0.011616721150793869"],[1490954921.446,"0.011935843650793056"],[1490954981.446,"0.012041806150794254"],[1490955041.446,"0.011776362817460298"],[1490955101.446,"0.011507964920634838"],[1490955161.446,"0.012249892380951723"],[1490955221.446,"0.011680689451964254"],[1490955281.446,"0.011966289381797203"],[1490955341.446,"0.011113054447726804"],[1490955401.446,"0.012155607703748966"],[1490955461.446,"0.011851554722222412"],[1490955521.446,"0.011899298531746077"],[1490955581.446,"0.01202313674603201"],[1490955641.446,"0.011739823253968055"],[1490955701.446,"0.011866135595237215"],[1490955761.446,"0.012171682563083994"],[1490955821.446,"0.01125473955952014"],[1490955881.446,"0.011791852817460289"],[1490955941.446,"0.011389896547619342"],[1490956001.446,"0.011801524404761971"],[1490956061.446,"0.011788201388888577"],[1490956121.446,"0.011472721388889214"],[1490956181.446,"0.012352298174603236"],[1490956241.446,"0.011831984404761721"],[1490956301.446,"0.0114478640476188"],[1490956361.446,"0.012315896944444986"],[1490956421.446,"0.01184387992063444"],[1490956481.446,"0.0108170579365078"],[1490956541.446,"0.012441825119047971"],[1490956601.446,"0.011650502579365023"],[1490956661.446,"0.011244622936507553"],[1490956721.446,"0.01138462460317496"],[1490956781.446,"0.012361013348424437"],[1490956841.446,"0.011687763677888905"],[1490956901.446,"0.011387440952381297"],[1490956961.446,"0.012246620039682158"],[1490957021.446,"0.010769535198412467"],[1490957081.446,"0.012311013690477024"],[1490957141.446,"0.011455958968253554"],[1490957201.446,"0.012126715198413286"],[1490957261.446,"0.011078292499999627"],[1490957321.446,"0.012041933253967746"],[1490957381.446,"0.01147051317460329"],[1490957441.446,"0.01173451460317538"],[1490957501.446,"0.011660740317459825"],[1490957561.446,"0.011851131269840753"],[1490957621.446,"0.012117949444444812"],[1490957681.446,"0.011214277301587397"],[1490957741.446,"0.011935565277777841"],[1490957801.446,"0.011180848809523986"],[1490957861.446,"0.011540955039682404"],[1490957921.446,"0.011678924523809829"],[1490957981.446,"0.01175049698412655"],[1490958041.446,"0.01179233821428546"],[1490958101.446,"0.011217207341269743"],[1490958161.446,"0.011623496111110998"],[1490958221.446,"0.011751017182540137"],[1490958281.446,"0.011548055515872839"],[1490958341.446,"0.01157145297619062"],[1490958401.446,"0.011809365079364814"],[1490958461.446,"0.011367088134920926"],[1490958521.446,"0.011220626785714515"],[1490958581.446,"0.012502413531745657"],[1490958641.446,"0.011674712222222085"],[1490958701.446,"0.010840117777778147"],[1490958761.446,"0.01169669242063464"],[1490958821.446,"0.01206404448412709"],[1490958881.446,"0.011476003253967956"],[1490958941.446,"0.011927363650794281"],[1490959001.446,"0.011834540039682623"],[1490959061.446,"0.011952310396106811"],[1490959121.446,"0.011641002569963536"],[1490959181.446,"0.011215335912698408"],[1490959241.446,"0.011801235515873079"],[1490959301.446,"0.012109150079365269"],[1490959361.446,"0.011696530238095701"],[1490959421.446,"0.01188721699431308"],[1490959481.446,"0.011013023946272025"],[1490959541.446,"0.011927455988174854"],[1490959601.446,"0.011773952156046168"],[1490959661.446,"0.011311449525742057"],[1490959721.446,"0.011926485873016056"],[1490959781.446,"0.012208613174603443"],[1490959841.446,"0.011077256706349554"],[1490959901.446,"0.012141572896825473"],[1490959961.446,"0.011884196547619123"],[1490960021.446,"0.01182910611111061"],[1490960081.446,"0.011089906190476237"],[1490960141.446,"0.011485851349206303"],[1490960201.446,"0.011621675079365073"],[1490960261.446,"0.011420984246031282"],[1490960321.446,"0.011702707664224543"],[1490960381.446,"0.011122996101531552"],[1490960441.446,"0.011923133293650747"],[1490960501.446,"0.012209551587301823"],[1490960561.446,"0.011541768293650705"],[1490960621.446,"0.01133343007936486"],[1490960681.446,"0.011718844880952742"],[1490960741.446,"0.01170618126984048"],[1490960801.446,"0.01158023575396868"],[1490960861.446,"0.012154581865079351"],[1490960921.446,"0.011287024246031918"],[1490960981.446,"0.012035483412697787"],[1490961041.446,"0.01206407186508005"],[1490961101.446,"0.011742228333332922"],[1490961161.446,"0.011460450952381294"],[1490961221.446,"0.011752177539682223"],[1490961281.446,"0.012416623373015778"],[1490961341.446,"0.01134374146825419"],[1490961401.446,"0.011742214642857577"],[1490961461.446,"0.01157076337301528"],[1490961521.446,"0.011251291190475883"],[1490961581.446,"0.010835279404761772"],[1490961641.446,"0.012082314722223412"],[1490961701.446,"0.011244282817460054"],[1490961761.446,"0.012600352738094536"],[1490961821.446,"0.011595374841270692"],[1490961881.446,"0.012047435158729298"],[1490961941.446,"0.012117879285714984"],[1490962001.446,"0.011105805912698236"],[1490962061.446,"0.011228379365079935"],[1490962121.446,"0.012051188888888457"],[1490962181.446,"0.011811605198411965"],[1490962241.446,"0.011438638690477312"],[1490962301.446,"0.011535638928571016"],[1490962361.446,"0.011846252277212543"],[1490962421.446,"0.011137096779830425"],[1490962481.446,"0.011301488807399701"],[1490962541.446,"0.011706436349206364"],[1490962601.446,"0.011607870952381014"],[1490962661.446,"0.01165941666666676"],[1490962721.446,"0.011457761706349363"],[1490962781.446,"0.012004376428571304"],[1490962841.446,"0.012380191230158676"],[1490962901.446,"0.011650816111111262"],[1490962961.446,"0.011339834484126858"],[1490963021.446,"0.011815001031746352"],[1490963081.446,"0.01215702742063424"],[1490963141.446,"0.011112767612387399"],[1490963201.446,"0.011991515394890143"],[1490963261.446,"0.011573327579365182"],[1490963321.446,"0.011559778809523533"],[1490963381.446,"0.012400119444444207"],[1490963441.446,"0.011127036507936056"],[1490963501.446,"0.012095518055556944"],[1490963561.446,"0.011203742460316668"],[1490963621.446,"0.012493672738095584"],[1490963681.446,"0.012086427023809085"],[1490963741.446,"0.01073350408730215"],[1490963801.446,"0.011784052619047683"],[1490963861.446,"0.011817165277777068"],[1490963921.446,"0.01162805619047661"],[1490963981.446,"0.01141054027777739"],[1490964041.446,"0.012398790952381392"],[1490964101.446,"0.011081906428571691"],[1490964161.446,"0.012049610714285322"],[1490964221.446,"0.011764468492063805"]]}],"cpu_current":[{"metric":{},"value":[1490964221.765,"0.011764468492063801"]}]},"last_update":"2017-03-31T12:43:41.618Z"}
diff --git a/spec/javascripts/blob/sketch/index_spec.js b/spec/javascripts/blob/sketch/index_spec.js
new file mode 100644
index 00000000000..0e4431548c4
--- /dev/null
+++ b/spec/javascripts/blob/sketch/index_spec.js
@@ -0,0 +1,118 @@
+/* eslint-disable no-new */
+import JSZip from 'jszip';
+import SketchLoader from '~/blob/sketch';
+
+describe('Sketch viewer', () => {
+ const generateZipFileArrayBuffer = (zipFile, resolve, done) => {
+ zipFile
+ .generateAsync({ type: 'arrayBuffer' })
+ .then((content) => {
+ resolve(content);
+
+ setTimeout(() => {
+ done();
+ }, 100);
+ });
+ };
+
+ preloadFixtures('static/sketch_viewer.html.raw');
+
+ beforeEach(() => {
+ loadFixtures('static/sketch_viewer.html.raw');
+ });
+
+ describe('with error message', () => {
+ beforeEach((done) => {
+ spyOn(SketchLoader.prototype, 'getZipFile').and.callFake(() => new Promise((resolve, reject) => {
+ reject();
+
+ setTimeout(() => {
+ done();
+ });
+ }));
+
+ new SketchLoader(document.getElementById('js-sketch-viewer'));
+ });
+
+ it('renders error message', () => {
+ expect(
+ document.querySelector('#js-sketch-viewer p'),
+ ).not.toBeNull();
+
+ expect(
+ document.querySelector('#js-sketch-viewer p').textContent.trim(),
+ ).toContain('Cannot show preview.');
+ });
+
+ it('removes render the loading icon', () => {
+ expect(
+ document.querySelector('.js-loading-icon'),
+ ).toBeNull();
+ });
+ });
+
+ describe('success', () => {
+ beforeEach((done) => {
+ spyOn(SketchLoader.prototype, 'getZipFile').and.callFake(() => new Promise((resolve) => {
+ const zipFile = new JSZip();
+ zipFile.folder('previews')
+ .file('preview.png', 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAMAAAAoyzS7AAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAA1JREFUeNoBAgD9/wAAAAIAAVMrnDAAAAAASUVORK5CYII=', {
+ base64: true,
+ });
+
+ generateZipFileArrayBuffer(zipFile, resolve, done);
+ }));
+
+ new SketchLoader(document.getElementById('js-sketch-viewer'));
+ });
+
+ it('does not render error message', () => {
+ expect(
+ document.querySelector('#js-sketch-viewer p'),
+ ).toBeNull();
+ });
+
+ it('removes render the loading icon', () => {
+ expect(
+ document.querySelector('.js-loading-icon'),
+ ).toBeNull();
+ });
+
+ it('renders preview img', () => {
+ const img = document.querySelector('#js-sketch-viewer img');
+
+ expect(img).not.toBeNull();
+ expect(img.classList.contains('img-responsive')).toBeTruthy();
+ });
+
+ it('renders link to image', () => {
+ const img = document.querySelector('#js-sketch-viewer img');
+ const link = document.querySelector('#js-sketch-viewer a');
+
+ expect(link.href).toBe(img.src);
+ expect(link.target).toBe('_blank');
+ });
+ });
+
+ describe('incorrect file', () => {
+ beforeEach((done) => {
+ spyOn(SketchLoader.prototype, 'getZipFile').and.callFake(() => new Promise((resolve) => {
+ const zipFile = new JSZip();
+
+ generateZipFileArrayBuffer(zipFile, resolve, done);
+ }));
+
+ new SketchLoader(document.getElementById('js-sketch-viewer'));
+ });
+
+ it('renders error message', () => {
+ expect(
+ document.querySelector('#js-sketch-viewer p'),
+ ).not.toBeNull();
+
+ expect(
+ document.querySelector('#js-sketch-viewer p').textContent.trim(),
+ ).toContain('Cannot show preview.');
+ });
+ });
+});
diff --git a/spec/javascripts/boards/board_list_spec.js b/spec/javascripts/boards/board_list_spec.js
new file mode 100644
index 00000000000..3f598887603
--- /dev/null
+++ b/spec/javascripts/boards/board_list_spec.js
@@ -0,0 +1,201 @@
+/* global BoardService */
+/* global boardsMockInterceptor */
+/* global List */
+/* global listObj */
+/* global ListIssue */
+import Vue from 'vue';
+import _ from 'underscore';
+import Sortable from 'vendor/Sortable';
+import BoardList from '~/boards/components/board_list';
+import eventHub from '~/boards/eventhub';
+import '~/boards/mixins/sortable_default_options';
+import '~/boards/models/issue';
+import '~/boards/models/list';
+import '~/boards/stores/boards_store';
+import './mock_data';
+
+window.Sortable = Sortable;
+
+describe('Board list component', () => {
+ let component;
+
+ beforeEach((done) => {
+ const el = document.createElement('div');
+
+ document.body.appendChild(el);
+ Vue.http.interceptors.push(boardsMockInterceptor);
+ gl.boardService = new BoardService('/test/issue-boards/board', '', '1');
+ gl.issueBoards.BoardsStore.create();
+ gl.IssueBoardsApp = new Vue();
+
+ const BoardListComp = Vue.extend(BoardList);
+ const list = new List(listObj);
+ const issue = new ListIssue({
+ title: 'Testing',
+ iid: 1,
+ confidential: false,
+ labels: [],
+ });
+ list.issuesSize = 1;
+ list.issues.push(issue);
+
+ component = new BoardListComp({
+ el,
+ propsData: {
+ disabled: false,
+ list,
+ issues: list.issues,
+ loading: false,
+ issueLinkBase: '/issues',
+ rootPath: '/',
+ },
+ }).$mount();
+
+ Vue.nextTick(() => {
+ done();
+ });
+ });
+
+ afterEach(() => {
+ Vue.http.interceptors = _.without(Vue.http.interceptors, boardsMockInterceptor);
+ });
+
+ it('renders component', () => {
+ expect(
+ component.$el.classList.contains('board-list-component'),
+ ).toBe(true);
+ });
+
+ it('renders loading icon', (done) => {
+ component.loading = true;
+
+ Vue.nextTick(() => {
+ expect(
+ component.$el.querySelector('.board-list-loading'),
+ ).not.toBeNull();
+
+ done();
+ });
+ });
+
+ it('renders issues', () => {
+ expect(
+ component.$el.querySelectorAll('.card').length,
+ ).toBe(1);
+ });
+
+ it('sets data attribute with issue id', () => {
+ expect(
+ component.$el.querySelector('.card').getAttribute('data-issue-id'),
+ ).toBe('1');
+ });
+
+ it('shows new issue form', (done) => {
+ component.toggleForm();
+
+ Vue.nextTick(() => {
+ expect(
+ component.$el.querySelector('.board-new-issue-form'),
+ ).not.toBeNull();
+
+ expect(
+ component.$el.querySelector('.is-smaller'),
+ ).not.toBeNull();
+
+ done();
+ });
+ });
+
+ it('shows new issue form after eventhub event', (done) => {
+ eventHub.$emit(`hide-issue-form-${component.list.id}`);
+
+ Vue.nextTick(() => {
+ expect(
+ component.$el.querySelector('.board-new-issue-form'),
+ ).not.toBeNull();
+
+ expect(
+ component.$el.querySelector('.is-smaller'),
+ ).not.toBeNull();
+
+ done();
+ });
+ });
+
+ it('does not show new issue form for closed list', (done) => {
+ component.list.type = 'closed';
+ component.toggleForm();
+
+ Vue.nextTick(() => {
+ expect(
+ component.$el.querySelector('.board-new-issue-form'),
+ ).toBeNull();
+
+ done();
+ });
+ });
+
+ it('shows count list item', (done) => {
+ component.showCount = true;
+
+ Vue.nextTick(() => {
+ expect(
+ component.$el.querySelector('.board-list-count'),
+ ).not.toBeNull();
+
+ expect(
+ component.$el.querySelector('.board-list-count').textContent.trim(),
+ ).toBe('Showing all issues');
+
+ done();
+ });
+ });
+
+ it('shows how many more issues to load', (done) => {
+ component.showCount = true;
+ component.list.issuesSize = 20;
+
+ Vue.nextTick(() => {
+ expect(
+ component.$el.querySelector('.board-list-count').textContent.trim(),
+ ).toBe('Showing 1 of 20 issues');
+
+ done();
+ });
+ });
+
+ it('loads more issues after scrolling', (done) => {
+ spyOn(component.list, 'nextPage');
+ component.$refs.list.style.height = '100px';
+ component.$refs.list.style.overflow = 'scroll';
+
+ for (let i = 0; i < 19; i += 1) {
+ const issue = component.list.issues[0];
+ issue.id += 1;
+ component.list.issues.push(issue);
+ }
+
+ Vue.nextTick(() => {
+ component.$refs.list.scrollTop = 20000;
+
+ setTimeout(() => {
+ expect(component.list.nextPage).toHaveBeenCalled();
+
+ done();
+ });
+ });
+ });
+
+ it('shows loading more spinner', (done) => {
+ component.showCount = true;
+ component.list.loadingMore = true;
+
+ Vue.nextTick(() => {
+ expect(
+ component.$el.querySelector('.board-list-count .fa-spinner'),
+ ).not.toBeNull();
+
+ done();
+ });
+ });
+});
diff --git a/spec/javascripts/fixtures/sketch_viewer.html.haml b/spec/javascripts/fixtures/sketch_viewer.html.haml
new file mode 100644
index 00000000000..f01bd00925a
--- /dev/null
+++ b/spec/javascripts/fixtures/sketch_viewer.html.haml
@@ -0,0 +1,2 @@
+.file-content#js-sketch-viewer{ data: { endpoint: '/test_sketch_file.sketch' } }
+ .js-loading-icon
diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml
index 002cffd3062..24654bf6afd 100644
--- a/spec/lib/gitlab/import_export/all_models.yml
+++ b/spec/lib/gitlab/import_export/all_models.yml
@@ -156,6 +156,8 @@ project:
- external_wiki_service
- kubernetes_service
- mock_ci_service
+- mock_deployment_service
+- mock_monitoring_service
- forked_project_link
- forked_from_project
- forked_project_links
diff --git a/spec/models/blob_spec.rb b/spec/models/blob_spec.rb
index 552229e9b07..ba110383977 100644
--- a/spec/models/blob_spec.rb
+++ b/spec/models/blob_spec.rb
@@ -67,6 +67,20 @@ describe Blob do
end
end
+ describe '#sketch?' do
+ it 'is falsey with image extension' do
+ git_blob = Gitlab::Git::Blob.new(name: "design.png")
+
+ expect(described_class.decorate(git_blob)).not_to be_sketch
+ end
+
+ it 'is truthy with sketch extension' do
+ git_blob = Gitlab::Git::Blob.new(name: "design.sketch")
+
+ expect(described_class.decorate(git_blob)).to be_sketch
+ end
+ end
+
describe '#video?' do
it 'is falsey with image extension' do
git_blob = Gitlab::Git::Blob.new(name: 'image.png')
@@ -92,7 +106,8 @@ describe Blob do
language: nil,
lfs_pointer?: false,
svg?: false,
- text?: false
+ text?: false,
+ binary?: false
)
described_class.decorate(double).tap do |blob|
@@ -135,6 +150,11 @@ describe Blob do
blob = stubbed_blob(text?: true, ipython_notebook?: true)
expect(blob.to_partial_path(project)).to eq 'notebook'
end
+
+ it 'handles Sketch files' do
+ blob = stubbed_blob(text?: true, sketch?: true, binary?: true)
+ expect(blob.to_partial_path(project)).to eq 'sketch'
+ end
end
describe '#size_within_svg_limits?' do
diff --git a/spec/requests/api/runner_spec.rb b/spec/requests/api/runner_spec.rb
index 044b989e5ba..1cfac7353d4 100644
--- a/spec/requests/api/runner_spec.rb
+++ b/spec/requests/api/runner_spec.rb
@@ -461,6 +461,29 @@ describe API::Runner do
end
end
+ context 'when dependencies is an empty array' do
+ let!(:job) { create(:ci_build_tag, pipeline: pipeline, name: 'spinach', stage: 'test', stage_idx: 0) }
+ let!(:job2) { create(:ci_build_tag, pipeline: pipeline, name: 'rubocop', stage: 'test', stage_idx: 0) }
+ let!(:empty_dependencies_job) do
+ create(:ci_build, pipeline: pipeline, token: 'test-job-token', name: 'empty_dependencies_job',
+ stage: 'deploy', stage_idx: 1,
+ options: { dependencies: [] })
+ end
+
+ before do
+ job.success
+ job2.success
+ end
+
+ it 'returns an empty array' do
+ request_job
+
+ expect(response).to have_http_status(201)
+ expect(json_response['id']).to eq(empty_dependencies_job.id)
+ expect(json_response['dependencies'].count).to eq(0)
+ end
+ end
+
context 'when job has no tags' do
before { job.update(tags: []) }
diff --git a/spec/support/controllers/githubish_import_controller_shared_examples.rb b/spec/support/controllers/githubish_import_controller_shared_examples.rb
index 51f1015f43c..c59b30c772d 100644
--- a/spec/support/controllers/githubish_import_controller_shared_examples.rb
+++ b/spec/support/controllers/githubish_import_controller_shared_examples.rb
@@ -180,7 +180,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do
it "takes the new namespace" do
expect(Gitlab::GithubImport::ProjectCreator).
to receive(:new).with(provider_repo, provider_repo.name, an_instance_of(Group), user, access_params, type: provider).
- and_return(double(execute: true))
+ and_return(double(execute: true))
post :create, target_namespace: provider_repo.name, format: :js
end
@@ -201,7 +201,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do
it "takes the current user's namespace" do
expect(Gitlab::GithubImport::ProjectCreator).
to receive(:new).with(provider_repo, provider_repo.name, user.namespace, user, access_params, type: provider).
- and_return(double(execute: true))
+ and_return(double(execute: true))
post :create, format: :js
end
@@ -229,7 +229,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do
end
end
- context 'user has chosen a nested namespace and name for the project' do
+ context 'user has chosen an existing nested namespace and name for the project' do
let(:parent_namespace) { create(:namespace, name: 'foo', owner: user) }
let(:nested_namespace) { create(:namespace, name: 'bar', parent: parent_namespace, owner: user) }
let(:test_name) { 'test_name' }
@@ -242,5 +242,58 @@ shared_examples 'a GitHub-ish import controller: POST create' do
post :create, { target_namespace: nested_namespace.full_path, new_name: test_name, format: :js }
end
end
+
+ context 'user has chosen a non-existent nested namespaces and name for the project' do
+ let(:test_name) { 'test_name' }
+
+ it 'takes the selected namespace and name' do
+ expect(Gitlab::GithubImport::ProjectCreator).
+ to receive(:new).with(provider_repo, test_name, kind_of(Namespace), user, access_params, type: provider).
+ and_return(double(execute: true))
+
+ post :create, { target_namespace: 'foo/bar', new_name: test_name, format: :js }
+ end
+
+ it 'creates the namespaces' do
+ allow(Gitlab::GithubImport::ProjectCreator).
+ to receive(:new).with(provider_repo, test_name, kind_of(Namespace), user, access_params, type: provider).
+ and_return(double(execute: true))
+
+ expect { post :create, { target_namespace: 'foo/bar', new_name: test_name, format: :js } }
+ .to change { Namespace.count }.by(2)
+ end
+
+ it 'new namespace has the right parent' do
+ allow(Gitlab::GithubImport::ProjectCreator).
+ to receive(:new).with(provider_repo, test_name, kind_of(Namespace), user, access_params, type: provider).
+ and_return(double(execute: true))
+
+ post :create, { target_namespace: 'foo/bar', new_name: test_name, format: :js }
+
+ expect(Namespace.find_by_path_or_name('bar').parent.path).to eq('foo')
+ end
+ end
+
+ context 'user has chosen existent and non-existent nested namespaces and name for the project' do
+ let(:test_name) { 'test_name' }
+ let!(:parent_namespace) { create(:namespace, name: 'foo', owner: user) }
+
+ it 'takes the selected namespace and name' do
+ expect(Gitlab::GithubImport::ProjectCreator).
+ to receive(:new).with(provider_repo, test_name, kind_of(Namespace), user, access_params, type: provider).
+ and_return(double(execute: true))
+
+ post :create, { target_namespace: 'foo/foobar/bar', new_name: test_name, format: :js }
+ end
+
+ it 'creates the namespaces' do
+ allow(Gitlab::GithubImport::ProjectCreator).
+ to receive(:new).with(provider_repo, test_name, kind_of(Namespace), user, access_params, type: provider).
+ and_return(double(execute: true))
+
+ expect { post :create, { target_namespace: 'foo/foobar/bar', new_name: test_name, format: :js } }
+ .to change { Namespace.count }.by(2)
+ end
+ end
end
end
diff --git a/yarn.lock b/yarn.lock
index f254668646c..48b847b84d0 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1245,6 +1245,10 @@ core-js@^2.2.0, core-js@^2.4.0, core-js@^2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e"
+core-js@~2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.3.0.tgz#fab83fbb0b2d8dc85fa636c4b9d34c75420c6d65"
+
core-util-is@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
@@ -1581,6 +1585,10 @@ es6-map@^0.1.3:
es6-symbol "~3.1.0"
event-emitter "~0.3.4"
+es6-promise@~3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.0.2.tgz#010d5858423a5f118979665f46486a95c6ee2bb6"
+
es6-promise@~4.0.3:
version "4.0.5"
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.0.5.tgz#7882f30adde5b240ccfa7f7d78c548330951ae42"
@@ -2335,6 +2343,10 @@ ignore@^3.2.0:
version "3.2.2"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.2.2.tgz#1c51e1ef53bab6ddc15db4d9ac4ec139eceb3410"
+immediate@~3.0.5:
+ version "3.0.6"
+ resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b"
+
imurmurhash@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
@@ -2764,6 +2776,20 @@ jsprim@^1.2.2:
json-schema "0.2.3"
verror "1.3.6"
+jszip-utils@^0.0.2:
+ version "0.0.2"
+ resolved "https://registry.yarnpkg.com/jszip-utils/-/jszip-utils-0.0.2.tgz#457d5cbca60a1c2e0706e9da2b544e8e7bc50bf8"
+
+jszip@^3.1.3:
+ version "3.1.3"
+ resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.1.3.tgz#8a920403b2b1651c0fc126be90192d9080957c37"
+ dependencies:
+ core-js "~2.3.0"
+ es6-promise "~3.0.2"
+ lie "~3.1.0"
+ pako "~1.0.2"
+ readable-stream "~2.0.6"
+
karma-coverage-istanbul-reporter@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/karma-coverage-istanbul-reporter/-/karma-coverage-istanbul-reporter-0.2.0.tgz#5766263338adeb0026f7e4ac7a89a5f056c5642c"
@@ -2868,6 +2894,12 @@ levn@^0.3.0, levn@~0.3.0:
prelude-ls "~1.1.2"
type-check "~0.3.2"
+lie@~3.1.0:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e"
+ dependencies:
+ immediate "~3.0.5"
+
load-json-file@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0"
@@ -3349,6 +3381,10 @@ pako@~0.2.0:
version "0.2.9"
resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75"
+pako@~1.0.2:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.5.tgz#d2205dfe5b9da8af797e7c163db4d1f84e4600bc"
+
parse-asn1@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.0.0.tgz#35060f6d5015d37628c770f4e091a0b5a278bc23"
@@ -3661,7 +3697,7 @@ readable-stream@~1.0.2:
isarray "0.0.1"
string_decoder "~0.10.x"
-readable-stream@~2.0.0:
+readable-stream@~2.0.0, readable-stream@~2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e"
dependencies: