diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 6b261bd5938..83e41a11e52 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -296,9 +296,9 @@ might be edited to make them small and simple.
Please submit Feature Proposals using the ['Feature Proposal' issue template](.gitlab/issue_templates/Feature Proposal.md) provided on the issue tracker.
-For changes in the interface, it is helpful to include a mockup. Issues that add to, or change, the interface should
-be given the ~"UX" label. This will allow the UX team to provide input and guidance. You may
-need to ask one of the [core team] members to add the label, if you do not have permissions to do it by yourself.
+For changes in the interface, it is helpful to include a mockup. Issues that add to, or change, the interface should
+be given the ~"UX" label. This will allow the UX team to provide input and guidance. You may
+need to ask one of the [core team] members to add the label, if you do not have permissions to do it by yourself.
If you want to create something yourself, consider opening an issue first to
discuss whether it is interesting to include this in GitLab.
@@ -658,7 +658,7 @@ available at [http://contributor-covenant.org/version/1/1/0/](http://contributor
[license-finder-doc]: doc/development/licensing.md
[GitLab Inc engineering workflow]: https://about.gitlab.com/handbook/engineering/workflow/#labelling-issues
[polling-etag]: https://docs.gitlab.com/ce/development/polling.html
-[testing]: doc/development/testing.md
+[testing]: doc/development/testing_guide/index.md
[^1]: Please note that specs other than JavaScript specs are considered backend
code.
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index 8298bb08b2d..301092317fe 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-0.43.0
+0.46.0
diff --git a/GITLAB_SHELL_VERSION b/GITLAB_SHELL_VERSION
index 5508e17c23b..c5b7013b9c5 100644
--- a/GITLAB_SHELL_VERSION
+++ b/GITLAB_SHELL_VERSION
@@ -1,2 +1 @@
-5.9.3
-
+5.9.4
diff --git a/Gemfile b/Gemfile
index e43370b1ab6..0dca265d1c7 100644
--- a/Gemfile
+++ b/Gemfile
@@ -398,7 +398,7 @@ group :ed25519 do
end
# Gitaly GRPC client
-gem 'gitaly-proto', '~> 0.39.0', require: 'gitaly'
+gem 'gitaly-proto', '~> 0.41.0', require: 'gitaly'
gem 'toml-rb', '~> 0.3.15', require: false
diff --git a/Gemfile.lock b/Gemfile.lock
index 0b56058defc..5bf1d6a8bc2 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -274,7 +274,7 @@ GEM
po_to_json (>= 1.0.0)
rails (>= 3.2.0)
gherkin-ruby (0.3.2)
- gitaly-proto (0.39.0)
+ gitaly-proto (0.41.0)
google-protobuf (~> 3.1)
grpc (~> 1.0)
github-linguist (4.7.6)
@@ -1023,7 +1023,7 @@ DEPENDENCIES
gettext (~> 3.2.2)
gettext_i18n_rails (~> 1.8.0)
gettext_i18n_rails_js (~> 1.2.0)
- gitaly-proto (~> 0.39.0)
+ gitaly-proto (~> 0.41.0)
github-linguist (~> 4.7.0)
gitlab-flowdock-git-hook (~> 1.0.1)
gitlab-markup (~> 1.6.2)
diff --git a/PROCESS.md b/PROCESS.md
index 5e65bb59246..06963243b25 100644
--- a/PROCESS.md
+++ b/PROCESS.md
@@ -1,4 +1,4 @@
-## GitLab Core Team & GitLab Inc. Contribution Process
+## GitLab core team & GitLab Inc. contribution process
---
diff --git a/app/assets/javascripts/awards_handler.js b/app/assets/javascripts/awards_handler.js
index 4f01345ee3b..622764107ad 100644
--- a/app/assets/javascripts/awards_handler.js
+++ b/app/assets/javascripts/awards_handler.js
@@ -1,8 +1,8 @@
/* eslint-disable class-methods-use-this */
-/* global Flash */
import _ from 'underscore';
import Cookies from 'js-cookie';
import { isInIssuePage, updateTooltipTitle } from './lib/utils/common_utils';
+import Flash from './flash';
const animationEndEventString = 'animationend webkitAnimationEnd MSAnimationEnd oAnimationEnd';
const transitionEndEventString = 'transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd';
diff --git a/app/assets/javascripts/blob/balsamiq_viewer.js b/app/assets/javascripts/blob/balsamiq_viewer.js
index 8641a6fdae6..062577af385 100644
--- a/app/assets/javascripts/blob/balsamiq_viewer.js
+++ b/app/assets/javascripts/blob/balsamiq_viewer.js
@@ -1,9 +1,8 @@
-/* global Flash */
-
+import Flash from '../flash';
import BalsamiqViewer from './balsamiq/balsamiq_viewer';
function onError() {
- const flash = new window.Flash('Balsamiq file could not be loaded.');
+ const flash = new Flash('Balsamiq file could not be loaded.');
return flash;
}
diff --git a/app/assets/javascripts/blob/file_template_mediator.js b/app/assets/javascripts/blob/file_template_mediator.js
index a20c6ca7a21..583e5faa506 100644
--- a/app/assets/javascripts/blob/file_template_mediator.js
+++ b/app/assets/javascripts/blob/file_template_mediator.js
@@ -1,6 +1,5 @@
/* eslint-disable class-methods-use-this */
-/* global Flash */
-
+import Flash from '../flash';
import FileTemplateTypeSelector from './template_selectors/type_selector';
import BlobCiYamlSelector from './template_selectors/ci_yaml_selector';
import DockerfileSelector from './template_selectors/dockerfile_selector';
diff --git a/app/assets/javascripts/blob/viewer/index.js b/app/assets/javascripts/blob/viewer/index.js
index e0b73f13d36..54132e8537b 100644
--- a/app/assets/javascripts/blob/viewer/index.js
+++ b/app/assets/javascripts/blob/viewer/index.js
@@ -1,4 +1,4 @@
-/* global Flash */
+import Flash from '../../flash';
import { handleLocationHash } from '../../lib/utils/common_utils';
export default class BlobViewer {
diff --git a/app/assets/javascripts/boards/boards_bundle.js b/app/assets/javascripts/boards/boards_bundle.js
index 815248f38ee..ef4093b59e3 100644
--- a/app/assets/javascripts/boards/boards_bundle.js
+++ b/app/assets/javascripts/boards/boards_bundle.js
@@ -1,10 +1,10 @@
/* eslint-disable one-var, quote-props, comma-dangle, space-before-function-paren */
/* global BoardService */
-/* global Flash */
import _ from 'underscore';
import Vue from 'vue';
import VueResource from 'vue-resource';
+import Flash from '../flash';
import FilteredSearchBoards from './filtered_search_boards';
import eventHub from './eventhub';
import './models/issue';
diff --git a/app/assets/javascripts/boards/components/board_sidebar.js b/app/assets/javascripts/boards/components/board_sidebar.js
index 590b7be36e3..7f3afefc9cc 100644
--- a/app/assets/javascripts/boards/components/board_sidebar.js
+++ b/app/assets/javascripts/boards/components/board_sidebar.js
@@ -3,9 +3,9 @@
/* global MilestoneSelect */
/* global LabelsSelect */
/* global Sidebar */
-/* global Flash */
import Vue from 'vue';
+import Flash from '../../flash';
import eventHub from '../../sidebar/event_hub';
import AssigneeTitle from '../../sidebar/components/assignees/assignee_title';
import Assignees from '../../sidebar/components/assignees/assignees';
diff --git a/app/assets/javascripts/boards/components/modal/footer.js b/app/assets/javascripts/boards/components/modal/footer.js
index a656f0546c0..de9e44cef35 100644
--- a/app/assets/javascripts/boards/components/modal/footer.js
+++ b/app/assets/javascripts/boards/components/modal/footer.js
@@ -1,7 +1,7 @@
/* eslint-disable no-new */
-/* global Flash */
import Vue from 'vue';
+import Flash from '../../../flash';
import './lists_dropdown';
const ModalStore = gl.issueBoards.ModalStore;
diff --git a/app/assets/javascripts/boards/components/sidebar/remove_issue.js b/app/assets/javascripts/boards/components/sidebar/remove_issue.js
index 1e623cf58b7..1ad97211934 100644
--- a/app/assets/javascripts/boards/components/sidebar/remove_issue.js
+++ b/app/assets/javascripts/boards/components/sidebar/remove_issue.js
@@ -1,7 +1,7 @@
/* eslint-disable no-new */
-/* global Flash */
import Vue from 'vue';
+import Flash from '../../../flash';
const Store = gl.issueBoards.BoardsStore;
diff --git a/app/assets/javascripts/build_artifacts.js b/app/assets/javascripts/build_artifacts.js
index 19388f1f9ae..ace89398943 100644
--- a/app/assets/javascripts/build_artifacts.js
+++ b/app/assets/javascripts/build_artifacts.js
@@ -1,30 +1,30 @@
-/* eslint-disable func-names, space-before-function-paren, wrap-iife, prefer-arrow-callback, no-unused-vars, no-return-assign, max-len */
+/* eslint-disable func-names, prefer-arrow-callback, no-return-assign */
import { visitUrl } from './lib/utils/url_utility';
import { convertPermissionToBoolean } from './lib/utils/common_utils';
-window.BuildArtifacts = (function() {
- function BuildArtifacts() {
+export default class BuildArtifacts {
+ constructor() {
this.disablePropagation();
this.setupEntryClick();
this.setupTooltips();
}
-
- BuildArtifacts.prototype.disablePropagation = function() {
- $('.top-block').on('click', '.download', function(e) {
+ // eslint-disable-next-line class-methods-use-this
+ disablePropagation() {
+ $('.top-block').on('click', '.download', function (e) {
return e.stopPropagation();
});
- return $('.tree-holder').on('click', 'tr[data-link] a', function(e) {
+ return $('.tree-holder').on('click', 'tr[data-link] a', function (e) {
return e.stopImmediatePropagation();
});
- };
-
- BuildArtifacts.prototype.setupEntryClick = function() {
- return $('.tree-holder').on('click', 'tr[data-link]', function(e) {
+ }
+ // eslint-disable-next-line class-methods-use-this
+ setupEntryClick() {
+ return $('.tree-holder').on('click', 'tr[data-link]', function () {
visitUrl(this.dataset.link, convertPermissionToBoolean(this.dataset.externalLink));
});
- };
-
- BuildArtifacts.prototype.setupTooltips = function() {
+ }
+ // eslint-disable-next-line class-methods-use-this
+ setupTooltips() {
$('.js-artifact-tree-tooltip').tooltip({
placement: 'bottom',
// Stop the tooltip from hiding when we stop hovering the element directly
@@ -41,7 +41,5 @@ window.BuildArtifacts = (function() {
.on('mouseleave', (e) => {
$(e.currentTarget).find('.js-artifact-tree-tooltip').tooltip('hide');
});
- };
-
- return BuildArtifacts;
-})();
+ }
+}
diff --git a/app/assets/javascripts/build_variables.js b/app/assets/javascripts/build_variables.js
index c955a9ac2ea..35edf3e0017 100644
--- a/app/assets/javascripts/build_variables.js
+++ b/app/assets/javascripts/build_variables.js
@@ -1,8 +1,10 @@
-/* eslint-disable func-names, prefer-arrow-callback, space-before-function-paren */
+/* eslint-disable func-names*/
-$(function() {
- $('.reveal-variables').off('click').on('click', function() {
- $('.js-build-variables').toggle();
- $(this).hide();
- });
-});
+export default function handleRevealVariables() {
+ $('.js-reveal-variables')
+ .off('click')
+ .on('click', function () {
+ $('.js-build-variables').toggle();
+ $(this).hide();
+ });
+}
diff --git a/app/assets/javascripts/ci_lint_editor.js b/app/assets/javascripts/ci_lint_editor.js
index dd4a08a2f31..b9469e5b7cb 100644
--- a/app/assets/javascripts/ci_lint_editor.js
+++ b/app/assets/javascripts/ci_lint_editor.js
@@ -1,7 +1,4 @@
-
-window.gl = window.gl || {};
-
-class CILintEditor {
+export default class CILintEditor {
constructor() {
this.editor = window.ace.edit('ci-editor');
this.textarea = document.querySelector('#content');
@@ -13,5 +10,3 @@ class CILintEditor {
});
}
}
-
-gl.CILintEditor = CILintEditor;
diff --git a/app/assets/javascripts/create_merge_request_dropdown.js b/app/assets/javascripts/create_merge_request_dropdown.js
index ff2f2c81971..bf40eb3ee11 100644
--- a/app/assets/javascripts/create_merge_request_dropdown.js
+++ b/app/assets/javascripts/create_merge_request_dropdown.js
@@ -1,5 +1,5 @@
/* eslint-disable no-new */
-/* global Flash */
+import Flash from './flash';
import DropLab from './droplab/drop_lab';
import ISetter from './droplab/plugins/input_setter';
diff --git a/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js b/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js
index cdf5e3c0290..49bb6c52180 100644
--- a/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js
+++ b/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js
@@ -1,7 +1,6 @@
-/* global Flash */
-
import Vue from 'vue';
import Cookies from 'js-cookie';
+import Flash from '../flash';
import Translate from '../vue_shared/translate';
import banner from './components/banner.vue';
import stageCodeComponent from './components/stage_code_component.vue';
diff --git a/app/assets/javascripts/deploy_keys/components/app.vue b/app/assets/javascripts/deploy_keys/components/app.vue
index a663e30dfd0..54e13b79a4f 100644
--- a/app/assets/javascripts/deploy_keys/components/app.vue
+++ b/app/assets/javascripts/deploy_keys/components/app.vue
@@ -1,5 +1,5 @@
" }
it { is_expected.to render_template('new') }
- it { project.repository.branch_names.include?('feature/test') }
+ it { project.repository.branch_exists?('feature/test') }
end
end
diff --git a/spec/factories/merge_requests.rb b/spec/factories/merge_requests.rb
index 2c732aaf4ed..7c4a22c94c2 100644
--- a/spec/factories/merge_requests.rb
+++ b/spec/factories/merge_requests.rb
@@ -73,6 +73,12 @@ FactoryGirl.define do
merge_user author
end
+ trait :remove_source_branch do
+ merge_params do
+ { 'force_remove_source_branch' => '1' }
+ end
+ end
+
after(:build) do |merge_request|
target_project = merge_request.target_project
source_project = merge_request.source_project
diff --git a/spec/features/dashboard/groups_list_spec.rb b/spec/features/dashboard/groups_list_spec.rb
index 4c120b09345..1cb78410957 100644
--- a/spec/features/dashboard/groups_list_spec.rb
+++ b/spec/features/dashboard/groups_list_spec.rb
@@ -1,14 +1,15 @@
require 'spec_helper'
feature 'Dashboard Groups page', :js do
- let!(:user) { create :user }
- let!(:group) { create(:group) }
- let!(:nested_group) { create(:group, :nested) }
- let!(:another_group) { create(:group) }
+ let(:user) { create :user }
+ let(:group) { create(:group) }
+ let(:nested_group) { create(:group, :nested) }
+ let(:another_group) { create(:group) }
it 'shows groups user is member of' do
group.add_owner(user)
nested_group.add_owner(user)
+ expect(another_group).to be_persisted
sign_in(user)
visit dashboard_groups_path
@@ -22,6 +23,7 @@ feature 'Dashboard Groups page', :js do
before do
group.add_owner(user)
nested_group.add_owner(user)
+ expect(another_group).to be_persisted
sign_in(user)
@@ -51,7 +53,7 @@ feature 'Dashboard Groups page', :js do
end
end
- describe 'group with subgroups' do
+ describe 'group with subgroups', :nested_groups do
let!(:subgroup) { create(:group, :public, parent: group) }
before do
@@ -90,7 +92,8 @@ feature 'Dashboard Groups page', :js do
end
describe 'when using pagination' do
- let(:group2) { create(:group) }
+ let(:group) { create(:group, created_at: 5.days.ago) }
+ let(:group2) { create(:group, created_at: 2.days.ago) }
before do
group.add_owner(user)
@@ -102,12 +105,9 @@ feature 'Dashboard Groups page', :js do
visit dashboard_groups_path
end
- it 'shows pagination' do
- expect(page).to have_selector('.gl-pagination')
- expect(page).to have_selector('.gl-pagination .page', count: 2)
- end
-
it 'loads results for next page' do
+ expect(page).to have_selector('.gl-pagination .page', count: 2)
+
# Check first page
expect(page).to have_content(group2.full_name)
expect(page).to have_selector("#group-#{group2.id}")
diff --git a/spec/features/explore/user_explores_projects_spec.rb b/spec/features/explore/user_explores_projects_spec.rb
new file mode 100644
index 00000000000..6ac9497b024
--- /dev/null
+++ b/spec/features/explore/user_explores_projects_spec.rb
@@ -0,0 +1,72 @@
+require 'spec_helper'
+
+describe 'User explores projects' do
+ set(:archived_project) { create(:project, :archived) }
+ set(:internal_project) { create(:project, :internal) }
+ set(:private_project) { create(:project, :private) }
+ set(:public_project) { create(:project, :public) }
+
+ shared_examples_for 'shows public projects' do
+ it 'shows projects' do
+ expect(page).to have_content(public_project.title)
+ expect(page).not_to have_content(internal_project.title)
+ expect(page).not_to have_content(private_project.title)
+ expect(page).not_to have_content(archived_project.title)
+ end
+ end
+
+ shared_examples_for 'shows public and internal projects' do
+ it 'shows projects' do
+ expect(page).to have_content(public_project.title)
+ expect(page).to have_content(internal_project.title)
+ expect(page).not_to have_content(private_project.title)
+ expect(page).not_to have_content(archived_project.title)
+ end
+ end
+
+ context 'when not signed in' do
+ context 'when viewing public projects' do
+ before do
+ visit(explore_projects_path)
+ end
+
+ include_examples 'shows public projects'
+ end
+ end
+
+ context 'when signed in' do
+ set(:user) { create(:user) }
+
+ before do
+ sign_in(user)
+ end
+
+ context 'when viewing public projects' do
+ before do
+ visit(explore_projects_path)
+ end
+
+ include_examples 'shows public and internal projects'
+ end
+
+ context 'when viewing most starred projects' do
+ before do
+ visit(starred_explore_projects_path)
+ end
+
+ include_examples 'shows public and internal projects'
+ end
+
+ context 'when viewing trending projects' do
+ before do
+ [archived_project, public_project].each { |project| create(:note_on_issue, project: project) }
+
+ TrendingProject.refresh!
+
+ visit(trending_explore_projects_path)
+ end
+
+ include_examples 'shows public projects'
+ end
+ end
+end
diff --git a/spec/features/groups/milestone_spec.rb b/spec/features/groups/milestone_spec.rb
index 56144d17d4f..12aa54a3da1 100644
--- a/spec/features/groups/milestone_spec.rb
+++ b/spec/features/groups/milestone_spec.rb
@@ -18,6 +18,27 @@ feature 'Group milestones', :js do
visit new_group_milestone_path(group)
end
+ it 'renders description preview' do
+ form = find('.gfm-form')
+
+ form.fill_in(:milestone_description, with: '')
+
+ click_link('Preview')
+
+ preview = find('.js-md-preview')
+
+ expect(preview).to have_content('Nothing to preview.')
+
+ click_link('Write')
+
+ form.fill_in(:milestone_description, with: ':+1: Nice')
+
+ click_link('Preview')
+
+ expect(preview).to have_css('gl-emoji')
+ expect(find('#milestone_description', visible: false)).not_to be_visible
+ end
+
it 'creates milestone with start date' do
fill_in 'Title', with: 'testing'
find('#milestone_start_date').click
diff --git a/spec/features/merge_requests/diff_notes_resolve_spec.rb b/spec/features/merge_requests/diff_notes_resolve_spec.rb
index b475bcb3921..2b580ca1809 100644
--- a/spec/features/merge_requests/diff_notes_resolve_spec.rb
+++ b/spec/features/merge_requests/diff_notes_resolve_spec.rb
@@ -88,14 +88,24 @@ feature 'Diff notes resolve', :js do
end
end
- it 'hides resolved discussion' do
- page.within '.diff-content' do
- click_button 'Resolve discussion'
+ describe 'resolved discussion' do
+ before do
+ page.within '.diff-content' do
+ click_button 'Resolve discussion'
+ end
+
+ visit_merge_request
end
- visit_merge_request
+ it 'hides when resolve discussion is clicked' do
+ expect(page).to have_selector('.discussion-body', visible: false)
+ end
- expect(page).to have_selector('.discussion-body', visible: false)
+ it 'shows resolved discussion when toggled' do
+ find(".timeline-content .discussion[data-discussion-id='#{note.discussion_id}'] .discussion-toggle-button").click
+
+ expect(page.find(".timeline-content #note_#{note.noteable_id}")).to be_visible
+ end
end
it 'allows user to resolve from reply form without a comment' do
diff --git a/spec/features/merge_requests/diffs_spec.rb b/spec/features/merge_requests/diffs_spec.rb
index e32bbaf517b..21bbf82be77 100644
--- a/spec/features/merge_requests/diffs_spec.rb
+++ b/spec/features/merge_requests/diffs_spec.rb
@@ -44,12 +44,8 @@ feature 'Diffs URL', :js do
visit "#{diffs_project_merge_request_path(project, merge_request)}#{fragment}"
end
- it 'shows collapsed note' do
- wait_for_requests
-
- expect(page).to have_selector('.discussion-notes.collapsed') do |note_container|
- expect(note_container).to have_selector(fragment, visible: false)
- end
+ it 'shows expanded note' do
+ expect(page).to have_selector(fragment, visible: true)
end
end
end
diff --git a/spec/features/projects/import_export/import_file_spec.rb b/spec/features/projects/import_export/import_file_spec.rb
index c928459f911..026aa03f7cf 100644
--- a/spec/features/projects/import_export/import_file_spec.rb
+++ b/spec/features/projects/import_export/import_file_spec.rb
@@ -27,6 +27,7 @@ feature 'Import/Export - project import integration test', :js do
select2(namespace.id, from: '#project_namespace_id')
fill_in :project_path, with: project_path, visible: true
+ click_import_project_tab
click_link 'GitLab export'
expect(page).to have_content('Import an exported GitLab project')
@@ -51,6 +52,7 @@ feature 'Import/Export - project import integration test', :js do
context 'path is not prefilled' do
scenario 'user imports an exported project successfully' do
visit new_project_path
+ click_import_project_tab
click_link 'GitLab export'
fill_in :path, with: 'test-project-path', visible: true
@@ -72,6 +74,7 @@ feature 'Import/Export - project import integration test', :js do
select2(user.namespace.id, from: '#project_namespace_id')
fill_in :project_path, with: project.name, visible: true
+ click_import_project_tab
click_link 'GitLab export'
attach_file('file', file)
click_on 'Import project'
@@ -81,19 +84,6 @@ feature 'Import/Export - project import integration test', :js do
end
end
- context 'when limited to the default user namespace' do
- scenario 'passes correct namespace ID in the URL' do
- visit new_project_path
-
- fill_in :project_path, with: 'test-project-path', visible: true
-
- click_link 'GitLab export'
-
- expect(page).to have_content('GitLab project export')
- expect(URI.parse(current_url).query).to eq("namespace_id=#{user.namespace.id}&path=test-project-path")
- end
- end
-
def wiki_exists?(project)
wiki = ProjectWiki.new(project)
File.exist?(wiki.repository.path_to_repo) && !wiki.repository.empty?
@@ -102,4 +92,8 @@ feature 'Import/Export - project import integration test', :js do
def project_hook_exists?(project)
Gitlab::Git::Hook.new('post-receive', project.repository.raw_repository).exists?
end
+
+ def click_import_project_tab
+ find('#import-project-tab').trigger('click')
+ end
end
diff --git a/spec/features/projects/issuable_templates_spec.rb b/spec/features/projects/issuable_templates_spec.rb
index 62b23121c5a..9f67216705d 100644
--- a/spec/features/projects/issuable_templates_spec.rb
+++ b/spec/features/projects/issuable_templates_spec.rb
@@ -118,7 +118,7 @@ feature 'issuable templates', :js do
context 'user creates a merge request from a forked project using templates' do
let(:template_content) { 'this is a test "feature-proposal" template' }
let(:fork_user) { create(:user) }
- let(:forked_project) { fork_project(project, fork_user) }
+ let(:forked_project) { fork_project(project, fork_user, repository: true) }
let(:merge_request) { create(:merge_request, :with_diffs, source_project: forked_project, target_project: project) }
background do
diff --git a/spec/features/projects/issues/list_spec.rb b/spec/features/projects/issues/list_spec.rb
deleted file mode 100644
index 9fc03f49f5b..00000000000
--- a/spec/features/projects/issues/list_spec.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-require 'spec_helper'
-
-feature 'Issues List' do
- let(:user) { create(:user) }
- let(:project) { create(:project) }
-
- background do
- project.team << [user, :developer]
-
- sign_in(user)
- end
-
- scenario 'user does not see create new list button' do
- create(:issue, project: project)
-
- visit project_issues_path(project)
-
- expect(page).not_to have_selector('.js-new-board-list')
- end
-end
diff --git a/spec/features/projects/issues/user_views_issues_spec.rb b/spec/features/projects/issues/user_views_issues_spec.rb
new file mode 100644
index 00000000000..d35009b8974
--- /dev/null
+++ b/spec/features/projects/issues/user_views_issues_spec.rb
@@ -0,0 +1,56 @@
+require 'spec_helper'
+
+describe 'User views issues' do
+ set(:user) { create(:user) }
+
+ shared_examples_for 'shows issues' do
+ it 'shows issues' do
+ expect(page).to have_content(project.name)
+ .and have_content(issue1.title)
+ .and have_content(issue2.title)
+ .and have_no_selector('.js-new-board-list')
+ end
+ end
+
+ context 'when project is public' do
+ set(:project) { create(:project_empty_repo, :public) }
+ set(:issue1) { create(:issue, project: project) }
+ set(:issue2) { create(:issue, project: project) }
+
+ context 'when signed in' do
+ before do
+ project.add_developer(user)
+ sign_in(user)
+
+ visit(project_issues_path(project))
+ end
+
+ include_examples 'shows issues'
+ end
+
+ context 'when not signed in' do
+ before do
+ visit(project_issues_path(project))
+ end
+
+ include_examples 'shows issues'
+ end
+ end
+
+ context 'when project is internal' do
+ set(:project) { create(:project_empty_repo, :internal) }
+ set(:issue1) { create(:issue, project: project) }
+ set(:issue2) { create(:issue, project: project) }
+
+ context 'when signed in' do
+ before do
+ project.add_developer(user)
+ sign_in(user)
+
+ visit(project_issues_path(project))
+ end
+
+ include_examples 'shows issues'
+ end
+ end
+end
diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb
index d265191e0c6..171b001aa7a 100644
--- a/spec/features/projects/jobs_spec.rb
+++ b/spec/features/projects/jobs_spec.rb
@@ -300,13 +300,13 @@ feature 'Jobs' do
shared_examples 'expected variables behavior' do
it 'shows variable key and value after click', :js do
- expect(page).to have_css('.reveal-variables')
+ expect(page).to have_css('.js-reveal-variables')
expect(page).not_to have_css('.js-build-variable')
expect(page).not_to have_css('.js-build-value')
click_button 'Reveal Variables'
- expect(page).not_to have_css('.reveal-variables')
+ expect(page).not_to have_css('.js-reveal-variables')
expect(page).to have_selector('.js-build-variable', text: 'TRIGGER_KEY_1')
expect(page).to have_selector('.js-build-value', text: 'TRIGGER_VALUE_1')
end
diff --git a/spec/features/projects/merge_requests/user_views_open_merge_request_spec.rb b/spec/features/projects/merge_requests/user_views_open_merge_request_spec.rb
index 8970cf54457..3aac93eaf7c 100644
--- a/spec/features/projects/merge_requests/user_views_open_merge_request_spec.rb
+++ b/spec/features/projects/merge_requests/user_views_open_merge_request_spec.rb
@@ -6,7 +6,7 @@ describe 'User views an open merge request' do
end
context 'when a merge request does not have repository' do
- let(:project) { create(:project, :public) }
+ let(:project) { create(:project, :public, :repository) }
before do
visit(merge_request_path(merge_request))
diff --git a/spec/features/projects/merge_requests/user_views_open_merge_requests_spec.rb b/spec/features/projects/merge_requests/user_views_open_merge_requests_spec.rb
index 07b8c1ef479..bf95dbb7d09 100644
--- a/spec/features/projects/merge_requests/user_views_open_merge_requests_spec.rb
+++ b/spec/features/projects/merge_requests/user_views_open_merge_requests_spec.rb
@@ -1,72 +1,115 @@
require 'spec_helper'
describe 'User views open merge requests' do
- let(:project) { create(:project, :public, :repository) }
+ set(:user) { create(:user) }
- context "when the target branch is the project's default branch" do
- let!(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
- let!(:closed_merge_request) { create(:closed_merge_request, source_project: project, target_project: project) }
-
- before do
- visit(project_merge_requests_path(project))
- end
-
- it 'shows open merge requests' do
- expect(page).to have_content(merge_request.title).and have_no_content(closed_merge_request.title)
- end
-
- it 'does not show target branch name' do
- expect(page).to have_content(merge_request.title)
- expect(find('.issuable-info')).not_to have_content(project.default_branch)
+ shared_examples_for 'shows merge requests' do
+ it 'shows merge requests' do
+ expect(page).to have_content(project.name).and have_content(merge_request.source_project.name)
end
end
- context "when the target branch is different from the project's default branch" do
- let!(:merge_request) do
- create(:merge_request,
- source_project: project,
- target_project: project,
- source_branch: 'fix',
- target_branch: 'feature_conflict')
- end
+ context 'when project is public' do
+ set(:project) { create(:project, :public, :repository) }
- before do
- visit(project_merge_requests_path(project))
- end
+ context 'when not signed in' do
+ context "when the target branch is the project's default branch" do
+ let!(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
+ let!(:closed_merge_request) { create(:closed_merge_request, source_project: project, target_project: project) }
- it 'shows target branch name' do
- expect(page).to have_content(merge_request.target_branch)
- end
- end
+ before do
+ visit(project_merge_requests_path(project))
+ end
- context 'when a merge request has pipelines' do
- let!(:build) { create :ci_build, pipeline: pipeline }
+ include_examples 'shows merge requests'
- let(:merge_request) do
- create(:merge_request_with_diffs,
- source_project: project,
- target_project: project,
- source_branch: 'merge-test')
- end
+ it 'shows open merge requests' do
+ expect(page).to have_content(merge_request.title).and have_no_content(closed_merge_request.title)
+ end
- let(:pipeline) do
- create(:ci_pipeline,
- project: project,
- sha: merge_request.diff_head_sha,
- ref: merge_request.source_branch,
- head_pipeline_of: merge_request)
- end
-
- before do
- project.enable_ci
-
- visit(project_merge_requests_path(project))
- end
-
- it 'shows pipeline status' do
- page.within('.mr-list') do
- expect(page).to have_link('Pipeline: pending')
+ it 'does not show target branch name' do
+ expect(page).to have_content(merge_request.title)
+ expect(find('.issuable-info')).not_to have_content(project.default_branch)
+ end
end
+
+ context "when the target branch is different from the project's default branch" do
+ let!(:merge_request) do
+ create(:merge_request,
+ source_project: project,
+ target_project: project,
+ source_branch: 'fix',
+ target_branch: 'feature_conflict')
+ end
+
+ before do
+ visit(project_merge_requests_path(project))
+ end
+
+ it 'shows target branch name' do
+ expect(page).to have_content(merge_request.target_branch)
+ end
+ end
+
+ context 'when a merge request has pipelines' do
+ let!(:build) { create :ci_build, pipeline: pipeline }
+
+ let(:merge_request) do
+ create(:merge_request_with_diffs,
+ source_project: project,
+ target_project: project,
+ source_branch: 'merge-test')
+ end
+
+ let(:pipeline) do
+ create(:ci_pipeline,
+ project: project,
+ sha: merge_request.diff_head_sha,
+ ref: merge_request.source_branch,
+ head_pipeline_of: merge_request)
+ end
+
+ before do
+ project.enable_ci
+
+ visit(project_merge_requests_path(project))
+ end
+
+ it 'shows pipeline status' do
+ page.within('.mr-list') do
+ expect(page).to have_link('Pipeline: pending')
+ end
+ end
+ end
+ end
+
+ context 'when signed in' do
+ let!(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
+
+ before do
+ project.add_developer(user)
+ sign_in(user)
+
+ visit(project_merge_requests_path(project))
+ end
+
+ include_examples 'shows merge requests'
+ end
+ end
+
+ context 'when project is internal' do
+ let!(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
+ set(:project) { create(:project, :internal, :repository) }
+
+ context 'when signed in' do
+ before do
+ project.add_developer(user)
+ sign_in(user)
+
+ visit(project_merge_requests_path(project))
+ end
+
+ include_examples 'shows merge requests'
end
end
end
diff --git a/spec/features/projects/new_project_spec.rb b/spec/features/projects/new_project_spec.rb
index cd3dc72d3c6..8e11cb94350 100644
--- a/spec/features/projects/new_project_spec.rb
+++ b/spec/features/projects/new_project_spec.rb
@@ -9,12 +9,14 @@ feature 'New project' do
sign_in(user)
end
- it 'shows "New project" page' do
+ it 'shows "New project" page', :js do
visit new_project_path
expect(page).to have_content('Project path')
expect(page).to have_content('Project name')
+ find('#import-project-tab').trigger('click')
+
expect(page).to have_link('GitHub')
expect(page).to have_link('Bitbucket')
expect(page).to have_link('GitLab.com')
@@ -23,14 +25,15 @@ feature 'New project' do
expect(page).to have_link('GitLab export')
end
- context 'Visibility level selector' do
+ context 'Visibility level selector', :js do
Gitlab::VisibilityLevel.options.each do |key, level|
it "sets selector to #{key}" do
stub_application_setting(default_project_visibility: level)
visit new_project_path
-
- expect(find_field("project_visibility_level_#{level}")).to be_checked
+ page.within('#blank-project-pane') do
+ expect(find_field("project_visibility_level_#{level}")).to be_checked
+ end
end
it "saves visibility level #{level} on validation error" do
@@ -38,8 +41,9 @@ feature 'New project' do
choose(s_(key))
click_button('Create project')
-
- expect(find_field("project_visibility_level_#{level}")).to be_checked
+ page.within('#blank-project-pane') do
+ expect(find_field("project_visibility_level_#{level}")).to be_checked
+ end
end
end
end
@@ -51,9 +55,11 @@ feature 'New project' do
end
it 'selects the user namespace' do
- namespace = find('#project_namespace_id')
+ page.within('#blank-project-pane') do
+ namespace = find('#project_namespace_id')
- expect(namespace.text).to eq user.username
+ expect(namespace.text).to eq user.username
+ end
end
end
@@ -66,9 +72,11 @@ feature 'New project' do
end
it 'selects the group namespace' do
- namespace = find('#project_namespace_id option[selected]')
+ page.within('#blank-project-pane') do
+ namespace = find('#project_namespace_id option[selected]')
- expect(namespace.text).to eq group.name
+ expect(namespace.text).to eq group.name
+ end
end
end
@@ -82,9 +90,11 @@ feature 'New project' do
end
it 'selects the group namespace' do
- namespace = find('#project_namespace_id option[selected]')
+ page.within('#blank-project-pane') do
+ namespace = find('#project_namespace_id option[selected]')
- expect(namespace.text).to eq subgroup.full_path
+ expect(namespace.text).to eq subgroup.full_path
+ end
end
end
@@ -124,9 +134,10 @@ feature 'New project' do
end
end
- context 'Import project options' do
+ context 'Import project options', :js do
before do
visit new_project_path
+ find('#import-project-tab').trigger('click')
end
context 'from git repository url' do
diff --git a/spec/features/projects/user_views_details_spec.rb b/spec/features/projects/user_views_details_spec.rb
new file mode 100644
index 00000000000..ffc063654cd
--- /dev/null
+++ b/spec/features/projects/user_views_details_spec.rb
@@ -0,0 +1,151 @@
+require 'spec_helper'
+
+describe 'User views details' do
+ set(:user) { create(:user) }
+
+ shared_examples_for 'redirects to the sign in page' do
+ it 'redirects to the sign in page' do
+ expect(current_path).to eq(new_user_session_path)
+ end
+ end
+
+ shared_examples_for 'shows details of empty project' do
+ let(:user_has_ssh_key) { false }
+
+ it 'shows details' do
+ expect(page).not_to have_content('Git global setup')
+
+ page.all(:css, '.git-empty .clone').each do |element|
+ expect(element.text).to include(project.http_url_to_repo)
+ end
+
+ expect(page).to have_field('project_clone', with: project.http_url_to_repo) unless user_has_ssh_key
+ end
+ end
+
+ shared_examples_for 'shows details of non empty project' do
+ let(:user_has_ssh_key) { false }
+
+ it 'shows details' do
+ page.within('.breadcrumbs .breadcrumb-item-text') do
+ expect(page).to have_content(project.title)
+ end
+
+ expect(page).to have_field('project_clone', with: project.http_url_to_repo) unless user_has_ssh_key
+ end
+ end
+
+ context 'when project is public' do
+ context 'when project is empty' do
+ set(:project) { create(:project_empty_repo, :public) }
+
+ context 'when not signed in' do
+ before do
+ visit(project_path(project))
+ end
+
+ include_examples 'shows details of empty project'
+ end
+
+ context 'when signed in' do
+ before do
+ sign_in(user)
+ end
+
+ context 'when user does not have ssh keys' do
+ before do
+ visit(project_path(project))
+ end
+
+ include_examples 'shows details of empty project'
+ end
+
+ context 'when user has ssh keys' do
+ before do
+ create(:personal_key, user: user)
+
+ visit(project_path(project))
+ end
+
+ include_examples 'shows details of empty project' do
+ let(:user_has_ssh_key) { true }
+ end
+ end
+ end
+ end
+
+ context 'when project is not empty' do
+ set(:project) { create(:project, :public, :repository) }
+
+ before do
+ visit(project_path(project))
+ end
+
+ context 'when not signed in' do
+ before do
+ allow(Gitlab.config.gitlab).to receive(:host).and_return('www.example.com')
+ end
+
+ include_examples 'shows details of non empty project'
+ end
+
+ context 'when signed in' do
+ before do
+ sign_in(user)
+ end
+
+ context 'when user does not have ssh keys' do
+ before do
+ visit(project_path(project))
+ end
+
+ include_examples 'shows details of non empty project'
+ end
+
+ context 'when user has ssh keys' do
+ before do
+ create(:personal_key, user: user)
+
+ visit(project_path(project))
+ end
+
+ include_examples 'shows details of non empty project' do
+ let(:user_has_ssh_key) { true }
+ end
+ end
+ end
+ end
+ end
+
+ context 'when project is internal' do
+ set(:project) { create(:project, :internal, :repository) }
+
+ context 'when not signed in' do
+ before do
+ visit(project_path(project))
+ end
+
+ include_examples 'redirects to the sign in page'
+ end
+
+ context 'when signed in' do
+ before do
+ sign_in(user)
+
+ visit(project_path(project))
+ end
+
+ include_examples 'shows details of non empty project'
+ end
+ end
+
+ context 'when project is private' do
+ set(:project) { create(:project, :private) }
+
+ before do
+ visit(project_path(project))
+ end
+
+ include_examples 'redirects to the sign in page'
+ end
+end
diff --git a/spec/features/projects_spec.rb b/spec/features/projects_spec.rb
index ac62280e4ca..3bc7ec3123f 100644
--- a/spec/features/projects_spec.rb
+++ b/spec/features/projects_spec.rb
@@ -12,8 +12,9 @@ feature 'Project' do
visit new_project_path
end
- it "allows creation from templates" do
- page.choose(template.name)
+ it "allows creation from templates", :js do
+ find('#create-from-template-tab').trigger('click')
+ find("##{template.name}").trigger('click')
fill_in("project_path", with: template.name)
page.within '#content-body' do
diff --git a/spec/features/task_lists_spec.rb b/spec/features/task_lists_spec.rb
index 485b0b287ad..2dc3c5e3927 100644
--- a/spec/features/task_lists_spec.rb
+++ b/spec/features/task_lists_spec.rb
@@ -3,7 +3,7 @@ require 'spec_helper'
feature 'Task Lists' do
include Warden::Test::Helpers
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:user) { create(:user) }
let(:user2) { create(:user) }
diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb
index 10bc5f2ecd2..87ae1fa5660 100644
--- a/spec/helpers/application_helper_spec.rb
+++ b/spec/helpers/application_helper_spec.rb
@@ -57,15 +57,17 @@ describe ApplicationHelper do
end
describe 'project_icon' do
+ let(:asset_host) { 'http://assets' }
+
it 'returns an url for the avatar' do
- project = create(:project, avatar: File.open(uploaded_image_temp_path))
+ project = create(:project, :public, avatar: File.open(uploaded_image_temp_path))
avatar_url = "/uploads/-/system/project/avatar/#{project.id}/banana_sample.gif"
expect(helper.project_icon(project.full_path).to_s)
.to eq "
"
- allow(ActionController::Base).to receive(:asset_host).and_return(gitlab_host)
- avatar_url = "#{gitlab_host}/uploads/-/system/project/avatar/#{project.id}/banana_sample.gif"
+ allow(ActionController::Base).to receive(:asset_host).and_return(asset_host)
+ avatar_url = "#{asset_host}/uploads/-/system/project/avatar/#{project.id}/banana_sample.gif"
expect(helper.project_icon(project.full_path).to_s)
.to eq "
"
diff --git a/spec/helpers/groups_helper_spec.rb b/spec/helpers/groups_helper_spec.rb
index 76e5964ccf7..97f0ed4904e 100644
--- a/spec/helpers/groups_helper_spec.rb
+++ b/spec/helpers/groups_helper_spec.rb
@@ -3,6 +3,8 @@ require 'spec_helper'
describe GroupsHelper do
include ApplicationHelper
+ let(:asset_host) { 'http://assets' }
+
describe 'group_icon' do
avatar_file_path = File.join(Rails.root, 'spec', 'fixtures', 'banana_sample.gif')
@@ -10,14 +12,53 @@ describe GroupsHelper do
group = create(:group)
group.avatar = fixture_file_upload(avatar_file_path)
group.save!
- expect(group_icon(group.path).to_s)
+
+ avatar_url = "/uploads/-/system/group/avatar/#{group.id}/banana_sample.gif"
+
+ expect(helper.group_icon(group).to_s)
+ .to eq "
"
+
+ allow(ActionController::Base).to receive(:asset_host).and_return(asset_host)
+ avatar_url = "#{asset_host}/uploads/-/system/group/avatar/#{group.id}/banana_sample.gif"
+
+ expect(helper.group_icon(group).to_s)
+ .to eq "
"
+ end
+ end
+
+ describe 'group_icon_url' do
+ avatar_file_path = File.join(Rails.root, 'spec', 'fixtures', 'banana_sample.gif')
+
+ it 'returns an url for the avatar' do
+ group = create(:group)
+ group.avatar = fixture_file_upload(avatar_file_path)
+ group.save!
+ expect(group_icon_url(group.path).to_s)
+ .to match("/uploads/-/system/group/avatar/#{group.id}/banana_sample.gif")
+ end
+
+ it 'returns an CDN url for the avatar' do
+ allow(ActionController::Base).to receive(:asset_host).and_return(asset_host)
+ group = create(:group)
+ group.avatar = fixture_file_upload(avatar_file_path)
+ group.save!
+ expect(group_icon_url(group.path).to_s)
+ .to match("#{asset_host}/uploads/-/system/group/avatar/#{group.id}/banana_sample.gif")
+ end
+
+ it 'returns an based url for the avatar if private' do
+ allow(ActionController::Base).to receive(:asset_host).and_return(asset_host)
+ group = create(:group, :private)
+ group.avatar = fixture_file_upload(avatar_file_path)
+ group.save!
+ expect(group_icon_url(group.path).to_s)
.to match("/uploads/-/system/group/avatar/#{group.id}/banana_sample.gif")
end
it 'gives default avatar_icon when no avatar is present' do
group = create(:group)
group.save!
- expect(group_icon(group.path)).to match_asset_path('group_avatar.png')
+ expect(group_icon_url(group.path)).to match_asset_path('group_avatar.png')
end
end
diff --git a/spec/javascripts/awards_handler_spec.js b/spec/javascripts/awards_handler_spec.js
index a22b71fd1dc..268b5b83b73 100644
--- a/spec/javascripts/awards_handler_spec.js
+++ b/spec/javascripts/awards_handler_spec.js
@@ -28,7 +28,7 @@ import '~/lib/utils/common_utils';
preloadFixtures('merge_requests/diff_comment.html.raw');
beforeEach(function(done) {
loadFixtures('merge_requests/diff_comment.html.raw');
- $('body').data('page', 'projects:merge_requests:show');
+ $('body').attr('data-page', 'projects:merge_requests:show');
loadAwardsHandler(true).then((obj) => {
awardsHandler = obj;
spyOn(awardsHandler, 'postEmoji').and.callFake((button, url, emoji, cb) => cb());
@@ -55,6 +55,9 @@ import '~/lib/utils/common_utils';
// restore original url root value
gon.relative_url_root = urlRoot;
+ // Undo what we did to the shared
+ $('body').removeAttr('data-page');
+
awardsHandler.destroy();
});
describe('::showEmojiMenu', function() {
diff --git a/spec/javascripts/behaviors/quick_submit_spec.js b/spec/javascripts/behaviors/quick_submit_spec.js
index f62bf43adb9..d5300d9c63d 100644
--- a/spec/javascripts/behaviors/quick_submit_spec.js
+++ b/spec/javascripts/behaviors/quick_submit_spec.js
@@ -19,6 +19,11 @@ describe('Quick Submit behavior', () => {
this.textarea = $('.js-quick-submit textarea').first();
});
+ afterEach(() => {
+ // Undo what we did to the shared
+ $('body').removeAttr('data-page');
+ });
+
it('does not respond to other keyCodes', () => {
this.textarea.trigger(keydownEvent({
keyCode: 32,
diff --git a/spec/javascripts/flash_spec.js b/spec/javascripts/flash_spec.js
new file mode 100644
index 00000000000..060ffaa339b
--- /dev/null
+++ b/spec/javascripts/flash_spec.js
@@ -0,0 +1,269 @@
+import flash, {
+ createFlashEl,
+ createAction,
+ hideFlash,
+} from '~/flash';
+
+describe('Flash', () => {
+ describe('createFlashEl', () => {
+ let el;
+
+ beforeEach(() => {
+ el = document.createElement('div');
+ });
+
+ afterEach(() => {
+ el.innerHTML = '';
+ });
+
+ it('creates flash element with type', () => {
+ el.innerHTML = createFlashEl('testing', 'alert');
+
+ expect(
+ el.querySelector('.flash-alert'),
+ ).not.toBeNull();
+ });
+
+ it('escapes text', () => {
+ el.innerHTML = createFlashEl('', 'alert');
+
+ expect(
+ el.querySelector('.flash-text').textContent.trim(),
+ ).toBe('');
+ });
+
+ it('adds container classes when inside content wrapper', () => {
+ el.innerHTML = createFlashEl('testing', 'alert', true);
+
+ expect(
+ el.querySelector('.flash-text').classList.contains('container-fluid'),
+ ).toBeTruthy();
+ expect(
+ el.querySelector('.flash-text').classList.contains('container-limited'),
+ ).toBeTruthy();
+ });
+ });
+
+ describe('hideFlash', () => {
+ let el;
+
+ beforeEach(() => {
+ el = document.createElement('div');
+ el.className = 'js-testing';
+ });
+
+ it('sets transition style', () => {
+ hideFlash(el);
+
+ expect(
+ el.style.transition,
+ ).toBe('opacity 0.3s');
+ });
+
+ it('sets opacity style', () => {
+ hideFlash(el);
+
+ expect(
+ el.style.opacity,
+ ).toBe('0');
+ });
+
+ it('does not set styles when fadeTransition is false', () => {
+ hideFlash(el, false);
+
+ expect(
+ el.style.opacity,
+ ).toBe('');
+ expect(
+ el.style.transition,
+ ).toBe('');
+ });
+
+ it('removes element after transitionend', () => {
+ document.body.appendChild(el);
+
+ hideFlash(el);
+ el.dispatchEvent(new Event('transitionend'));
+
+ expect(
+ document.querySelector('.js-testing'),
+ ).toBeNull();
+ });
+
+ it('calls event listener callback once', () => {
+ spyOn(el, 'remove').and.callThrough();
+ document.body.appendChild(el);
+
+ hideFlash(el);
+
+ el.dispatchEvent(new Event('transitionend'));
+ el.dispatchEvent(new Event('transitionend'));
+
+ expect(
+ el.remove.calls.count(),
+ ).toBe(1);
+ });
+ });
+
+ describe('createAction', () => {
+ let el;
+
+ beforeEach(() => {
+ el = document.createElement('div');
+ });
+
+ it('creates link with href', () => {
+ el.innerHTML = createAction({
+ href: 'testing',
+ title: 'test',
+ });
+
+ expect(
+ el.querySelector('.flash-action').href,
+ ).toContain('testing');
+ });
+
+ it('uses hash as href when no href is present', () => {
+ el.innerHTML = createAction({
+ title: 'test',
+ });
+
+ expect(
+ el.querySelector('.flash-action').href,
+ ).toContain('#');
+ });
+
+ it('adds role when no href is present', () => {
+ el.innerHTML = createAction({
+ title: 'test',
+ });
+
+ expect(
+ el.querySelector('.flash-action').getAttribute('role'),
+ ).toBe('button');
+ });
+
+ it('escapes the title text', () => {
+ el.innerHTML = createAction({
+ title: '',
+ });
+
+ expect(
+ el.querySelector('.flash-action').textContent.trim(),
+ ).toBe('');
+ });
+ });
+
+ describe('createFlash', () => {
+ describe('no flash-container', () => {
+ it('does not add to the DOM', () => {
+ const flashEl = flash('testing');
+
+ expect(
+ flashEl,
+ ).toBeNull();
+ expect(
+ document.querySelector('.flash-alert'),
+ ).toBeNull();
+ });
+ });
+
+ describe('with flash-container', () => {
+ beforeEach(() => {
+ document.body.innerHTML += `
+ '));
- $el.closest.and.returnValue($('
'));
+ notes.putEditFormInPlace($el);
- Notes.prototype.putEditFormInPlace.call({
- getEditFormSelector: () => '',
- enableGFM: true
- }, $el);
-
- expect(gl.GLForm).toHaveBeenCalledWith(jasmine.any(Object), true);
+ expect(notes.glForm.enableGFM).toBeTruthy();
});
});
@@ -815,7 +818,7 @@ import '~/notes';
});
it('shows a flash message', () => {
- this.notes.addFlash('Error message', FLASH_TYPE_ALERT, this.notes.parentTimeline);
+ this.notes.addFlash('Error message', FLASH_TYPE_ALERT, this.notes.parentTimeline.get(0));
expect($('.flash-alert').is(':visible')).toBeTruthy();
});
@@ -828,7 +831,7 @@ import '~/notes';
});
it('hides visible flash message', () => {
- this.notes.addFlash('Error message 1', FLASH_TYPE_ALERT, this.notes.parentTimeline);
+ this.notes.addFlash('Error message 1', FLASH_TYPE_ALERT, this.notes.parentTimeline.get(0));
this.notes.clearFlash();
diff --git a/spec/javascripts/pipeline_schedules/setup_pipeline_variable_list_spec.js b/spec/javascripts/pipeline_schedules/setup_pipeline_variable_list_spec.js
index e90c20e20d2..5b316b319a5 100644
--- a/spec/javascripts/pipeline_schedules/setup_pipeline_variable_list_spec.js
+++ b/spec/javascripts/pipeline_schedules/setup_pipeline_variable_list_spec.js
@@ -92,7 +92,7 @@ describe('Pipeline Variable List', () => {
});
it('should remove the row when clicking the remove button', () => {
- $markup.find('.js-row-remove-button').click();
+ $markup.find('.js-row-remove-button').trigger('click');
expect($markup.find('.js-row').length).toBe(0);
});
diff --git a/spec/javascripts/prometheus_metrics/prometheus_metrics_spec.js b/spec/javascripts/prometheus_metrics/prometheus_metrics_spec.js
index 2b3a821dbd9..b24567ffc0c 100644
--- a/spec/javascripts/prometheus_metrics/prometheus_metrics_spec.js
+++ b/spec/javascripts/prometheus_metrics/prometheus_metrics_spec.js
@@ -109,12 +109,16 @@ describe('PrometheusMetrics', () => {
it('should show loader animation while response is being loaded and hide it when request is complete', (done) => {
const deferred = $.Deferred();
- spyOn($, 'getJSON').and.returnValue(deferred.promise());
+ spyOn($, 'ajax').and.returnValue(deferred.promise());
prometheusMetrics.loadActiveMetrics();
expect(prometheusMetrics.$monitoredMetricsLoading.hasClass('hidden')).toBeFalsy();
- expect($.getJSON).toHaveBeenCalledWith(prometheusMetrics.activeMetricsEndpoint);
+ expect($.ajax).toHaveBeenCalledWith({
+ url: prometheusMetrics.activeMetricsEndpoint,
+ dataType: 'json',
+ global: false,
+ });
deferred.resolve({ data: metrics, success: true });
@@ -126,7 +130,7 @@ describe('PrometheusMetrics', () => {
it('should show empty state if response failed to load', (done) => {
const deferred = $.Deferred();
- spyOn($, 'getJSON').and.returnValue(deferred.promise());
+ spyOn($, 'ajax').and.returnValue(deferred.promise());
spyOn(prometheusMetrics, 'populateActiveMetrics');
prometheusMetrics.loadActiveMetrics();
@@ -142,7 +146,7 @@ describe('PrometheusMetrics', () => {
it('should populate metrics list once response is loaded', (done) => {
const deferred = $.Deferred();
- spyOn($, 'getJSON').and.returnValue(deferred.promise());
+ spyOn($, 'ajax').and.returnValue(deferred.promise());
spyOn(prometheusMetrics, 'populateActiveMetrics');
prometheusMetrics.loadActiveMetrics();
diff --git a/spec/javascripts/search_autocomplete_spec.js b/spec/javascripts/search_autocomplete_spec.js
index a53f58b5d0d..cf811af3d6c 100644
--- a/spec/javascripts/search_autocomplete_spec.js
+++ b/spec/javascripts/search_autocomplete_spec.js
@@ -6,7 +6,7 @@ import '~/lib/utils/common_utils';
import 'vendor/fuzzaldrin-plus';
(function() {
- var addBodyAttributes, assertLinks, dashboardIssuesPath, dashboardMRsPath, groupIssuesPath, groupMRsPath, groupName, mockDashboardOptions, mockGroupOptions, mockProjectOptions, projectIssuesPath, projectMRsPath, projectName, userId, widget;
+ var assertLinks, dashboardIssuesPath, dashboardMRsPath, groupIssuesPath, groupMRsPath, groupName, mockDashboardOptions, mockGroupOptions, mockProjectOptions, projectIssuesPath, projectMRsPath, projectName, userId, widget;
var userName = 'root';
widget = null;
@@ -29,25 +29,31 @@ import 'vendor/fuzzaldrin-plus';
groupName = 'Gitlab Org';
- // Add required attributes to body before starting the test.
- // section would be dashboard|group|project
- addBodyAttributes = function(section) {
- var $body;
- if (section == null) {
- section = 'dashboard';
- }
- $body = $('body');
+ const removeBodyAttributes = function() {
+ const $body = $('body');
+
$body.removeAttr('data-page');
$body.removeAttr('data-project');
$body.removeAttr('data-group');
+ };
+
+ // Add required attributes to body before starting the test.
+ // section would be dashboard|group|project
+ const addBodyAttributes = function(section) {
+ if (section == null) {
+ section = 'dashboard';
+ }
+
+ const $body = $('body');
+ removeBodyAttributes();
switch (section) {
case 'dashboard':
- return $body.data('page', 'root:index');
+ return $body.attr('data-page', 'root:index');
case 'group':
- $body.data('page', 'groups:show');
+ $body.attr('data-page', 'groups:show');
return $body.data('group', 'gitlab-org');
case 'project':
- $body.data('page', 'projects:show');
+ $body.attr('data-page', 'projects:show');
return $body.data('project', 'gitlab-ce');
}
};
@@ -108,7 +114,7 @@ import 'vendor/fuzzaldrin-plus';
preloadFixtures('static/search_autocomplete.html.raw');
beforeEach(function() {
loadFixtures('static/search_autocomplete.html.raw');
- widget = new gl.SearchAutocomplete;
+
// Prevent turbolinks from triggering within gl_dropdown
spyOn(window.gl.utils, 'visitUrl').and.returnValue(true);
@@ -120,6 +126,8 @@ import 'vendor/fuzzaldrin-plus';
});
afterEach(function() {
+ // Undo what we did to the shared
+ removeBodyAttributes();
window.gon = {};
});
it('should show Dashboard specific dropdown menu', function() {
diff --git a/spec/javascripts/u2f/authenticate_spec.js b/spec/javascripts/u2f/authenticate_spec.js
index e924107b29b..29b15f3a782 100644
--- a/spec/javascripts/u2f/authenticate_spec.js
+++ b/spec/javascripts/u2f/authenticate_spec.js
@@ -1,72 +1,63 @@
-/* eslint-disable space-before-function-paren, new-parens, quotes, comma-dangle, no-var, one-var, one-var-declaration-per-line, max-len */
-/* global MockU2FDevice */
-/* global U2FAuthenticate */
-
-import '~/u2f/authenticate';
-import '~/u2f/util';
-import '~/u2f/error';
+import U2FAuthenticate from '~/u2f/authenticate';
import 'vendor/u2f';
-import './mock_u2f_device';
+import MockU2FDevice from './mock_u2f_device';
-(function() {
- describe('U2FAuthenticate', function() {
- preloadFixtures('u2f/authenticate.html.raw');
+describe('U2FAuthenticate', () => {
+ preloadFixtures('u2f/authenticate.html.raw');
- beforeEach(function() {
- loadFixtures('u2f/authenticate.html.raw');
- this.u2fDevice = new MockU2FDevice;
- this.container = $("#js-authenticate-u2f");
- this.component = new window.gl.U2FAuthenticate(
- this.container,
- '#js-login-u2f-form',
- {
- sign_requests: []
- },
- document.querySelector('#js-login-2fa-device'),
- document.querySelector('.js-2fa-form')
- );
+ beforeEach(() => {
+ loadFixtures('u2f/authenticate.html.raw');
+ this.u2fDevice = new MockU2FDevice();
+ this.container = $('#js-authenticate-u2f');
+ this.component = new U2FAuthenticate(
+ this.container,
+ '#js-login-u2f-form',
+ {
+ sign_requests: [],
+ },
+ document.querySelector('#js-login-2fa-device'),
+ document.querySelector('.js-2fa-form'),
+ );
- // bypass automatic form submission within renderAuthenticated
- spyOn(this.component, 'renderAuthenticated').and.returnValue(true);
+ // bypass automatic form submission within renderAuthenticated
+ spyOn(this.component, 'renderAuthenticated').and.returnValue(true);
- return this.component.start();
+ return this.component.start();
+ });
+
+ it('allows authenticating via a U2F device', () => {
+ const inProgressMessage = this.container.find('p');
+ expect(inProgressMessage.text()).toContain('Trying to communicate with your device');
+ this.u2fDevice.respondToAuthenticateRequest({
+ deviceData: 'this is data from the device',
});
- it('allows authenticating via a U2F device', function() {
- var inProgressMessage;
- inProgressMessage = this.container.find("p");
- expect(inProgressMessage.text()).toContain("Trying to communicate with your device");
+ expect(this.component.renderAuthenticated).toHaveBeenCalledWith('{"deviceData":"this is data from the device"}');
+ });
+
+ return describe('errors', () => {
+ it('displays an error message', () => {
+ const setupButton = this.container.find('#js-login-u2f-device');
+ setupButton.trigger('click');
this.u2fDevice.respondToAuthenticateRequest({
- deviceData: "this is data from the device"
+ errorCode: 'error!',
+ });
+ const errorMessage = this.container.find('p');
+ return expect(errorMessage.text()).toContain('There was a problem communicating with your device');
+ });
+ return it('allows retrying authentication after an error', () => {
+ let setupButton = this.container.find('#js-login-u2f-device');
+ setupButton.trigger('click');
+ this.u2fDevice.respondToAuthenticateRequest({
+ errorCode: 'error!',
+ });
+ const retryButton = this.container.find('#js-u2f-try-again');
+ retryButton.trigger('click');
+ setupButton = this.container.find('#js-login-u2f-device');
+ setupButton.trigger('click');
+ this.u2fDevice.respondToAuthenticateRequest({
+ deviceData: 'this is data from the device',
});
expect(this.component.renderAuthenticated).toHaveBeenCalledWith('{"deviceData":"this is data from the device"}');
});
- return describe("errors", function() {
- it("displays an error message", function() {
- var errorMessage, setupButton;
- setupButton = this.container.find("#js-login-u2f-device");
- setupButton.click();
- this.u2fDevice.respondToAuthenticateRequest({
- errorCode: "error!"
- });
- errorMessage = this.container.find("p");
- return expect(errorMessage.text()).toContain("There was a problem communicating with your device");
- });
- return it("allows retrying authentication after an error", function() {
- var retryButton, setupButton;
- setupButton = this.container.find("#js-login-u2f-device");
- setupButton.click();
- this.u2fDevice.respondToAuthenticateRequest({
- errorCode: "error!"
- });
- retryButton = this.container.find("#js-u2f-try-again");
- retryButton.click();
- setupButton = this.container.find("#js-login-u2f-device");
- setupButton.click();
- this.u2fDevice.respondToAuthenticateRequest({
- deviceData: "this is data from the device"
- });
- expect(this.component.renderAuthenticated).toHaveBeenCalledWith('{"deviceData":"this is data from the device"}');
- });
- });
});
-}).call(window);
+});
diff --git a/spec/javascripts/u2f/mock_u2f_device.js b/spec/javascripts/u2f/mock_u2f_device.js
index 4eb8ad3d9e4..5a1ace2b4d6 100644
--- a/spec/javascripts/u2f/mock_u2f_device.js
+++ b/spec/javascripts/u2f/mock_u2f_device.js
@@ -1,31 +1,28 @@
-/* eslint-disable space-before-function-paren, no-var, prefer-rest-params, wrap-iife, no-unused-expressions, no-return-assign, no-param-reassign, max-len */
+/* eslint-disable prefer-rest-params, wrap-iife,
+no-unused-expressions, no-return-assign, no-param-reassign*/
-(function() {
- this.MockU2FDevice = (function() {
- function MockU2FDevice() {
- this.respondToAuthenticateRequest = this.respondToAuthenticateRequest.bind(this);
- this.respondToRegisterRequest = this.respondToRegisterRequest.bind(this);
- window.u2f || (window.u2f = {});
- window.u2f.register = (function(_this) {
- return function(appId, registerRequests, signRequests, callback) {
- return _this.registerCallback = callback;
- };
- })(this);
- window.u2f.sign = (function(_this) {
- return function(appId, challenges, signRequests, callback) {
- return _this.authenticateCallback = callback;
- };
- })(this);
- }
+export default class MockU2FDevice {
+ constructor() {
+ this.respondToAuthenticateRequest = this.respondToAuthenticateRequest.bind(this);
+ this.respondToRegisterRequest = this.respondToRegisterRequest.bind(this);
+ window.u2f || (window.u2f = {});
+ window.u2f.register = (function (_this) {
+ return function (appId, registerRequests, signRequests, callback) {
+ return _this.registerCallback = callback;
+ };
+ })(this);
+ window.u2f.sign = (function (_this) {
+ return function (appId, challenges, signRequests, callback) {
+ return _this.authenticateCallback = callback;
+ };
+ })(this);
+ }
- MockU2FDevice.prototype.respondToRegisterRequest = function(params) {
- return this.registerCallback(params);
- };
+ respondToRegisterRequest(params) {
+ return this.registerCallback(params);
+ }
- MockU2FDevice.prototype.respondToAuthenticateRequest = function(params) {
- return this.authenticateCallback(params);
- };
-
- return MockU2FDevice;
- })();
-}).call(window);
+ respondToAuthenticateRequest(params) {
+ return this.authenticateCallback(params);
+ }
+}
diff --git a/spec/javascripts/u2f/register_spec.js b/spec/javascripts/u2f/register_spec.js
index f5e32c1b358..b0051f11362 100644
--- a/spec/javascripts/u2f/register_spec.js
+++ b/spec/javascripts/u2f/register_spec.js
@@ -1,77 +1,69 @@
-/* eslint-disable space-before-function-paren, new-parens, quotes, no-var, one-var, one-var-declaration-per-line, comma-dangle, max-len */
-/* global MockU2FDevice */
-/* global U2FRegister */
-
-import '~/u2f/register';
-import '~/u2f/util';
-import '~/u2f/error';
+import U2FRegister from '~/u2f/register';
import 'vendor/u2f';
-import './mock_u2f_device';
+import MockU2FDevice from './mock_u2f_device';
-(function() {
- describe('U2FRegister', function() {
- preloadFixtures('u2f/register.html.raw');
+describe('U2FRegister', () => {
+ preloadFixtures('u2f/register.html.raw');
- beforeEach(function() {
- loadFixtures('u2f/register.html.raw');
- this.u2fDevice = new MockU2FDevice;
- this.container = $("#js-register-u2f");
- this.component = new U2FRegister(this.container, $("#js-register-u2f-templates"), {}, "token");
- return this.component.start();
+ beforeEach(() => {
+ loadFixtures('u2f/register.html.raw');
+ this.u2fDevice = new MockU2FDevice();
+ this.container = $('#js-register-u2f');
+ this.component = new U2FRegister(this.container, $('#js-register-u2f-templates'), {}, 'token');
+ return this.component.start();
+ });
+
+ it('allows registering a U2F device', () => {
+ const setupButton = this.container.find('#js-setup-u2f-device');
+ expect(setupButton.text()).toBe('Setup new U2F device');
+ setupButton.trigger('click');
+ const inProgressMessage = this.container.children('p');
+ expect(inProgressMessage.text()).toContain('Trying to communicate with your device');
+ this.u2fDevice.respondToRegisterRequest({
+ deviceData: 'this is data from the device',
});
- it('allows registering a U2F device', function() {
- var deviceResponse, inProgressMessage, registeredMessage, setupButton;
- setupButton = this.container.find("#js-setup-u2f-device");
- expect(setupButton.text()).toBe('Setup new U2F device');
- setupButton.click();
- inProgressMessage = this.container.children("p");
- expect(inProgressMessage.text()).toContain("Trying to communicate with your device");
+ const registeredMessage = this.container.find('p');
+ const deviceResponse = this.container.find('#js-device-response');
+ expect(registeredMessage.text()).toContain('Your device was successfully set up!');
+ return expect(deviceResponse.val()).toBe('{"deviceData":"this is data from the device"}');
+ });
+
+ return describe('errors', () => {
+ it('doesn\'t allow the same device to be registered twice (for the same user', () => {
+ const setupButton = this.container.find('#js-setup-u2f-device');
+ setupButton.trigger('click');
this.u2fDevice.respondToRegisterRequest({
- deviceData: "this is data from the device"
+ errorCode: 4,
});
- registeredMessage = this.container.find('p');
- deviceResponse = this.container.find('#js-device-response');
- expect(registeredMessage.text()).toContain("Your device was successfully set up!");
- return expect(deviceResponse.val()).toBe('{"deviceData":"this is data from the device"}');
+ const errorMessage = this.container.find('p');
+ return expect(errorMessage.text()).toContain('already been registered with us');
});
- return describe("errors", function() {
- it("doesn't allow the same device to be registered twice (for the same user", function() {
- var errorMessage, setupButton;
- setupButton = this.container.find("#js-setup-u2f-device");
- setupButton.click();
- this.u2fDevice.respondToRegisterRequest({
- errorCode: 4
- });
- errorMessage = this.container.find("p");
- return expect(errorMessage.text()).toContain("already been registered with us");
+
+ it('displays an error message for other errors', () => {
+ const setupButton = this.container.find('#js-setup-u2f-device');
+ setupButton.trigger('click');
+ this.u2fDevice.respondToRegisterRequest({
+ errorCode: 'error!',
});
- it("displays an error message for other errors", function() {
- var errorMessage, setupButton;
- setupButton = this.container.find("#js-setup-u2f-device");
- setupButton.click();
- this.u2fDevice.respondToRegisterRequest({
- errorCode: "error!"
- });
- errorMessage = this.container.find("p");
- return expect(errorMessage.text()).toContain("There was a problem communicating with your device");
+ const errorMessage = this.container.find('p');
+ return expect(errorMessage.text()).toContain('There was a problem communicating with your device');
+ });
+
+ return it('allows retrying registration after an error', () => {
+ let setupButton = this.container.find('#js-setup-u2f-device');
+ setupButton.trigger('click');
+ this.u2fDevice.respondToRegisterRequest({
+ errorCode: 'error!',
});
- return it("allows retrying registration after an error", function() {
- var registeredMessage, retryButton, setupButton;
- setupButton = this.container.find("#js-setup-u2f-device");
- setupButton.click();
- this.u2fDevice.respondToRegisterRequest({
- errorCode: "error!"
- });
- retryButton = this.container.find("#U2FTryAgain");
- retryButton.click();
- setupButton = this.container.find("#js-setup-u2f-device");
- setupButton.click();
- this.u2fDevice.respondToRegisterRequest({
- deviceData: "this is data from the device"
- });
- registeredMessage = this.container.find("p");
- return expect(registeredMessage.text()).toContain("Your device was successfully set up!");
+ const retryButton = this.container.find('#U2FTryAgain');
+ retryButton.trigger('click');
+ setupButton = this.container.find('#js-setup-u2f-device');
+ setupButton.trigger('click');
+ this.u2fDevice.respondToRegisterRequest({
+ deviceData: 'this is data from the device',
});
+ const registeredMessage = this.container.find('p');
+ return expect(registeredMessage.text()).toContain('Your device was successfully set up!');
});
});
-}).call(window);
+});
diff --git a/spec/lib/gitlab/file_detector_spec.rb b/spec/lib/gitlab/file_detector_spec.rb
index 695fd6f8573..8e524f9b05a 100644
--- a/spec/lib/gitlab/file_detector_spec.rb
+++ b/spec/lib/gitlab/file_detector_spec.rb
@@ -18,6 +18,10 @@ describe Gitlab::FileDetector do
expect(described_class.type_of('README.md')).to eq(:readme)
end
+ it 'returns nil for a README file in a directory' do
+ expect(described_class.type_of('foo/README.md')).to be_nil
+ end
+
it 'returns the type of a changelog file' do
%w(CHANGELOG HISTORY CHANGES NEWS).each do |file|
expect(described_class.type_of(file)).to eq(:changelog)
@@ -52,6 +56,14 @@ describe Gitlab::FileDetector do
end
end
+ it 'returns the type of an issue template' do
+ expect(described_class.type_of('.gitlab/issue_templates/foo.md')).to eq(:issue_template)
+ end
+
+ it 'returns the type of a merge request template' do
+ expect(described_class.type_of('.gitlab/merge_request_templates/foo.md')).to eq(:merge_request_template)
+ end
+
it 'returns nil for an unknown file' do
expect(described_class.type_of('foo.txt')).to be_nil
end
diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb
index 1ee4acfd193..b11fa38856b 100644
--- a/spec/lib/gitlab/git/repository_spec.rb
+++ b/spec/lib/gitlab/git/repository_spec.rb
@@ -68,31 +68,52 @@ describe Gitlab::Git::Repository, seed_helper: true do
expect { broken_repo.rugged }.to raise_error(Gitlab::Git::Repository::NoRepository)
end
- context 'with no Git env stored' do
- before do
- expect(Gitlab::Git::Env).to receive(:all).and_return({})
+ describe 'alternates keyword argument' do
+ context 'with no Git env stored' do
+ before do
+ allow(Gitlab::Git::Env).to receive(:all).and_return({})
+ end
+
+ it "is passed an empty array" do
+ expect(Rugged::Repository).to receive(:new).with(repository.path, alternates: [])
+
+ repository.rugged
+ end
end
- it "whitelist some variables and pass them via the alternates keyword argument" do
- expect(Rugged::Repository).to receive(:new).with(repository.path, alternates: [])
+ context 'with absolute and relative Git object dir envvars stored' do
+ before do
+ allow(Gitlab::Git::Env).to receive(:all).and_return({
+ 'GIT_OBJECT_DIRECTORY_RELATIVE' => './objects/foo',
+ 'GIT_ALTERNATE_OBJECT_DIRECTORIES_RELATIVE' => ['./objects/bar', './objects/baz'],
+ 'GIT_OBJECT_DIRECTORY' => 'ignored',
+ 'GIT_ALTERNATE_OBJECT_DIRECTORIES' => %w[ignored ignored],
+ 'GIT_OTHER' => 'another_env'
+ })
+ end
- repository.rugged
- end
- end
+ it "is passed the relative object dir envvars after being converted to absolute ones" do
+ alternates = %w[foo bar baz].map { |d| File.join(repository.path, './objects', d) }
+ expect(Rugged::Repository).to receive(:new).with(repository.path, alternates: alternates)
- context 'with some Git env stored' do
- before do
- expect(Gitlab::Git::Env).to receive(:all).and_return({
- 'GIT_OBJECT_DIRECTORY' => 'foo',
- 'GIT_ALTERNATE_OBJECT_DIRECTORIES' => 'bar',
- 'GIT_OTHER' => 'another_env'
- })
+ repository.rugged
+ end
end
- it "whitelist some variables and pass them via the alternates keyword argument" do
- expect(Rugged::Repository).to receive(:new).with(repository.path, alternates: %w[foo bar])
+ context 'with only absolute Git object dir envvars stored' do
+ before do
+ allow(Gitlab::Git::Env).to receive(:all).and_return({
+ 'GIT_OBJECT_DIRECTORY' => 'foo',
+ 'GIT_ALTERNATE_OBJECT_DIRECTORIES' => %w[bar baz],
+ 'GIT_OTHER' => 'another_env'
+ })
+ end
- repository.rugged
+ it "is passed the absolute object dir envvars as is" do
+ expect(Rugged::Repository).to receive(:new).with(repository.path, alternates: %w[foo bar baz])
+
+ repository.rugged
+ end
end
end
end
@@ -1489,6 +1510,21 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
end
+ describe '#fetch' do
+ let(:git_path) { Gitlab.config.git.bin_path }
+ let(:remote_name) { 'my_remote' }
+
+ subject { repository.fetch(remote_name) }
+
+ it 'fetches the remote and returns true if the command was successful' do
+ expect(repository).to receive(:popen)
+ .with(%W(#{git_path} fetch #{remote_name}), repository.path)
+ .and_return(['', 0])
+
+ expect(subject).to be(true)
+ end
+ end
+
def create_remote_branch(repository, remote_name, branch_name, source_branch_name)
source_branch = repository.branches.find { |branch| branch.name == source_branch_name }
rugged = repository.rugged
diff --git a/spec/lib/gitlab/gitaly_client/repository_service_spec.rb b/spec/lib/gitlab/gitaly_client/repository_service_spec.rb
index fd5f984601e..cbc7ce1c1b0 100644
--- a/spec/lib/gitlab/gitaly_client/repository_service_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/repository_service_spec.rb
@@ -73,4 +73,15 @@ describe Gitlab::GitalyClient::RepositoryService do
client.apply_gitattributes(revision)
end
end
+
+ describe '#has_local_branches?' do
+ it 'sends a has_local_branches message' do
+ expect_any_instance_of(Gitaly::RepositoryService::Stub)
+ .to receive(:has_local_branches)
+ .with(gitaly_request_with_path(storage_name, relative_path), kind_of(Hash))
+ .and_return(double(value: true))
+
+ expect(client.has_local_branches?).to be(true)
+ end
+ end
end
diff --git a/spec/lib/gitlab/gitaly_client/util_spec.rb b/spec/lib/gitlab/gitaly_client/util_spec.rb
index 498f6886bee..c0c29552494 100644
--- a/spec/lib/gitlab/gitaly_client/util_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/util_spec.rb
@@ -6,16 +6,16 @@ describe Gitlab::GitalyClient::Util do
let(:relative_path) { 'my/repo.git' }
let(:gl_repository) { 'project-1' }
let(:git_object_directory) { '.git/objects' }
- let(:git_alternate_object_directory) { '/dir/one:/dir/two' }
+ let(:git_alternate_object_directory) { ['/dir/one', '/dir/two'] }
subject do
described_class.repository(repository_storage, relative_path, gl_repository)
end
it 'creates a Gitaly::Repository with the given data' do
- expect(Gitlab::Git::Env).to receive(:[]).with('GIT_OBJECT_DIRECTORY')
+ allow(Gitlab::Git::Env).to receive(:[]).with('GIT_OBJECT_DIRECTORY_RELATIVE')
.and_return(git_object_directory)
- expect(Gitlab::Git::Env).to receive(:[]).with('GIT_ALTERNATE_OBJECT_DIRECTORIES')
+ allow(Gitlab::Git::Env).to receive(:[]).with('GIT_ALTERNATE_OBJECT_DIRECTORIES_RELATIVE')
.and_return(git_alternate_object_directory)
expect(subject).to be_a(Gitaly::Repository)
@@ -23,7 +23,7 @@ describe Gitlab::GitalyClient::Util do
expect(subject.relative_path).to eq(relative_path)
expect(subject.gl_repository).to eq(gl_repository)
expect(subject.git_object_directory).to eq(git_object_directory)
- expect(subject.git_alternate_object_directories).to eq([git_alternate_object_directory])
+ expect(subject.git_alternate_object_directories).to eq(git_alternate_object_directory)
end
end
diff --git a/spec/lib/gitlab/import_export/project.group.json b/spec/lib/gitlab/import_export/project.group.json
new file mode 100644
index 00000000000..82a1fbd2fc5
--- /dev/null
+++ b/spec/lib/gitlab/import_export/project.group.json
@@ -0,0 +1,188 @@
+{
+ "description": "Nisi et repellendus ut enim quo accusamus vel magnam.",
+ "visibility_level": 10,
+ "archived": false,
+ "milestones": [
+ {
+ "id": 1,
+ "title": "Project milestone",
+ "project_id": 8,
+ "description": "Project-level milestone",
+ "due_date": null,
+ "created_at": "2016-06-14T15:02:04.415Z",
+ "updated_at": "2016-06-14T15:02:04.415Z",
+ "state": "active",
+ "iid": 1,
+ "group_id": null
+ }
+ ],
+ "labels": [
+ {
+ "id": 2,
+ "title": "project label",
+ "color": "#428bca",
+ "project_id": 8,
+ "created_at": "2016-07-22T08:55:44.161Z",
+ "updated_at": "2016-07-22T08:55:44.161Z",
+ "template": false,
+ "description": "",
+ "type": "ProjectLabel",
+ "priorities": [
+ {
+ "id": 1,
+ "project_id": 5,
+ "label_id": 1,
+ "priority": 1,
+ "created_at": "2016-10-18T09:35:43.338Z",
+ "updated_at": "2016-10-18T09:35:43.338Z"
+ }
+ ]
+ }
+ ],
+ "issues": [
+ {
+ "id": 1,
+ "title": "Fugiat est minima quae maxime non similique.",
+ "assignee_id": null,
+ "project_id": 8,
+ "author_id": 1,
+ "created_at": "2017-07-07T18:13:01.138Z",
+ "updated_at": "2017-08-15T18:37:40.807Z",
+ "branch_name": null,
+ "description": "Quam totam fuga numquam in eveniet.",
+ "state": "opened",
+ "iid": 1,
+ "updated_by_id": 1,
+ "confidential": false,
+ "deleted_at": null,
+ "due_date": null,
+ "moved_to_id": null,
+ "lock_version": null,
+ "time_estimate": 0,
+ "closed_at": null,
+ "last_edited_at": null,
+ "last_edited_by_id": null,
+ "group_milestone_id": null,
+ "milestone": {
+ "id": 1,
+ "title": "Project milestone",
+ "project_id": 8,
+ "description": "Project-level milestone",
+ "due_date": null,
+ "created_at": "2016-06-14T15:02:04.415Z",
+ "updated_at": "2016-06-14T15:02:04.415Z",
+ "state": "active",
+ "iid": 1,
+ "group_id": null
+ },
+ "label_links": [
+ {
+ "id": 11,
+ "label_id": 6,
+ "target_id": 1,
+ "target_type": "Issue",
+ "created_at": "2017-08-15T18:37:40.795Z",
+ "updated_at": "2017-08-15T18:37:40.795Z",
+ "label": {
+ "id": 6,
+ "title": "group label",
+ "color": "#A8D695",
+ "project_id": null,
+ "created_at": "2017-08-15T18:37:19.698Z",
+ "updated_at": "2017-08-15T18:37:19.698Z",
+ "template": false,
+ "description": "",
+ "group_id": 5,
+ "type": "GroupLabel",
+ "priorities": []
+ }
+ },
+ {
+ "id": 11,
+ "label_id": 2,
+ "target_id": 1,
+ "target_type": "Issue",
+ "created_at": "2017-08-15T18:37:40.795Z",
+ "updated_at": "2017-08-15T18:37:40.795Z",
+ "label": {
+ "id": 6,
+ "title": "project label",
+ "color": "#A8D695",
+ "project_id": null,
+ "created_at": "2017-08-15T18:37:19.698Z",
+ "updated_at": "2017-08-15T18:37:19.698Z",
+ "template": false,
+ "description": "",
+ "group_id": 5,
+ "type": "ProjectLabel",
+ "priorities": []
+ }
+ }
+ ]
+ },
+ {
+ "id": 2,
+ "title": "Fugiat est minima quae maxime non similique.",
+ "assignee_id": null,
+ "project_id": 8,
+ "author_id": 1,
+ "created_at": "2017-07-07T18:13:01.138Z",
+ "updated_at": "2017-08-15T18:37:40.807Z",
+ "branch_name": null,
+ "description": "Quam totam fuga numquam in eveniet.",
+ "state": "opened",
+ "iid": 2,
+ "updated_by_id": 1,
+ "confidential": false,
+ "deleted_at": null,
+ "due_date": null,
+ "moved_to_id": null,
+ "lock_version": null,
+ "time_estimate": 0,
+ "closed_at": null,
+ "last_edited_at": null,
+ "last_edited_by_id": null,
+ "group_milestone_id": null,
+ "milestone": {
+ "id": 2,
+ "title": "A group milestone",
+ "description": "Group-level milestone",
+ "due_date": null,
+ "created_at": "2016-06-14T15:02:04.415Z",
+ "updated_at": "2016-06-14T15:02:04.415Z",
+ "state": "active",
+ "iid": 1,
+ "group_id": 100
+ },
+ "label_links": [
+ {
+ "id": 11,
+ "label_id": 2,
+ "target_id": 1,
+ "target_type": "Issue",
+ "created_at": "2017-08-15T18:37:40.795Z",
+ "updated_at": "2017-08-15T18:37:40.795Z",
+ "label": {
+ "id": 2,
+ "title": "project label",
+ "color": "#A8D695",
+ "project_id": null,
+ "created_at": "2017-08-15T18:37:19.698Z",
+ "updated_at": "2017-08-15T18:37:19.698Z",
+ "template": false,
+ "description": "",
+ "group_id": 5,
+ "type": "ProjectLabel",
+ "priorities": []
+ }
+ }
+ ]
+ }
+ ],
+ "snippets": [
+
+ ],
+ "hooks": [
+
+ ]
+}
diff --git a/spec/lib/gitlab/import_export/project.light.json b/spec/lib/gitlab/import_export/project.light.json
index 2d8f3d4a566..02450478a77 100644
--- a/spec/lib/gitlab/import_export/project.light.json
+++ b/spec/lib/gitlab/import_export/project.light.json
@@ -5,9 +5,9 @@
"milestones": [
{
"id": 1,
- "title": "test milestone",
+ "title": "Project milestone",
"project_id": 8,
- "description": "test milestone",
+ "description": "Project-level milestone",
"due_date": null,
"created_at": "2016-06-14T15:02:04.415Z",
"updated_at": "2016-06-14T15:02:04.415Z",
@@ -19,7 +19,7 @@
"labels": [
{
"id": 2,
- "title": "test2",
+ "title": "A project label",
"color": "#428bca",
"project_id": 8,
"created_at": "2016-07-22T08:55:44.161Z",
@@ -63,28 +63,19 @@
"last_edited_at": null,
"last_edited_by_id": null,
"group_milestone_id": null,
+ "milestone": {
+ "id": 1,
+ "title": "Project milestone",
+ "project_id": 8,
+ "description": "Project-level milestone",
+ "due_date": null,
+ "created_at": "2016-06-14T15:02:04.415Z",
+ "updated_at": "2016-06-14T15:02:04.415Z",
+ "state": "active",
+ "iid": 1,
+ "group_id": null
+ },
"label_links": [
- {
- "id": 11,
- "label_id": 6,
- "target_id": 1,
- "target_type": "Issue",
- "created_at": "2017-08-15T18:37:40.795Z",
- "updated_at": "2017-08-15T18:37:40.795Z",
- "label": {
- "id": 6,
- "title": "group label",
- "color": "#A8D695",
- "project_id": null,
- "created_at": "2017-08-15T18:37:19.698Z",
- "updated_at": "2017-08-15T18:37:19.698Z",
- "template": false,
- "description": "",
- "group_id": 5,
- "type": "GroupLabel",
- "priorities": []
- }
- },
{
"id": 11,
"label_id": 2,
@@ -94,14 +85,14 @@
"updated_at": "2017-08-15T18:37:40.795Z",
"label": {
"id": 6,
- "title": "project label",
+ "title": "Another project label",
"color": "#A8D695",
"project_id": null,
"created_at": "2017-08-15T18:37:19.698Z",
"updated_at": "2017-08-15T18:37:19.698Z",
"template": false,
"description": "",
- "group_id": 5,
+ "group_id": null,
"type": "ProjectLabel",
"priorities": []
}
@@ -109,10 +100,6 @@
]
}
],
- "snippets": [
-
- ],
- "hooks": [
-
- ]
+ "snippets": [],
+ "hooks": []
}
diff --git a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
index efe11ca794a..4301eee17dc 100644
--- a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
@@ -24,7 +24,7 @@ describe Gitlab::ImportExport::ProjectTreeRestorer do
context 'JSON' do
it 'restores models based on JSON' do
- expect(@restored_project_json).to be true
+ expect(@restored_project_json).to be_truthy
end
it 'restore correct project features' do
@@ -182,6 +182,53 @@ describe Gitlab::ImportExport::ProjectTreeRestorer do
end
end
+ shared_examples 'restores project successfully' do
+ it 'correctly restores project' do
+ expect(shared.errors).to be_empty
+ expect(restored_project_json).to be_truthy
+ end
+ end
+
+ shared_examples 'restores project correctly' do |**results|
+ it 'has labels' do
+ expect(project.labels.size).to eq(results.fetch(:labels, 0))
+ end
+
+ it 'has label priorities' do
+ expect(project.labels.first.priorities).not_to be_empty
+ end
+
+ it 'has milestones' do
+ expect(project.milestones.size).to eq(results.fetch(:milestones, 0))
+ end
+
+ it 'has issues' do
+ expect(project.issues.size).to eq(results.fetch(:issues, 0))
+ end
+
+ it 'has issue with group label and project label' do
+ labels = project.issues.first.labels
+
+ expect(labels.where(type: "ProjectLabel").count).to eq(results.fetch(:first_issue_labels, 0))
+ end
+ end
+
+ shared_examples 'restores group correctly' do |**results|
+ it 'has group label' do
+ expect(project.group.labels.size).to eq(results.fetch(:labels, 0))
+ end
+
+ it 'has group milestone' do
+ expect(project.group.milestones.size).to eq(results.fetch(:milestones, 0))
+ end
+
+ it 'has issue with group label' do
+ labels = project.issues.first.labels
+
+ expect(labels.where(type: "GroupLabel").count).to eq(results.fetch(:first_issue_labels, 0))
+ end
+ end
+
context 'Light JSON' do
let(:user) { create(:user) }
let(:shared) { Gitlab::ImportExport::Shared.new(relative_path: "", project_path: 'path') }
@@ -190,33 +237,45 @@ describe Gitlab::ImportExport::ProjectTreeRestorer do
let(:restored_project_json) { project_tree_restorer.restore }
before do
- project_tree_restorer.instance_variable_set(:@path, "spec/lib/gitlab/import_export/project.light.json")
-
allow(shared).to receive(:export_path).and_return('spec/lib/gitlab/import_export/')
end
- context 'project.json file access check' do
- it 'does not read a symlink' do
- Dir.mktmpdir do |tmpdir|
- setup_symlink(tmpdir, 'project.json')
- allow(shared).to receive(:export_path).and_call_original
+ context 'with a simple project' do
+ before do
+ project_tree_restorer.instance_variable_set(:@path, "spec/lib/gitlab/import_export/project.light.json")
- restored_project_json
+ restored_project_json
+ end
- expect(shared.errors.first).to be_nil
+ it_behaves_like 'restores project correctly',
+ issues: 1,
+ labels: 1,
+ milestones: 1,
+ first_issue_labels: 1
+
+ context 'project.json file access check' do
+ it 'does not read a symlink' do
+ Dir.mktmpdir do |tmpdir|
+ setup_symlink(tmpdir, 'project.json')
+ allow(shared).to receive(:export_path).and_call_original
+
+ restored_project_json
+
+ expect(shared.errors).to be_empty
+ end
end
end
- end
- context 'when there is an existing build with build token' do
- it 'restores project json correctly' do
- create(:ci_build, token: 'abcd')
+ context 'when there is an existing build with build token' do
+ before do
+ create(:ci_build, token: 'abcd')
+ end
- expect(restored_project_json).to be true
+ it_behaves_like 'restores project successfully'
end
end
- context 'with group' do
+ context 'with a project that has a group' do
let!(:project) do
create(:project,
:builds_disabled,
@@ -227,43 +286,22 @@ describe Gitlab::ImportExport::ProjectTreeRestorer do
end
before do
- project_tree_restorer.instance_variable_set(:@path, "spec/lib/gitlab/import_export/project.light.json")
+ project_tree_restorer.instance_variable_set(:@path, "spec/lib/gitlab/import_export/project.group.json")
restored_project_json
end
- it 'correctly restores project' do
- expect(restored_project_json).to be_truthy
- expect(shared.errors).to be_empty
- end
+ it_behaves_like 'restores project successfully'
+ it_behaves_like 'restores project correctly',
+ issues: 2,
+ labels: 1,
+ milestones: 1,
+ first_issue_labels: 1
- it 'has labels' do
- expect(project.labels.count).to eq(2)
- end
-
- it 'creates group label' do
- expect(project.group.labels.count).to eq(1)
- end
-
- it 'has label priorities' do
- expect(project.labels.first.priorities).not_to be_empty
- end
-
- it 'has milestones' do
- expect(project.milestones.count).to eq(1)
- end
-
- it 'has issue' do
- expect(project.issues.count).to eq(1)
- expect(project.issues.first.labels.count).to eq(2)
- end
-
- it 'has issue with group label and project label' do
- labels = project.issues.first.labels
-
- expect(labels.where(type: "GroupLabel").count).to eq(1)
- expect(labels.where(type: "ProjectLabel").count).to eq(1)
- end
+ it_behaves_like 'restores group correctly',
+ labels: 1,
+ milestones: 1,
+ first_issue_labels: 1
end
end
end
diff --git a/spec/lib/gitlab/project_template_spec.rb b/spec/lib/gitlab/project_template_spec.rb
index d19bd611919..57b0ef8d1ad 100644
--- a/spec/lib/gitlab/project_template_spec.rb
+++ b/spec/lib/gitlab/project_template_spec.rb
@@ -4,9 +4,9 @@ describe Gitlab::ProjectTemplate do
describe '.all' do
it 'returns a all templates' do
expected = [
- described_class.new('rails', 'Ruby on Rails'),
- described_class.new('spring', 'Spring'),
- described_class.new('express', 'NodeJS Express')
+ described_class.new('rails', 'Ruby on Rails', 'Includes an MVC structure, .gitignore, Gemfile, and more great stuff', 'https://gitlab.com/gitlab-org/project-templates/rails'),
+ described_class.new('spring', 'Spring', 'Includes an MVC structure, .gitignore, Gemfile, and more great stuff', 'https://gitlab.com/gitlab-org/project-templates/spring'),
+ described_class.new('express', 'NodeJS Express', 'Includes an MVC structure, .gitignore, Gemfile, and more great stuff', 'https://gitlab.com/gitlab-org/project-templates/express')
]
expect(described_class.all).to be_an(Array)
@@ -31,7 +31,7 @@ describe Gitlab::ProjectTemplate do
end
describe 'instance methods' do
- subject { described_class.new('phoenix', 'Phoenix Framework') }
+ subject { described_class.new('phoenix', 'Phoenix Framework', 'Phoenix description', 'link-to-template') }
it { is_expected.to respond_to(:logo, :file, :archive_path) }
end
diff --git a/spec/lib/gitlab/workhorse_spec.rb b/spec/lib/gitlab/workhorse_spec.rb
index 9230d58012f..80bf7986ee0 100644
--- a/spec/lib/gitlab/workhorse_spec.rb
+++ b/spec/lib/gitlab/workhorse_spec.rb
@@ -66,12 +66,34 @@ describe Gitlab::Workhorse do
let(:diff_refs) { double(base_sha: "base", head_sha: "head") }
subject { described_class.send_git_patch(repository, diff_refs) }
- it 'sets the header correctly' do
- key, command, params = decode_workhorse_header(subject)
+ context 'when Gitaly workhorse_send_git_patch feature is enabled' do
+ it 'sets the header correctly' do
+ key, command, params = decode_workhorse_header(subject)
- expect(key).to eq("Gitlab-Workhorse-Send-Data")
- expect(command).to eq("git-format-patch")
- expect(params).to eq("RepoPath" => repository.path_to_repo, "ShaFrom" => "base", "ShaTo" => "head")
+ expect(key).to eq("Gitlab-Workhorse-Send-Data")
+ expect(command).to eq("git-format-patch")
+ expect(params).to eq({
+ 'GitalyServer' => {
+ address: Gitlab::GitalyClient.address(project.repository_storage),
+ token: Gitlab::GitalyClient.token(project.repository_storage)
+ },
+ 'RawPatchRequest' => Gitaly::RawPatchRequest.new(
+ repository: repository.gitaly_repository,
+ left_commit_id: 'base',
+ right_commit_id: 'head'
+ ).to_json
+ }.deep_stringify_keys)
+ end
+ end
+
+ context 'when Gitaly workhorse_send_git_patch feature is disabled', :skip_gitaly_mock do
+ it 'sets the header correctly' do
+ key, command, params = decode_workhorse_header(subject)
+
+ expect(key).to eq("Gitlab-Workhorse-Send-Data")
+ expect(command).to eq("git-format-patch")
+ expect(params).to eq("RepoPath" => repository.path_to_repo, "ShaFrom" => "base", "ShaTo" => "head")
+ end
end
end
@@ -115,14 +137,36 @@ describe Gitlab::Workhorse do
describe '.send_git_diff' do
let(:diff_refs) { double(base_sha: "base", head_sha: "head") }
- subject { described_class.send_git_patch(repository, diff_refs) }
+ subject { described_class.send_git_diff(repository, diff_refs) }
- it 'sets the header correctly' do
- key, command, params = decode_workhorse_header(subject)
+ context 'when Gitaly workhorse_send_git_diff feature is enabled' do
+ it 'sets the header correctly' do
+ key, command, params = decode_workhorse_header(subject)
- expect(key).to eq("Gitlab-Workhorse-Send-Data")
- expect(command).to eq("git-format-patch")
- expect(params).to eq("RepoPath" => repository.path_to_repo, "ShaFrom" => "base", "ShaTo" => "head")
+ expect(key).to eq("Gitlab-Workhorse-Send-Data")
+ expect(command).to eq("git-diff")
+ expect(params).to eq({
+ 'GitalyServer' => {
+ address: Gitlab::GitalyClient.address(project.repository_storage),
+ token: Gitlab::GitalyClient.token(project.repository_storage)
+ },
+ 'RawDiffRequest' => Gitaly::RawDiffRequest.new(
+ repository: repository.gitaly_repository,
+ left_commit_id: 'base',
+ right_commit_id: 'head'
+ ).to_json
+ }.deep_stringify_keys)
+ end
+ end
+
+ context 'when Gitaly workhorse_send_git_diff feature is disabled', :skip_gitaly_mock do
+ it 'sets the header correctly' do
+ key, command, params = decode_workhorse_header(subject)
+
+ expect(key).to eq("Gitlab-Workhorse-Send-Data")
+ expect(command).to eq("git-diff")
+ expect(params).to eq("RepoPath" => repository.path_to_repo, "ShaFrom" => "base", "ShaTo" => "head")
+ end
end
end
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index a26c71e5155..cf26dbfea49 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -874,7 +874,7 @@ describe Project do
let(:project) { create(:project) }
context 'when avatar file is uploaded' do
- let(:project) { create(:project, :with_avatar) }
+ let(:project) { create(:project, :public, :with_avatar) }
let(:avatar_path) { "/uploads/-/system/project/avatar/#{project.id}/dk.png" }
let(:gitlab_host) { "http://#{Gitlab.config.gitlab.host}" }
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb
index 5d78aed5b4f..f44693a71bb 100644
--- a/spec/models/repository_spec.rb
+++ b/spec/models/repository_spec.rb
@@ -1509,7 +1509,9 @@ describe Repository do
:gitignore,
:koding,
:gitlab_ci,
- :avatar
+ :avatar,
+ :issue_template,
+ :merge_request_template
])
repository.after_change_head
diff --git a/spec/requests/api/helpers_spec.rb b/spec/requests/api/helpers_spec.rb
index 862920ad7c3..9f3b5a809d7 100644
--- a/spec/requests/api/helpers_spec.rb
+++ b/spec/requests/api/helpers_spec.rb
@@ -222,13 +222,6 @@ describe API::Helpers do
expect { current_user }.to raise_error /401/
end
- it "returns a 401 response for a token without the appropriate scope" do
- personal_access_token = create(:personal_access_token, user: user, scopes: ['read_user'])
- env[API::APIGuard::PRIVATE_TOKEN_HEADER] = personal_access_token.token
-
- expect { current_user }.to raise_error /401/
- end
-
it "leaves user as is when sudo not specified" do
env[API::APIGuard::PRIVATE_TOKEN_HEADER] = personal_access_token.token
expect(current_user).to eq(user)
@@ -238,18 +231,25 @@ describe API::Helpers do
expect(current_user).to eq(user)
end
+ it "does not allow tokens without the appropriate scope" do
+ personal_access_token = create(:personal_access_token, user: user, scopes: ['read_user'])
+ env[API::APIGuard::PRIVATE_TOKEN_HEADER] = personal_access_token.token
+
+ expect { current_user }.to raise_error API::APIGuard::InsufficientScopeError
+ end
+
it 'does not allow revoked tokens' do
personal_access_token.revoke!
env[API::APIGuard::PRIVATE_TOKEN_HEADER] = personal_access_token.token
- expect { current_user }.to raise_error /401/
+ expect { current_user }.to raise_error API::APIGuard::RevokedError
end
it 'does not allow expired tokens' do
personal_access_token.update_attributes!(expires_at: 1.day.ago)
env[API::APIGuard::PRIVATE_TOKEN_HEADER] = personal_access_token.token
- expect { current_user }.to raise_error /401/
+ expect { current_user }.to raise_error API::APIGuard::ExpiredError
end
end
diff --git a/spec/rubocop/cop/migration/datetime_spec.rb b/spec/rubocop/cop/migration/datetime_spec.rb
index 388b086ce6a..b1dfcf1b048 100644
--- a/spec/rubocop/cop/migration/datetime_spec.rb
+++ b/spec/rubocop/cop/migration/datetime_spec.rb
@@ -9,6 +9,7 @@ describe RuboCop::Cop::Migration::Datetime do
include CopHelper
subject(:cop) { described_class.new }
+
let(:migration_with_datetime) do
%q(
class Users < ActiveRecord::Migration
@@ -22,6 +23,19 @@ describe RuboCop::Cop::Migration::Datetime do
)
end
+ let(:migration_with_timestamp) do
+ %q(
+ class Users < ActiveRecord::Migration
+ DOWNTIME = false
+
+ def change
+ add_column(:users, :username, :text)
+ add_column(:users, :last_sign_in, :timestamp)
+ end
+ end
+ )
+ end
+
let(:migration_without_datetime) do
%q(
class Users < ActiveRecord::Migration
@@ -58,6 +72,17 @@ describe RuboCop::Cop::Migration::Datetime do
aggregate_failures do
expect(cop.offenses.size).to eq(1)
expect(cop.offenses.map(&:line)).to eq([7])
+ expect(cop.offenses.first.message).to include('datetime')
+ end
+ end
+
+ it 'registers an offense when the ":timestamp" data type is used' do
+ inspect_source(cop, migration_with_timestamp)
+
+ aggregate_failures do
+ expect(cop.offenses.size).to eq(1)
+ expect(cop.offenses.map(&:line)).to eq([7])
+ expect(cop.offenses.first.message).to include('timestamp')
end
end
@@ -81,6 +106,7 @@ describe RuboCop::Cop::Migration::Datetime do
context 'outside of migration' do
it 'registers no offense' do
inspect_source(cop, migration_with_datetime)
+ inspect_source(cop, migration_with_timestamp)
inspect_source(cop, migration_without_datetime)
inspect_source(cop, migration_with_datetime_with_timezone)
diff --git a/spec/serializers/merge_request_entity_spec.rb b/spec/serializers/merge_request_entity_spec.rb
index 4aeb593da44..87832b3dca1 100644
--- a/spec/serializers/merge_request_entity_spec.rb
+++ b/spec/serializers/merge_request_entity_spec.rb
@@ -1,7 +1,7 @@
require 'spec_helper'
describe MergeRequestEntity do
- let(:project) { create :project }
+ let(:project) { create :project, :repository }
let(:resource) { create(:merge_request, source_project: project, target_project: project) }
let(:user) { create(:user) }
diff --git a/spec/services/merge_requests/conflicts/resolve_service_spec.rb b/spec/services/merge_requests/conflicts/resolve_service_spec.rb
index 9c9b0c4c4a1..a1f7dc44d31 100644
--- a/spec/services/merge_requests/conflicts/resolve_service_spec.rb
+++ b/spec/services/merge_requests/conflicts/resolve_service_spec.rb
@@ -6,11 +6,7 @@ describe MergeRequests::Conflicts::ResolveService do
let(:project) { create(:project, :public, :repository) }
let(:forked_project) do
- forked_project = fork_project(project, user)
- TestEnv.copy_repo(forked_project,
- bare_repo: TestEnv.forked_repo_path_bare,
- refs: TestEnv::FORKED_BRANCH_SHA)
- forked_project
+ fork_project_with_submodules(project, user)
end
let(:merge_request) do
diff --git a/spec/services/merge_requests/merge_service_spec.rb b/spec/services/merge_requests/merge_service_spec.rb
index 80213d093f1..d1043f99b5a 100644
--- a/spec/services/merge_requests/merge_service_spec.rb
+++ b/spec/services/merge_requests/merge_service_spec.rb
@@ -185,7 +185,7 @@ describe MergeRequests::MergeService do
context 'source branch removal' do
context 'when the source branch is protected' do
let(:service) do
- described_class.new(project, user, should_remove_source_branch: '1')
+ described_class.new(project, user, 'should_remove_source_branch' => true)
end
before do
@@ -200,7 +200,7 @@ describe MergeRequests::MergeService do
context 'when the source branch is the default branch' do
let(:service) do
- described_class.new(project, user, should_remove_source_branch: '1')
+ described_class.new(project, user, 'should_remove_source_branch' => true)
end
before do
@@ -215,10 +215,10 @@ describe MergeRequests::MergeService do
context 'when the source branch can be removed' do
context 'when MR author set the source branch to be removed' do
- let(:service) do
- merge_request.merge_params['force_remove_source_branch'] = '1'
- merge_request.save!
- described_class.new(project, user, commit_message: 'Awesome message')
+ let(:service) { described_class.new(project, user, commit_message: 'Awesome message') }
+
+ before do
+ merge_request.update_attribute(:merge_params, { 'force_remove_source_branch' => '1' })
end
it 'removes the source branch using the author user' do
@@ -227,11 +227,20 @@ describe MergeRequests::MergeService do
.and_call_original
service.execute(merge_request)
end
+
+ context 'when the merger set the source branch not to be removed' do
+ let(:service) { described_class.new(project, user, commit_message: 'Awesome message', 'should_remove_source_branch' => false) }
+
+ it 'does not delete the source branch' do
+ expect(DeleteBranchService).not_to receive(:new)
+ service.execute(merge_request)
+ end
+ end
end
context 'when MR merger set the source branch to be removed' do
let(:service) do
- described_class.new(project, user, commit_message: 'Awesome message', should_remove_source_branch: '1')
+ described_class.new(project, user, commit_message: 'Awesome message', 'should_remove_source_branch' => true)
end
it 'removes the source branch using the current user' do
diff --git a/spec/services/merge_requests/update_service_spec.rb b/spec/services/merge_requests/update_service_spec.rb
index 7257c359a7e..98409be4236 100644
--- a/spec/services/merge_requests/update_service_spec.rb
+++ b/spec/services/merge_requests/update_service_spec.rb
@@ -127,10 +127,10 @@ describe MergeRequests::UpdateService, :mailer do
end
it 'creates system note about discussion lock' do
- note = find_note('locked this issue')
+ note = find_note('locked this merge request')
expect(note).not_to be_nil
- expect(note.note).to eq 'locked this issue'
+ expect(note.note).to eq 'locked this merge request'
end
context 'when not including source branch removal options' do
diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb
index b64ca5be8fc..b13e12e7c94 100644
--- a/spec/services/notification_service_spec.rb
+++ b/spec/services/notification_service_spec.rb
@@ -731,6 +731,18 @@ describe NotificationService, :mailer do
should_not_email(@u_participating)
end
+ it "doesn't send multiple email when a user is subscribed to multiple given labels" do
+ subscriber_to_both = create(:user) do |user|
+ [label_1, label_2].each { |label| label.toggle_subscription(user, project) }
+ end
+
+ notification.relabeled_issue(issue, [label_1, label_2], @u_disabled)
+
+ should_email(subscriber_to_label_1)
+ should_email(subscriber_to_label_2)
+ should_email(subscriber_to_both)
+ end
+
context 'confidential issues' do
let(:author) { create(:user) }
let(:assignee) { create(:user) }
diff --git a/spec/services/system_note_service_spec.rb b/spec/services/system_note_service_spec.rb
index b1241cd8d0b..cd473c1f388 100644
--- a/spec/services/system_note_service_spec.rb
+++ b/spec/services/system_note_service_spec.rb
@@ -1145,4 +1145,42 @@ describe SystemNoteService do
it { expect(subject.note).to eq "marked #{duplicate_issue.to_reference(project)} as a duplicate of this issue" }
end
end
+
+ describe '.discussion_lock' do
+ subject { described_class.discussion_lock(noteable, author) }
+
+ context 'discussion unlocked' do
+ it_behaves_like 'a system note' do
+ let(:action) { 'unlocked' }
+ end
+
+ it 'creates the note text correctly' do
+ [:issue, :merge_request].each do |type|
+ issuable = create(type)
+
+ expect(described_class.discussion_lock(issuable, author).note)
+ .to eq("unlocked this #{type.to_s.titleize.downcase}")
+ end
+ end
+ end
+
+ context 'discussion locked' do
+ before do
+ noteable.update_attribute(:discussion_locked, true)
+ end
+
+ it_behaves_like 'a system note' do
+ let(:action) { 'locked' }
+ end
+
+ it 'creates the note text correctly' do
+ [:issue, :merge_request].each do |type|
+ issuable = create(type, discussion_locked: true)
+
+ expect(described_class.discussion_lock(issuable, author).note)
+ .to eq("locked this #{type.to_s.titleize.downcase}")
+ end
+ end
+ end
+ end
end
diff --git a/spec/support/api/scopes/read_user_shared_examples.rb b/spec/support/api/scopes/read_user_shared_examples.rb
index 57e28e040d7..111534f2f26 100644
--- a/spec/support/api/scopes/read_user_shared_examples.rb
+++ b/spec/support/api/scopes/read_user_shared_examples.rb
@@ -27,10 +27,10 @@ shared_examples_for 'allows the "read_user" scope' do
stub_container_registry_config(enabled: true)
end
- it 'returns a "401" response' do
+ it 'returns a "403" response' do
get api_call.call(path, user, personal_access_token: token)
- expect(response).to have_http_status(401)
+ expect(response).to have_http_status(403)
end
end
end
@@ -74,10 +74,10 @@ shared_examples_for 'does not allow the "read_user" scope' do
context 'when the requesting token has the "read_user" scope' do
let(:token) { create(:personal_access_token, scopes: ['read_user'], user: user) }
- it 'returns a "401" response' do
+ it 'returns a "403" response' do
post api_call.call(path, user, personal_access_token: token), attributes_for(:user, projects_limit: 3)
- expect(response).to have_http_status(401)
+ expect(response).to have_http_status(403)
end
end
end
diff --git a/spec/support/email_helpers.rb b/spec/support/email_helpers.rb
index 3e979f2f470..b39052923dd 100644
--- a/spec/support/email_helpers.rb
+++ b/spec/support/email_helpers.rb
@@ -1,6 +1,6 @@
module EmailHelpers
- def sent_to_user?(user, recipients = email_recipients)
- recipients.include?(user.notification_email)
+ def sent_to_user(user, recipients: email_recipients)
+ recipients.count { |to| to == user.notification_email }
end
def reset_delivered_emails!
@@ -10,17 +10,17 @@ module EmailHelpers
def should_only_email(*users, kind: :to)
recipients = email_recipients(kind: kind)
- users.each { |user| should_email(user, recipients) }
+ users.each { |user| should_email(user, recipients: recipients) }
expect(recipients.count).to eq(users.count)
end
- def should_email(user, recipients = email_recipients)
- expect(sent_to_user?(user, recipients)).to be_truthy
+ def should_email(user, times: 1, recipients: email_recipients)
+ expect(sent_to_user(user, recipients: recipients)).to eq(times)
end
- def should_not_email(user, recipients = email_recipients)
- expect(sent_to_user?(user, recipients)).to be_falsey
+ def should_not_email(user, recipients: email_recipients)
+ should_email(user, times: 0, recipients: recipients)
end
def should_not_email_anyone
diff --git a/spec/support/project_forks_helper.rb b/spec/support/project_forks_helper.rb
index 0d1c6792d13..d6680735aa1 100644
--- a/spec/support/project_forks_helper.rb
+++ b/spec/support/project_forks_helper.rb
@@ -52,7 +52,7 @@ module ProjectForksHelper
TestEnv.copy_repo(forked_project,
bare_repo: TestEnv.forked_repo_path_bare,
refs: TestEnv::FORKED_BRANCH_SHA)
-
+ forked_project.repository.after_import
forked_project
end
end
diff --git a/spec/workers/repository_fork_worker_spec.rb b/spec/workers/repository_fork_worker_spec.rb
index d9e9409840f..e881ec37ae5 100644
--- a/spec/workers/repository_fork_worker_spec.rb
+++ b/spec/workers/repository_fork_worker_spec.rb
@@ -12,6 +12,28 @@ describe RepositoryForkWorker do
end
describe "#perform" do
+ describe 'when a worker was reset without cleanup' do
+ let(:jid) { '12345678' }
+ let(:started_project) { create(:project, :repository, :import_started) }
+
+ it 'creates a new repository from a fork' do
+ allow(subject).to receive(:jid).and_return(jid)
+
+ expect(shell).to receive(:fork_repository).with(
+ '/test/path',
+ project.full_path,
+ project.repository_storage_path,
+ fork_project.namespace.full_path
+ ).and_return(true)
+
+ subject.perform(
+ project.id,
+ '/test/path',
+ project.full_path,
+ fork_project.namespace.full_path)
+ end
+ end
+
it "creates a new repository from a fork" do
expect(shell).to receive(:fork_repository).with(
'/test/path',
diff --git a/spec/workers/repository_import_worker_spec.rb b/spec/workers/repository_import_worker_spec.rb
index 100dfc32bbe..5cff5108477 100644
--- a/spec/workers/repository_import_worker_spec.rb
+++ b/spec/workers/repository_import_worker_spec.rb
@@ -6,6 +6,23 @@ describe RepositoryImportWorker do
subject { described_class.new }
describe '#perform' do
+ context 'when worker was reset without cleanup' do
+ let(:jid) { '12345678' }
+ let(:started_project) { create(:project, :import_started, import_jid: jid) }
+
+ it 'imports the project successfully' do
+ allow(subject).to receive(:jid).and_return(jid)
+
+ expect_any_instance_of(Projects::ImportService).to receive(:execute)
+ .and_return({ status: :ok })
+
+ expect_any_instance_of(Repository).to receive(:expire_emptiness_caches)
+ expect_any_instance_of(Project).to receive(:import_finish)
+
+ subject.perform(project.id)
+ end
+ end
+
context 'when the import was successful' do
it 'imports a project' do
expect_any_instance_of(Projects::ImportService).to receive(:execute)
diff --git a/vendor/gitignore/Android.gitignore b/vendor/gitignore/Android.gitignore
index 520a86352f7..c79ba5080a3 100644
--- a/vendor/gitignore/Android.gitignore
+++ b/vendor/gitignore/Android.gitignore
@@ -41,7 +41,8 @@ captures/
.idea/libraries
# Keystore files
-*.jks
+# Uncomment the following line if you do not want to check your keystore files in.
+#*.jks
# External native build folder generated in Android Studio 2.2 and later
.externalNativeBuild
diff --git a/vendor/gitignore/Autotools.gitignore b/vendor/gitignore/Autotools.gitignore
index e3923f96fce..ffa6ecc3f9b 100644
--- a/vendor/gitignore/Autotools.gitignore
+++ b/vendor/gitignore/Autotools.gitignore
@@ -31,3 +31,12 @@ Makefile.in
# http://www.gnu.org/software/texinfo
/texinfo.tex
+
+# http://www.gnu.org/software/m4/
+
+m4/libtool.m4
+m4/ltoptions.m4
+m4/ltsugar.m4
+m4/ltversion.m4
+m4/lt~obsolete.m4
+autom4te.cache
diff --git a/vendor/gitignore/Elixir.gitignore b/vendor/gitignore/Elixir.gitignore
index ac67aaf3243..b6d65867dac 100644
--- a/vendor/gitignore/Elixir.gitignore
+++ b/vendor/gitignore/Elixir.gitignore
@@ -1,6 +1,8 @@
/_build
/cover
/deps
+/doc
+/.fetch
erl_crash.dump
*.ez
*.beam
diff --git a/vendor/gitignore/ExtJs.gitignore b/vendor/gitignore/ExtJs.gitignore
index c92aea0fe0c..ab97a8cc3e1 100644
--- a/vendor/gitignore/ExtJs.gitignore
+++ b/vendor/gitignore/ExtJs.gitignore
@@ -10,3 +10,5 @@ ext/
modern.json
modern.jsonp
resources/sass/.sass-cache/
+resources/.arch-internal-preview.css
+.arch-internal-preview.css
diff --git a/vendor/gitignore/Global/Matlab.gitignore b/vendor/gitignore/Global/Matlab.gitignore
index 09dfde64b5f..cca150a88dd 100644
--- a/vendor/gitignore/Global/Matlab.gitignore
+++ b/vendor/gitignore/Global/Matlab.gitignore
@@ -19,4 +19,4 @@ slprj/
octave-workspace
# Simulink autosave extension
-.autosave
+*.autosave
diff --git a/vendor/gitignore/Global/Xcode.gitignore b/vendor/gitignore/Global/Xcode.gitignore
index 37de8bb4793..cd0c7d3e45a 100644
--- a/vendor/gitignore/Global/Xcode.gitignore
+++ b/vendor/gitignore/Global/Xcode.gitignore
@@ -2,11 +2,17 @@
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
-## Build generated
+## User settings
+xcuserdata/
+
+## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
+*.xcscmblueprint
+*.xccheckout
+
+## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
build/
DerivedData/
-
-## Various settings
+*.moved-aside
*.pbxuser
!default.pbxuser
*.mode1v3
@@ -15,9 +21,3 @@ DerivedData/
!default.mode2v3
*.perspectivev3
!default.perspectivev3
-xcuserdata/
-
-## Other
-*.moved-aside
-*.xccheckout
-*.xcscmblueprint
diff --git a/vendor/gitignore/Global/macOS.gitignore b/vendor/gitignore/Global/macOS.gitignore
index 9d1061e8bc4..135767fc075 100644
--- a/vendor/gitignore/Global/macOS.gitignore
+++ b/vendor/gitignore/Global/macOS.gitignore
@@ -1,5 +1,5 @@
# General
-*.DS_Store
+.DS_Store
.AppleDouble
.LSOverride
diff --git a/vendor/gitignore/Joomla.gitignore b/vendor/gitignore/Joomla.gitignore
index 53a74e74657..b6bf3a9c96a 100644
--- a/vendor/gitignore/Joomla.gitignore
+++ b/vendor/gitignore/Joomla.gitignore
@@ -251,7 +251,7 @@
/administrator/language/en-GB/en-GB.tpl_hathor.sys.ini
/administrator/language/en-GB/en-GB.xml
/administrator/language/overrides/*
-/administrator/logs/index.html
+/administrator/logs/*
/administrator/manifests/*
/administrator/modules/mod_custom/*
/administrator/modules/mod_feed/*
diff --git a/vendor/gitignore/OCaml.gitignore b/vendor/gitignore/OCaml.gitignore
index f7817ae5c36..da0b20424a0 100644
--- a/vendor/gitignore/OCaml.gitignore
+++ b/vendor/gitignore/OCaml.gitignore
@@ -18,3 +18,6 @@ _build/
# oasis generated files
setup.data
setup.log
+
+# Merlin configuring file for Vim and Emacs
+.merlin
diff --git a/vendor/gitignore/Python.gitignore b/vendor/gitignore/Python.gitignore
index 113294a5f18..af2f537516d 100644
--- a/vendor/gitignore/Python.gitignore
+++ b/vendor/gitignore/Python.gitignore
@@ -23,6 +23,7 @@ wheels/
*.egg-info/
.installed.cfg
*.egg
+MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
@@ -51,6 +52,8 @@ coverage.xml
# Django stuff:
*.log
+.static_storage/
+.media/
local_settings.py
# Flask stuff:
@@ -84,6 +87,8 @@ celerybeat-schedule
env/
venv/
ENV/
+env.bak/
+venv.bak/
# Spyder project settings
.spyderproject
diff --git a/vendor/gitignore/Qt.gitignore b/vendor/gitignore/Qt.gitignore
index fe67fdf1ee6..037a1e75790 100644
--- a/vendor/gitignore/Qt.gitignore
+++ b/vendor/gitignore/Qt.gitignore
@@ -31,11 +31,9 @@ ui_*.h
Makefile*
*build-*
-
# Qt unit tests
target_wrapper.*
-
# QtCreator
*.autosave
diff --git a/vendor/gitignore/TeX.gitignore b/vendor/gitignore/TeX.gitignore
index a0322dbd35a..b6418e51766 100644
--- a/vendor/gitignore/TeX.gitignore
+++ b/vendor/gitignore/TeX.gitignore
@@ -13,6 +13,7 @@
## Intermediate documents:
*.dvi
+*.xdv
*-converted-to.*
# these rules might exclude image files for figures etc.
# *.ps
diff --git a/vendor/gitignore/Terraform.gitignore b/vendor/gitignore/Terraform.gitignore
index f20453be963..9b5aebb1b35 100644
--- a/vendor/gitignore/Terraform.gitignore
+++ b/vendor/gitignore/Terraform.gitignore
@@ -5,3 +5,6 @@
# Module directory
.terraform/
+
+# Variable values for development
+terraform.tfvars
diff --git a/vendor/gitignore/Umbraco.gitignore b/vendor/gitignore/Umbraco.gitignore
index ea05e1fb2a9..b6b0743f62a 100644
--- a/vendor/gitignore/Umbraco.gitignore
+++ b/vendor/gitignore/Umbraco.gitignore
@@ -1,3 +1,7 @@
+## Ignore Umbraco files/folders generated for each instance
+##
+## Get latest from https://github.com/github/gitignore/blob/master/Umbraco.gitignore
+
# Note: VisualStudio gitignore rules may also be relevant
# Umbraco
diff --git a/vendor/gitignore/VisualStudio.gitignore b/vendor/gitignore/VisualStudio.gitignore
index f652b45c2ee..0867ec5a7ee 100644
--- a/vendor/gitignore/VisualStudio.gitignore
+++ b/vendor/gitignore/VisualStudio.gitignore
@@ -96,6 +96,9 @@ ipch/
*.vspx
*.sap
+# Visual Studio Trace Files
+*.e2e
+
# TFS 2012 Local Workspace
$tf/
@@ -297,3 +300,6 @@ __pycache__/
*.btm.cs
*.odx.cs
*.xsd.cs
+
+# OpenCover UI analysis results
+OpenCover/
diff --git a/vendor/gitignore/ZendFramework.gitignore b/vendor/gitignore/ZendFramework.gitignore
index 80adb154900..f0b7d8585b7 100644
--- a/vendor/gitignore/ZendFramework.gitignore
+++ b/vendor/gitignore/ZendFramework.gitignore
@@ -19,7 +19,6 @@ temp/
data/DoctrineORMModule/Proxy/
data/DoctrineORMModule/cache/
-
# Legacy ZF1
demos/
extras/documentation
diff --git a/vendor/gitlab-ci-yml/Go.gitlab-ci.yml b/vendor/gitlab-ci-yml/Go.gitlab-ci.yml
index 8a214352d2a..86e4985d8d2 100644
--- a/vendor/gitlab-ci-yml/Go.gitlab-ci.yml
+++ b/vendor/gitlab-ci-yml/Go.gitlab-ci.yml
@@ -29,7 +29,7 @@ format:
compile:
stage: build
script:
- - go build -race -ldflags "-extldflags '-static'" -o mybinary
+ - go build -race -ldflags "-extldflags '-static'" -o $CI_PROJECT_DIR/mybinary
artifacts:
paths:
- mybinary
diff --git a/vendor/gitlab-ci-yml/Maven.gitlab-ci.yml b/vendor/gitlab-ci-yml/Maven.gitlab-ci.yml
index 91b096654d1..ba2efbd03a0 100644
--- a/vendor/gitlab-ci-yml/Maven.gitlab-ci.yml
+++ b/vendor/gitlab-ci-yml/Maven.gitlab-ci.yml
@@ -7,8 +7,8 @@
# This template will build and test your projects as well as create the documentation.
#
# * Caches downloaded dependencies and plugins between invocation.
-# * Does only verify merge requests but deploy built artifacts of the
-# master branch.
+# * Verify but don't deploy merge requests.
+# * Deploy built artifacts from master branch only.
# * Shows how to use multiple jobs in test stage for verifying functionality
# with multiple JDKs.
# * Uses site:stage to collect the documentation for multi-module projects.
@@ -20,7 +20,7 @@ variables:
MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true"
# As of Maven 3.3.0 instead of this you may define these options in `.mvn/maven.config` so the same config is used
# when running from the command line.
- # `installAtEnd` and `deployAtEnd`are only effective with recent version of the corresponding plugins.
+ # `installAtEnd` and `deployAtEnd` are only effective with recent version of the corresponding plugins.
MAVEN_CLI_OPTS: "--batch-mode --errors --fail-at-end --show-version -DinstallAtEnd=true -DdeployAtEnd=true"
# Cache downloaded dependencies and plugins between builds.
@@ -100,4 +100,3 @@ pages:
- public
only:
- master
-
diff --git a/vendor/gitlab-ci-yml/Python.gitlab-ci.yml b/vendor/gitlab-ci-yml/Python.gitlab-ci.yml
new file mode 100644
index 00000000000..a2882a5407d
--- /dev/null
+++ b/vendor/gitlab-ci-yml/Python.gitlab-ci.yml
@@ -0,0 +1,32 @@
+# This file is a template, and might need editing before it works on your project.
+image: python:latest
+
+before_script:
+ - python -V # Print out python version for debugging
+
+test:
+ script:
+ - python setup.py test
+ - pip install tox flake8 # you can also use tox
+ - tox -e py36,flake8
+
+run:
+ script:
+ - python setup.py bdist_wheel
+ # an alternative approach is to install and run:
+ - pip install dist/*
+ # run the command here
+ artifacts:
+ paths:
+ - dist/*.whl
+
+pages:
+ script:
+ - pip install sphinx sphinx-rtd-theme
+ - cd doc ; make html
+ - mv build/html/ ../public/
+ artifacts:
+ paths:
+ - public
+ only:
+ - master
diff --git a/vendor/licenses.csv b/vendor/licenses.csv
index 24623ff4c1f..9f78059986d 100644
--- a/vendor/licenses.csv
+++ b/vendor/licenses.csv
@@ -13,9 +13,9 @@ activemodel,4.2.8,MIT
activerecord,4.2.8,MIT
activesupport,4.2.8,MIT
acts-as-taggable-on,4.0.0,MIT
-addressable,2.3.8,Apache 2.0
+addressable,2.5.2,Apache 2.0
after,0.8.2,MIT
-ajv,5.2.0,MIT
+ajv,5.2.2,MIT
ajv-keywords,2.1.0,MIT
akismet,2.0.0,MIT
align-text,0.1.4,MIT
@@ -28,8 +28,6 @@ ansi-regex,2.1.1,MIT
ansi-styles,2.2.1,MIT
anymatch,1.3.2,ISC
append-transform,0.4.0,MIT
-aproba,1.1.1,ISC
-are-we-there-yet,1.1.4,ISC
arel,6.0.4,MIT
argparse,1.0.9,MIT
arr-diff,2.0.0,MIT
@@ -46,21 +44,15 @@ arrify,1.0.1,MIT
asana,0.6.0,MIT
asciidoctor,1.5.3,MIT
asciidoctor-plantuml,0.0.7,MIT
-asn1,0.2.3,MIT
asn1.js,4.9.1,MIT
assert,1.4.1,MIT
-assert-plus,0.2.0,MIT
async,2.4.1,MIT
async-each,1.0.1,MIT
-asynckit,0.4.0,MIT
atomic,1.1.99,Apache 2.0
attr_encrypted,3.0.3,MIT
attr_required,1.0.0,MIT
-autoparse,0.3.3,Apache 2.0
autoprefixer,6.7.7,MIT
autoprefixer-rails,6.2.3,MIT
-aws-sign2,0.6.0,Apache 2.0
-aws4,1.6.0,MIT
axiom-types,0.1.1,MIT
axios,0.16.2,MIT
babel-code-frame,6.22.0,MIT
@@ -145,19 +137,16 @@ base64-js,1.2.0,MIT
base64id,1.0.0,MIT
batch,0.6.1,MIT
bcrypt,3.1.11,MIT
-bcrypt-pbkdf,1.0.1,New BSD
bcrypt_pbkdf,1.0.0,MIT
better-assert,1.0.2,MIT
big.js,3.1.3,MIT
binary-extensions,1.10.0,MIT
-bindata,2.3.5,ruby
+bindata,2.4.1,ruby
blob,0.0.4,unknown
-block-stream,0.0.9,ISC
bluebird,2.11.0,MIT
bn.js,4.11.6,MIT
body-parser,1.17.2,MIT
bonjour,3.5.0,MIT
-boom,2.10.1,New BSD
bootstrap-sass,3.3.6,MIT
bootstrap_form,2.7.0,MIT
brace-expansion,1.1.8,MIT
@@ -187,7 +176,6 @@ camelcase-keys,2.1.0,MIT
caniuse-api,1.6.1,MIT
caniuse-db,1.0.30000649,CC-BY-4.0
carrierwave,1.1.0,MIT
-caseless,0.12.0,Apache 2.0
cause,0.1,MIT
center-align,0.1.3,MIT
chalk,1.1.3,MIT
@@ -216,7 +204,6 @@ color-string,0.3.0,MIT
colormin,1.1.2,MIT
colors,1.1.2,MIT
combine-lists,1.0.1,MIT
-combined-stream,1.0.5,MIT
commander,2.9.0,MIT
commondir,1.0.1,MIT
component-bind,1.0.0,unknown
@@ -233,8 +220,7 @@ configstore,1.4.0,Simplified BSD
connect,3.6.3,MIT
connect-history-api-fallback,1.3.0,MIT
connection_pool,2.2.1,MIT
-console-browserify,1.1.0,MIT
-console-control-strings,1.1.0,ISC
+console-browserify,1.1.0,[Circular]
consolidate,0.14.5,MIT
constants-browserify,1.0.0,MIT
contains-path,0.1.0,MIT
@@ -254,7 +240,6 @@ create-hmac,1.1.4,MIT
creole,0.5.0,ruby
cropper,2.3.0,MIT
cross-spawn,5.1.0,MIT
-cryptiles,2.0.5,New BSD
crypto-browserify,3.11.0,MIT
css-color-names,0.0.4,MIT
css-loader,0.28.0,MIT
@@ -268,13 +253,14 @@ custom-event,1.0.1,MIT
d,1.0.0,MIT
d3,3.5.11,New BSD
d3_rails,3.5.11,MIT
-dashdash,1.14.1,MIT
date-now,0.1.4,MIT
de-indent,1.0.2,MIT
debug,2.6.8,MIT
debugger-ruby_core_source,1.3.8,MIT
decamelize,1.2.0,MIT
deckar01-task_list,2.0.0,MIT
+declarative,0.0.10,MIT
+declarative-option,0.1.0,MIT
decompress-response,3.3.0,MIT
deep-equal,1.0.1,MIT
deep-extend,0.4.2,MIT
@@ -283,9 +269,7 @@ default-require-extensions,1.0.0,MIT
default_value_for,3.0.2,MIT
defined,1.0.0,MIT
del,2.2.2,MIT
-delayed-stream,1.0.0,MIT
delegate,3.1.2,MIT
-delegates,1.0.0,MIT
depd,1.1.1,MIT
des.js,1.0.0,MIT
descendants_tracker,0.0.4,MIT
@@ -310,14 +294,13 @@ domain_name,0.5.20161021,"Simplified BSD,New BSD,Mozilla Public License 2.0"
domelementtype,1.3.0,unknown
domhandler,2.3.0,unknown
domutils,1.5.1,unknown
-doorkeeper,4.2.0,MIT
-doorkeeper-openid_connect,1.1.2,MIT
+doorkeeper,4.2.6,MIT
+doorkeeper-openid_connect,1.2.0,MIT
dropzone,4.2.0,MIT
dropzonejs-rails,0.7.2,MIT
-duplexer,0.1.1,MIT
+duplexer,0.1.1,[Circular]
duplexer3,0.1.4,New BSD
duplexify,3.5.1,MIT
-ecc-jsbn,0.1.1,MIT
editorconfig,0.13.2,MIT
ee-first,1.1.1,MIT
ejs,2.5.6,Apache 2.0
@@ -362,7 +345,7 @@ eslint-plugin-import,2.2.0,MIT
eslint-plugin-jasmine,2.2.0,MIT
eslint-plugin-promise,3.5.0,ISC
espree,3.5.0,Simplified BSD
-esprima,4.0.0,Simplified BSD
+esprima,2.7.3,Simplified BSD
esquery,1.0.0,BSD
esrecurse,4.1.0,Simplified BSD
estraverse,4.1.1,Simplified BSD
@@ -388,12 +371,10 @@ express,4.15.4,MIT
expression_parser,0.9.0,MIT
extend,3.0.1,MIT
extglob,0.3.2,MIT
-extlib,0.9.16,MIT
-extsprintf,1.0.2,MIT
-faraday,0.12.1,MIT
+faraday,0.12.2,MIT
faraday_middleware,0.11.0.1,MIT
faraday_middleware-multi_json,0.0.6,MIT
-fast-deep-equal,0.1.0,MIT
+fast-deep-equal,1.0.0,MIT
fast-levenshtein,2.0.6,MIT
fast_gettext,1.4.0,"MIT,ruby"
fastparse,1.1.1,MIT
@@ -428,8 +409,6 @@ follow-redirects,1.2.3,MIT
font-awesome-rails,4.7.0.1,"MIT,SIL Open Font License"
for-in,0.1.6,MIT
for-own,0.1.4,MIT
-forever-agent,0.6.1,Apache 2.0
-form-data,2.1.4,MIT
formatador,0.2.5,MIT
forwarded,0.1.0,MIT
fresh,0.5.0,MIT
@@ -437,11 +416,8 @@ from,0.1.7,MIT
fs-access,1.0.1,MIT
fs-extra,0.26.7,MIT
fs.realpath,1.0.0,ISC
-fsevents,1.1.2,MIT
-fstream,1.0.11,ISC
-fstream-ignore,1.0.5,ISC
+fsevents,,unknown
function-bind,1.1.0,MIT
-gauge,2.7.4,ISC
gemnasium-gitlab-service,0.2.6,MIT
gemojione,3.3.0,MIT
generate-function,2.0.0,MIT
@@ -450,15 +426,15 @@ get-caller-file,1.0.2,ISC
get-stdin,4.0.1,MIT
get-stream,3.0.0,MIT
get_process_mem,0.2.0,MIT
-getpass,0.1.7,MIT
gettext_i18n_rails,1.8.0,MIT
gettext_i18n_rails_js,1.2.0,MIT
-gitaly-proto,0.33.0,MIT
+gitaly-proto,0.41.0,MIT
github-linguist,4.7.6,MIT
github-markup,1.6.1,MIT
gitlab-flowdock-git-hook,1.0.1,MIT
-gitlab-grit,2.8.1,MIT
-gitlab-markup,1.5.1,MIT
+gitlab-grit,2.8.2,MIT
+gitlab-markup,1.6.2,MIT
+gitlab-svgs,1.0.4,unknown
gitlab_omniauth-ldap,2.0.4,MIT
glob,6.0.4,ISC
glob-base,0.3.0,MIT
@@ -471,9 +447,9 @@ gollum-lib,4.2.7,MIT
gollum-rugged_adapter,0.4.4,MIT
gon,6.1.0,MIT
good-listener,1.2.2,MIT
-google-api-client,0.8.7,Apache 2.0
+google-api-client,0.13.6,Apache 2.0
google-protobuf,3.4.0.2,New BSD
-googleauth,0.5.1,Apache 2.0
+googleauth,0.5.3,Apache 2.0
got,7.1.0,MIT
gpgme,2.0.13,LGPL-2.1+
graceful-fs,4.1.11,ISC
@@ -481,14 +457,12 @@ graceful-readlink,1.0.1,MIT
grape,1.0.0,MIT
grape-entity,0.6.0,MIT
grape-route-helpers,2.1.0,MIT
-grape_logging,1.6.0,MIT
-grpc,1.4.5,New BSD
+grape_logging,1.7.0,MIT
+grpc,1.6.0,Apache 2.0
gzip-size,3.0.0,MIT
hamlit,2.6.1,MIT
handle-thing,1.2.5,MIT
handlebars,4.0.6,MIT
-har-schema,1.0.5,ISC
-har-validator,4.2.1,ISC
has,1.0.1,MIT
has-ansi,2.0.0,MIT
has-binary,0.1.7,MIT
@@ -496,16 +470,13 @@ has-cors,1.1.0,MIT
has-flag,2.0.0,MIT
has-symbol-support-x,1.3.0,MIT
has-to-string-tag-x,1.3.0,MIT
-has-unicode,2.0.1,ISC
hash-sum,1.0.2,MIT
hash.js,1.0.3,MIT
hashie,3.5.6,MIT
hashie-forbidden_attributes,0.1.1,MIT
-hawk,3.1.3,New BSD
he,1.1.1,MIT
health_check,2.6.0,MIT
hipchat,1.5.2,MIT
-hoek,2.16.3,New BSD
home-or-tmp,2.0.0,MIT
hosted-git-info,2.2.0,ISC
hpack.js,2.1.6,MIT
@@ -522,7 +493,6 @@ http-errors,1.6.2,MIT
http-form_data,1.0.1,MIT
http-proxy,1.16.2,MIT
http-proxy-middleware,0.17.4,MIT
-http-signature,1.1.1,MIT
http_parser.rb,0.6.0,MIT
httparty,0.13.7,MIT
httpclient,2.8.2,ruby
@@ -583,15 +553,13 @@ is-resolvable,1.0.0,MIT
is-retry-allowed,1.1.0,MIT
is-stream,1.1.0,MIT
is-svg,2.1.0,MIT
-is-typedarray,1.0.0,MIT
is-unc-path,0.1.2,MIT
is-utf8,0.2.1,MIT
is-windows,0.2.0,MIT
isarray,1.0.0,MIT
isbinaryfile,3.0.2,MIT
-isexe,1.1.2,ISC
+isexe,2.0.0,ISC
isobject,2.1.0,MIT
-isstream,0.1.2,MIT
istanbul,0.4.5,New BSD
istanbul-api,1.1.1,New BSD
istanbul-lib-coverage,1.0.1,New BSD
@@ -605,7 +573,6 @@ jasmine-core,2.6.3,MIT
jasmine-jquery,2.1.1,MIT
jed,1.1.1,MIT
jira-ruby,1.4.1,MIT
-jodid25519,1.0.2,MIT
jquery,2.2.1,MIT
jquery-atwho-rails,1.3.2,MIT
jquery-rails,4.1.1,MIT
@@ -615,21 +582,18 @@ js-beautify,1.6.12,MIT
js-cookie,2.1.3,MIT
js-tokens,3.0.1,MIT
js-yaml,3.7.0,MIT
-jsbn,0.1.1,MIT
jsesc,1.3.0,MIT
json,1.8.6,ruby
-json-jwt,1.7.1,MIT
+json-jwt,1.7.2,MIT
json-loader,0.5.7,MIT
-json-schema,0.2.3,"AFLv2.1,BSD"
json-schema-traverse,0.3.1,MIT
json-stable-stringify,1.0.1,MIT
json-stringify-safe,5.0.1,ISC
-json3,3.3.2,MIT
+json3,3.3.2,[Circular]
json5,0.5.1,MIT
jsonfile,2.4.0,MIT
jsonify,0.0.0,Public Domain
jsonpointer,4.0.1,MIT
-jsprim,1.4.0,MIT
jszip,3.1.3,(MIT OR GPL-3.0)
jszip-utils,0.0.2,MIT or GPLv3
jwt,1.5.6,MIT
@@ -649,7 +613,6 @@ kind-of,3.1.0,MIT
klaw,1.3.1,MIT
kubeclient,2.2.0,MIT
latest-version,1.0.1,MIT
-launchy,2.4.3,ISC
lazy-cache,1.0.4,MIT
lcid,1.0.0,MIT
levn,0.3.0,MIT
@@ -706,7 +669,7 @@ marked,0.3.6,MIT
math-expression-evaluator,1.2.16,MIT
media-typer,0.3.0,MIT
mem,1.1.0,MIT
-memoist,0.15.0,MIT
+memoist,0.16.0,MIT
memory-fs,0.4.1,MIT
meow,3.7.0,MIT
merge-descriptors,1.0.1,MIT
@@ -714,13 +677,14 @@ method_source,0.8.2,MIT
methods,1.1.2,MIT
micromatch,2.3.11,MIT
miller-rabin,4.0.0,MIT
-mime,1.3.4,MIT
-mime-db,1.27.0,MIT
-mime-types,2.99.3,"MIT,Artistic-2.0,GPL-2.0"
+mime,1.3.4,[Circular]
+mime-db,1.29.0,MIT
+mime-types,3.1,MIT
+mime-types-data,3.2016.0521,MIT
mimemagic,0.3.0,MIT
mimic-fn,1.1.0,MIT
mimic-response,1.0.0,MIT
-mini_portile2,2.2.0,MIT
+mini_portile2,2.3.0,MIT
minimalistic-assert,1.0.0,ISC
minimatch,3.0.3,ISC
minimist,0.0.8,MIT
@@ -731,7 +695,7 @@ monaco-editor,0.8.3,MIT
mousetrap,1.4.6,Apache 2.0
mousetrap-rails,1.4.6,"MIT,Apache"
ms,2.0.0,MIT
-multi_json,1.12.1,MIT
+multi_json,1.12.2,MIT
multi_xml,0.6.0,MIT
multicast-dns,6.1.1,MIT
multicast-dns-service-types,1.1.0,MIT
@@ -739,9 +703,7 @@ multipart-post,2.0.0,MIT
mustermann,1.0.0,MIT
mustermann-grape,1.0.0,MIT
mute-stream,0.0.5,ISC
-mysql2,0.4.5,MIT
name-all-modules-plugin,1.0.1,MIT
-nan,2.6.2,MIT
natural-compare,1.4.0,MIT
negotiator,0.6.1,MIT
nested-error-stacks,1.0.2,MIT
@@ -751,22 +713,19 @@ netrc,0.11.0,MIT
node-dir,0.1.17,MIT
node-forge,0.6.33,BSD
node-libs-browser,2.0.0,MIT
-node-pre-gyp,0.6.36,New BSD
nodemon,1.11.0,MIT
-nokogiri,1.8.0,MIT
+nokogiri,1.8.1,MIT
nopt,3.0.6,ISC
-normalize-package-data,2.4.0,Simplified BSD
+normalize-package-data,2.3.5,Simplified BSD
normalize-path,2.1.1,MIT
normalize-range,0.1.2,MIT
normalize-url,1.9.1,MIT
npm-run-path,2.0.2,MIT
-npmlog,4.1.0,ISC
null-check,1.0.0,MIT
num2fraction,1.2.2,MIT
number-is-nan,1.0.1,MIT
numerizer,0.1.1,MIT
oauth,0.5.1,MIT
-oauth-sign,0.8.2,Apache 2.0
oauth2,1.4.0,MIT
object-assign,4.1.1,MIT
object-component,0.0.3,unknown
@@ -777,7 +736,7 @@ oj,2.17.5,MIT
omniauth,1.4.2,MIT
omniauth-auth0,1.4.1,MIT
omniauth-authentiq,0.3.1,MIT
-omniauth-azure-oauth2,0.0.6,MIT
+omniauth-azure-oauth2,0.0.9,MIT
omniauth-cas3,1.1.4,MIT
omniauth-facebook,4.0.0,MIT
omniauth-github,1.1.2,MIT
@@ -786,7 +745,7 @@ omniauth-google-oauth2,0.5.2,MIT
omniauth-kerberos,0.3.0,MIT
omniauth-multipassword,0.4.2,MIT
omniauth-oauth,1.1.0,MIT
-omniauth-oauth2,1.3.1,MIT
+omniauth-oauth2,1.4.0,MIT
omniauth-oauth2-generic,0.2.2,MIT
omniauth-saml,1.7.0,MIT
omniauth-shibboleth,1.2.1,MIT
@@ -839,13 +798,11 @@ pbkdf2,3.0.9,MIT
peek,1.0.1,MIT
peek-gc,0.0.2,MIT
peek-host,1.0.0,MIT
-peek-mysql2,1.1.0,MIT
peek-performance_bar,1.3.0,MIT
peek-pg,1.3.0,MIT
peek-rblineprof,0.2.0,MIT
peek-redis,1.2.0,MIT
peek-sidekiq,1.0.3,MIT
-performance-now,0.2.0,MIT
pg,0.18.4,"BSD,ruby,GPL"
pify,2.3.0,MIT
pikaday,1.5.1,"BSD,MIT"
@@ -910,6 +867,7 @@ prr,0.0.0,MIT
ps-tree,1.1.0,MIT
pseudomap,1.0.2,ISC
public-encrypt,4.0.0,MIT
+public_suffix,3.0.0,MIT
punycode,1.4.1,MIT
pyu-ruby-sasl,0.0.3.3,MIT
q,1.5.0,MIT
@@ -917,7 +875,7 @@ qjobs,1.1.5,MIT
qs,6.5.0,New BSD
query-string,4.3.2,MIT
querystring,0.2.0,MIT
-querystring-es3,0.2.1,MIT
+querystring-es3,0.2.1,[Circular]
querystringify,0.0.4,MIT
rack,1.6.8,MIT
rack-accept,0.4.5,MIT
@@ -935,7 +893,7 @@ rails-i18n,4.0.9,MIT
railties,4.2.8,MIT
rainbow,2.2.2,MIT
raindrops,0.18.0,LGPL-2.1+
-rake,12.0.0,MIT
+rake,12.1.0,MIT
randomatic,1.1.6,MIT
randombytes,2.0.3,MIT
range-parser,1.2.0,MIT
@@ -982,7 +940,7 @@ remove-trailing-separator,1.1.0,ISC
repeat-element,1.1.2,MIT
repeat-string,1.6.1,MIT
repeating,2.0.1,MIT
-request,2.81.0,Apache 2.0
+representable,3.0.4,MIT
request_store,1.3.1,MIT
require-directory,2.1.1,MIT
require-from-string,1.2.1,MIT
@@ -994,7 +952,7 @@ resolve-from,1.0.1,MIT
responders,2.3.0,MIT
rest-client,2.0.0,MIT
restore-cursor,1.0.1,MIT
-retriable,1.4.1,MIT
+retriable,3.1.1,MIT
right-align,0.1.3,MIT
rimraf,2.6.1,ISC
rinku,2.0.0,ISC
@@ -1013,7 +971,7 @@ rufus-scheduler,3.4.0,MIT
rugged,0.26.0,MIT
run-async,0.1.0,MIT
rx-lite,3.1.2,Apache 2.0
-safe-buffer,5.1.1,MIT
+safe-buffer,5.0.1,MIT
safe_yaml,1.0.4,MIT
sanitize,2.1.0,MIT
sass,3.4.22,MIT
@@ -1053,7 +1011,6 @@ slack-notifier,1.5.1,MIT
slash,1.0.0,MIT
slice-ansi,0.0.4,MIT
slide,1.1.6,ISC
-sntp,1.0.9,BSD
socket.io,1.7.3,MIT
socket.io-adapter,0.5.0,MIT
socket.io-client,1.7.3,MIT
@@ -1074,7 +1031,6 @@ sprintf-js,1.0.3,New BSD
sprockets,3.7.1,MIT
sprockets-rails,3.2.0,MIT
sql.js,0.4.0,MIT
-sshpk,1.13.0,MIT
state_machines,0.4.0,MIT
state_machines-activemodel,0.4.0,MIT
state_machines-activerecord,0.4.0,MIT
@@ -1085,22 +1041,20 @@ stream-http,2.6.3,MIT
stream-shift,1.0.0,MIT
strict-uri-encode,1.1.0,MIT
string-length,1.0.1,MIT
-string-width,2.0.0,MIT
-string_decoder,1.0.3,MIT
+string-width,1.0.2,MIT
+string_decoder,0.10.31,MIT
stringex,2.7.1,MIT
-stringstream,0.0.5,MIT
strip-ansi,3.0.1,MIT
strip-bom,3.0.0,MIT
strip-eof,1.0.0,MIT
strip-indent,1.0.1,MIT
strip-json-comments,2.0.1,MIT
-supports-color,4.2.1,MIT
+supports-color,3.2.3,MIT
+svg4everybody,2.1.9,CC0-1.0
svgo,0.7.2,MIT
sys-filesystem,1.1.6,Artistic 2.0
table,3.8.3,New BSD
tapable,0.2.8,MIT
-tar,2.2.1,ISC
-tar-pack,3.4.0,Simplified BSD
temple,0.7.7,MIT
test-exclude,4.0.0,ISC
text,1.3.1,MIT
@@ -1113,6 +1067,7 @@ three-stl-loader,1.0.4,MIT
through,2.3.8,MIT
thunky,0.1.0,unknown
tilt,2.0.6,MIT
+time-stamp,2.0.0,MIT
timeago.js,2.0.5,MIT
timed-out,4.0.1,MIT
timers-browserify,2.0.4,MIT
@@ -1124,31 +1079,28 @@ to-arraybuffer,1.0.1,MIT
to-fast-properties,1.0.2,MIT
toml-rb,0.3.15,MIT
touch,1.0.0,ISC
-tough-cookie,2.3.2,New BSD
traverse,0.6.6,MIT
trim-newlines,1.0.0,MIT
trim-right,1.0.1,MIT
truncato,0.7.10,MIT
tryit,1.0.3,MIT
tty-browserify,0.0.0,MIT
-tunnel-agent,0.6.0,Apache 2.0
-tweetnacl,0.14.5,Unlicense
type-check,0.3.2,MIT
type-is,1.6.15,MIT
typedarray,0.0.6,MIT
tzinfo,1.2.3,MIT
u2f,0.2.1,MIT
+uber,0.1.0,MIT
uglifier,2.7.2,MIT
uglify-js,2.8.29,Simplified BSD
uglify-to-browserify,1.0.2,MIT
uglifyjs-webpack-plugin,0.4.6,MIT
-uid-number,0.0.6,ISC
ultron,1.1.0,MIT
unc-path-regex,0.1.2,MIT
undefsafe,0.0.3,MIT / http://rem.mit-license.org
underscore,1.8.3,MIT
unf,0.1.4,BSD
-unf_ext,0.0.7.2,MIT
+unf_ext,0.0.7.4,MIT
unicorn,5.1.0,ruby
unicorn-worker-killer,0.4.4,ruby
uniq,1.0.1,MIT
@@ -1166,13 +1118,12 @@ user-home,2.0.0,MIT
useragent,2.2.1,MIT
util,0.10.3,MIT
util-deprecate,1.0.2,MIT
-utils-merge,1.0.0,MIT
-uuid,3.0.1,MIT
+utils-merge,1.0.0,[Circular]
+uuid,2.0.3,MIT
validate-npm-package-license,3.0.1,Apache 2.0
validates_hostname,1.0.6,MIT
vary,1.1.1,MIT
vendors,1.0.1,MIT
-verror,1.3.6,MIT
version_sorter,2.1.0,MIT
virtus,1.0.5,MIT
visibilityjs,1.2.4,MIT
@@ -1200,12 +1151,11 @@ webpack-stats-plugin,0.1.5,MIT
websocket-driver,0.6.5,MIT
websocket-extensions,0.1.1,MIT
whet.extend,0.9.9,MIT
-which,1.2.12,ISC
+which,1.3.0,ISC
which-module,2.0.0,ISC
-wide-align,1.1.2,ISC
wikicloth,0.8.1,MIT
window-size,0.1.0,MIT
-wordwrap,0.0.2,MIT/X11
+wordwrap,1.0.0,MIT
wrap-ansi,2.1.0,MIT
wrappy,1.0.2,ISC
write,0.2.1,MIT