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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2019-10-21 21:06:29 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2019-10-21 21:06:29 +0300
commitf1bb2a307e9b125a8ee0be3728cb0d1baa21a3d4 (patch)
tree154817af5e3f1b134be08ef22d1926edf87ab74f
parentad1e4b8fb8104b642fa79ed34fd144bc2bed8a19 (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--GITALY_SERVER_VERSION2
-rw-r--r--app/assets/javascripts/ide/components/jobs/stage.vue3
-rw-r--r--app/assets/javascripts/search_autocomplete.js8
-rw-r--r--app/controllers/concerns/redirects_for_missing_path_on_tree.rb17
-rw-r--r--app/controllers/projects/blame_controller.rb5
-rw-r--r--app/controllers/projects/blob_controller.rb3
-rw-r--r--app/controllers/projects/jobs_controller.rb2
-rw-r--r--app/controllers/projects/tree_controller.rb8
-rw-r--r--changelogs/unreleased/33533-go-to-root-if-no-path-on-branch.yml6
-rw-r--r--changelogs/unreleased/pokstad1-gitaly-1-70-0.yml5
-rw-r--r--changelogs/unreleased/sh-use-template-project-id.yml5
-rw-r--r--db/post_migrate/20190809072552_set_self_monitoring_project_alerting_token.rb68
-rw-r--r--doc/development/testing_guide/flaky_tests.md1
-rw-r--r--doc/user/project/integrations/generic_alerts.md4
-rw-r--r--lib/feature/gitaly.rb1
-rw-r--r--locale/gitlab.pot3
-rw-r--r--qa/qa/resource/runner.rb1
-rw-r--r--spec/controllers/concerns/redirects_for_missing_path_on_tree_spec.rb33
-rw-r--r--spec/controllers/projects/blame_controller_spec.rb19
-rw-r--r--spec/controllers/projects/blob_controller_spec.rb11
-rw-r--r--spec/controllers/projects/tree_controller_spec.rb20
-rw-r--r--spec/features/search/user_uses_header_search_field_spec.rb3
-rw-r--r--spec/finders/todos_finder_spec.rb30
-rw-r--r--spec/frontend/ide/components/jobs/__snapshots__/stage_spec.js.snap61
-rw-r--r--spec/frontend/ide/components/jobs/stage_spec.js86
-rw-r--r--spec/javascripts/ide/components/jobs/stage_spec.js95
-rw-r--r--spec/requests/git_http_spec.rb4
27 files changed, 306 insertions, 198 deletions
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index 65ee0959841..832e9afb6c1 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-1.67.0
+1.70.0
diff --git a/app/assets/javascripts/ide/components/jobs/stage.vue b/app/assets/javascripts/ide/components/jobs/stage.vue
index 9ad9d4455b5..52ca61c06b0 100644
--- a/app/assets/javascripts/ide/components/jobs/stage.vue
+++ b/app/assets/javascripts/ide/components/jobs/stage.vue
@@ -58,6 +58,7 @@ export default {
<template>
<div class="ide-stage card prepend-top-default">
<div
+ ref="cardHeader"
:class="{
'border-bottom-0': stage.isCollapsed,
}"
@@ -79,7 +80,7 @@ export default {
</div>
<icon :name="collapseIcon" class="ide-stage-collapse-icon" />
</div>
- <div v-show="!stage.isCollapsed" class="card-body">
+ <div v-show="!stage.isCollapsed" ref="jobList" class="card-body">
<gl-loading-icon v-if="showLoadingIcon" />
<template v-else>
<item v-for="job in stage.jobs" :key="job.id" :job="job" @clickViewLog="clickViewLog" />
diff --git a/app/assets/javascripts/search_autocomplete.js b/app/assets/javascripts/search_autocomplete.js
index f6722ff7bca..e08a67ec604 100644
--- a/app/assets/javascripts/search_autocomplete.js
+++ b/app/assets/javascripts/search_autocomplete.js
@@ -95,10 +95,10 @@ export class SearchAutocomplete {
this.createAutocomplete();
}
- this.searchInput.addClass('disabled');
this.saveTextLength();
this.bindEvents();
this.dropdownToggle.dropdown();
+ this.searchInput.addClass('js-autocomplete-disabled');
}
// Finds an element inside wrapper element
@@ -338,7 +338,7 @@ export class SearchAutocomplete {
if (!this.dropdown.hasClass('show')) {
this.loadingSuggestions = false;
this.dropdownToggle.dropdown('toggle');
- return this.searchInput.removeClass('disabled');
+ return this.searchInput.removeClass('js-autocomplete-disabled');
}
}
@@ -432,8 +432,8 @@ export class SearchAutocomplete {
}
disableAutocomplete() {
- if (!this.searchInput.hasClass('disabled') && this.dropdown.hasClass('show')) {
- this.searchInput.addClass('disabled');
+ if (!this.searchInput.hasClass('js-autocomplete-disabled') && this.dropdown.hasClass('show')) {
+ this.searchInput.addClass('js-autocomplete-disabled');
this.dropdown.removeClass('show').trigger('hidden.bs.dropdown');
this.restoreMenu();
}
diff --git a/app/controllers/concerns/redirects_for_missing_path_on_tree.rb b/app/controllers/concerns/redirects_for_missing_path_on_tree.rb
new file mode 100644
index 00000000000..085afbf3975
--- /dev/null
+++ b/app/controllers/concerns/redirects_for_missing_path_on_tree.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module RedirectsForMissingPathOnTree
+ def redirect_to_tree_root_for_missing_path(project, ref, path)
+ redirect_to project_tree_path(project, ref), notice: missing_path_on_ref(path, ref)
+ end
+
+ private
+
+ def missing_path_on_ref(path, ref)
+ _('"%{path}" did not exist on "%{ref}"') % { path: truncate_path(path), ref: ref }
+ end
+
+ def truncate_path(path)
+ path.reverse.truncate(60, separator: "/").reverse
+ end
+end
diff --git a/app/controllers/projects/blame_controller.rb b/app/controllers/projects/blame_controller.rb
index 9076bdb9f04..92655d593dd 100644
--- a/app/controllers/projects/blame_controller.rb
+++ b/app/controllers/projects/blame_controller.rb
@@ -3,6 +3,7 @@
# Controller for viewing a file's blame
class Projects::BlameController < Projects::ApplicationController
include ExtractsPath
+ include RedirectsForMissingPathOnTree
before_action :require_non_empty_project
before_action :assign_ref_vars
@@ -11,7 +12,9 @@ class Projects::BlameController < Projects::ApplicationController
def show
@blob = @repository.blob_at(@commit.id, @path)
- return render_404 unless @blob
+ unless @blob
+ return redirect_to_tree_root_for_missing_path(@project, @ref, @path)
+ end
environment_params = @repository.branch_exists?(@ref) ? { ref: @ref } : { commit: @commit }
@environment = EnvironmentsFinder.new(@project, current_user, environment_params).execute.last
diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb
index 7c3d43fb49a..205ec288ce9 100644
--- a/app/controllers/projects/blob_controller.rb
+++ b/app/controllers/projects/blob_controller.rb
@@ -7,6 +7,7 @@ class Projects::BlobController < Projects::ApplicationController
include RendersBlob
include NotesHelper
include ActionView::Helpers::SanitizeHelper
+ include RedirectsForMissingPathOnTree
prepend_before_action :authenticate_user!, only: [:edit]
around_action :allow_gitaly_ref_name_caching, only: [:show]
@@ -119,7 +120,7 @@ class Projects::BlobController < Projects::ApplicationController
end
end
- return render_404
+ return redirect_to_tree_root_for_missing_path(@project, @ref, @path)
end
end
diff --git a/app/controllers/projects/jobs_controller.rb b/app/controllers/projects/jobs_controller.rb
index 050e2d1079b..1d914ab6011 100644
--- a/app/controllers/projects/jobs_controller.rb
+++ b/app/controllers/projects/jobs_controller.rb
@@ -12,7 +12,7 @@ class Projects::JobsController < Projects::ApplicationController
before_action :authorize_use_build_terminal!, only: [:terminal, :terminal_websocket_authorize]
before_action :verify_api_request!, only: :terminal_websocket_authorize
before_action only: [:show] do
- push_frontend_feature_flag(:job_log_json)
+ push_frontend_feature_flag(:job_log_json, project)
end
layout 'project'
diff --git a/app/controllers/projects/tree_controller.rb b/app/controllers/projects/tree_controller.rb
index 7509cc29a76..eec89afe354 100644
--- a/app/controllers/projects/tree_controller.rb
+++ b/app/controllers/projects/tree_controller.rb
@@ -5,6 +5,7 @@ class Projects::TreeController < Projects::ApplicationController
include ExtractsPath
include CreatesCommit
include ActionView::Helpers::SanitizeHelper
+ include RedirectsForMissingPathOnTree
around_action :allow_gitaly_ref_name_caching, only: [:show]
@@ -19,12 +20,9 @@ class Projects::TreeController < Projects::ApplicationController
if tree.entries.empty?
if @repository.blob_at(@commit.id, @path)
- return redirect_to(
- project_blob_path(@project,
- File.join(@ref, @path))
- )
+ return redirect_to project_blob_path(@project, File.join(@ref, @path))
elsif @path.present?
- return render_404
+ return redirect_to_tree_root_for_missing_path(@project, @ref, @path)
end
end
diff --git a/changelogs/unreleased/33533-go-to-root-if-no-path-on-branch.yml b/changelogs/unreleased/33533-go-to-root-if-no-path-on-branch.yml
new file mode 100644
index 00000000000..c85faa9e7a2
--- /dev/null
+++ b/changelogs/unreleased/33533-go-to-root-if-no-path-on-branch.yml
@@ -0,0 +1,6 @@
+---
+title: When a user views a file's blame or blob and switches to a branch where the
+ current file does not exist, they will now be redirected to the root of the repository.
+merge_request: 18169
+author: Jesse Hall @jessehall3
+type: changed
diff --git a/changelogs/unreleased/pokstad1-gitaly-1-70-0.yml b/changelogs/unreleased/pokstad1-gitaly-1-70-0.yml
new file mode 100644
index 00000000000..3ced037b74a
--- /dev/null
+++ b/changelogs/unreleased/pokstad1-gitaly-1-70-0.yml
@@ -0,0 +1,5 @@
+---
+title: Bump Gitaly to 1.70.0 and remove cache invalidation feature flag
+merge_request: 18766
+author:
+type: other
diff --git a/changelogs/unreleased/sh-use-template-project-id.yml b/changelogs/unreleased/sh-use-template-project-id.yml
new file mode 100644
index 00000000000..7784007f536
--- /dev/null
+++ b/changelogs/unreleased/sh-use-template-project-id.yml
@@ -0,0 +1,5 @@
+---
+title: Fix incorrect selection of custom templates
+merge_request: 17205
+author:
+type: fixed
diff --git a/db/post_migrate/20190809072552_set_self_monitoring_project_alerting_token.rb b/db/post_migrate/20190809072552_set_self_monitoring_project_alerting_token.rb
index 0c4faebc548..d10887fb5d5 100644
--- a/db/post_migrate/20190809072552_set_self_monitoring_project_alerting_token.rb
+++ b/db/post_migrate/20190809072552_set_self_monitoring_project_alerting_token.rb
@@ -3,71 +3,17 @@
class SetSelfMonitoringProjectAlertingToken < ActiveRecord::Migration[5.2]
DOWNTIME = false
- module Migratable
- module Alerting
- class ProjectAlertingSetting < ApplicationRecord
- self.table_name = 'project_alerting_settings'
-
- belongs_to :project
-
- validates :token, presence: true
-
- attr_encrypted :token,
- mode: :per_attribute_iv,
- key: Settings.attr_encrypted_db_key_base_truncated,
- algorithm: 'aes-256-gcm'
-
- before_validation :ensure_token
-
- private
-
- def ensure_token
- self.token ||= generate_token
- end
-
- def generate_token
- SecureRandom.hex
- end
- end
- end
-
- class Project < ApplicationRecord
- has_one :alerting_setting, inverse_of: :project, class_name: 'Alerting::ProjectAlertingSetting'
- end
-
- class ApplicationSetting < ApplicationRecord
- self.table_name = 'application_settings'
-
- belongs_to :instance_administration_project, class_name: 'Project'
-
- def self.current_without_cache
- last
- end
- end
- end
-
- def setup_alertmanager_token(project)
- return unless License.feature_available?(:prometheus_alerts)
-
- project.create_alerting_setting!
- end
-
def up
- Gitlab.ee do
- project = Migratable::ApplicationSetting.current_without_cache&.instance_administration_project
+ # no-op
+ # Converted to no-op in https://gitlab.com/gitlab-org/gitlab/merge_requests/17049.
- if project
- setup_alertmanager_token(project)
- end
- end
+ # This migration has been made a no-op because the pre-requisite migration
+ # which creates the self-monitoring project has already been removed in
+ # https://gitlab.com/gitlab-org/gitlab/merge_requests/16864. As
+ # such, this migration would do nothing.
end
def down
- Gitlab.ee do
- Migratable::ApplicationSetting.current_without_cache
- &.instance_administration_project
- &.alerting_setting
- &.destroy!
- end
+ # no-op
end
end
diff --git a/doc/development/testing_guide/flaky_tests.md b/doc/development/testing_guide/flaky_tests.md
index 0823c2e02b8..3a96f8204fc 100644
--- a/doc/development/testing_guide/flaky_tests.md
+++ b/doc/development/testing_guide/flaky_tests.md
@@ -83,6 +83,7 @@ This was originally implemented in: <https://gitlab.com/gitlab-org/gitlab-foss/m
- In JS tests, shifting elements can cause Capybara to misclick when the element moves at the exact time Capybara sends the click
- [Dropdowns rendering upward or downward due to window size and scroll position](https://gitlab.com/gitlab-org/gitlab/merge_requests/17660)
- [Lazy loaded images can cause Capybara to misclick](https://gitlab.com/gitlab-org/gitlab/merge_requests/18713)
+- [Triggering JS events before the event handlers are set up](https://gitlab.com/gitlab-org/gitlab/merge_requests/18742)
#### Capybara viewport size related issues
diff --git a/doc/user/project/integrations/generic_alerts.md b/doc/user/project/integrations/generic_alerts.md
index ec43696fdee..b5f86c00eb3 100644
--- a/doc/user/project/integrations/generic_alerts.md
+++ b/doc/user/project/integrations/generic_alerts.md
@@ -1,6 +1,6 @@
# Generic alerts integration **(ULTIMATE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/13203) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.3.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/13203) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.4.
GitLab can accept alerts from any source via a generic webhook receiver.
When you set up the generic alerts integration, a unique endpoint will
@@ -16,7 +16,7 @@ authored by the GitLab Alert Bot.
To set up the generic alerts integration:
1. Navigate to **Settings > Integrations** in a project.
-1. Click on **Alert endpoint**.
+1. Click on **Alerts endpoint**.
1. Toggle the **Active** alert setting. The `URL` and `Authorization Key` for the webhook configuration can be found there.
## Customizing the payload
diff --git a/lib/feature/gitaly.rb b/lib/feature/gitaly.rb
index 81f8ba5c8c3..c23d7025d0f 100644
--- a/lib/feature/gitaly.rb
+++ b/lib/feature/gitaly.rb
@@ -7,7 +7,6 @@ class Feature
# Server feature flags should use '_' to separate words.
SERVER_FEATURE_FLAGS =
%w[
- cache_invalidator
inforef_uploadpack_cache
get_all_lfs_pointers_go
].freeze
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 766b8c71dc5..6f66b51951d 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -62,6 +62,9 @@ msgstr ""
msgid " or references (e.g. path/to/project!merge_request_id)"
msgstr ""
+msgid "\"%{path}\" did not exist on \"%{ref}\""
+msgstr ""
+
msgid "%d comment"
msgid_plural "%d comments"
msgstr[0] ""
diff --git a/qa/qa/resource/runner.rb b/qa/qa/resource/runner.rb
index 1be2429bc04..102c1ec83f5 100644
--- a/qa/qa/resource/runner.rb
+++ b/qa/qa/resource/runner.rb
@@ -36,7 +36,6 @@ module QA
runner.tags = tags
runner.image = image
runner.config = config if config
- runner.run_untagged = true
runner.register!
end
end
diff --git a/spec/controllers/concerns/redirects_for_missing_path_on_tree_spec.rb b/spec/controllers/concerns/redirects_for_missing_path_on_tree_spec.rb
new file mode 100644
index 00000000000..903100ba93f
--- /dev/null
+++ b/spec/controllers/concerns/redirects_for_missing_path_on_tree_spec.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe RedirectsForMissingPathOnTree, type: :controller do
+ controller(ActionController::Base) do
+ include Gitlab::Routing.url_helpers
+ include RedirectsForMissingPathOnTree
+
+ def fake
+ redirect_to_tree_root_for_missing_path(Project.find(params[:project_id]), params[:ref], params[:file_path])
+ end
+ end
+
+ let(:project) { create(:project) }
+
+ before do
+ routes.draw { get 'fake' => 'anonymous#fake' }
+ end
+
+ describe '#redirect_to_root_path' do
+ it 'redirects to the tree path with a notice' do
+ long_file_path = ('a/b/' * 30) + 'foo.txt'
+ truncated_file_path = '...b/' + ('a/b/' * 12) + 'foo.txt'
+ expected_message = "\"#{truncated_file_path}\" did not exist on \"theref\""
+
+ get :fake, params: { project_id: project.id, ref: 'theref', file_path: long_file_path }
+
+ expect(response).to redirect_to project_tree_path(project, 'theref')
+ expect(response.flash[:notice]).to eq(expected_message)
+ end
+ end
+end
diff --git a/spec/controllers/projects/blame_controller_spec.rb b/spec/controllers/projects/blame_controller_spec.rb
index f901fd45604..dd7c0f45dc2 100644
--- a/spec/controllers/projects/blame_controller_spec.rb
+++ b/spec/controllers/projects/blame_controller_spec.rb
@@ -25,14 +25,25 @@ describe Projects::BlameController do
})
end
- context "valid file" do
+ context "valid branch, valid file" do
let(:id) { 'master/files/ruby/popen.rb' }
+
it { is_expected.to respond_with(:success) }
end
- context "invalid file" do
- let(:id) { 'master/files/ruby/missing_file.rb'}
- it { expect(response).to have_gitlab_http_status(404) }
+ context "valid branch, invalid file" do
+ let(:id) { 'master/files/ruby/invalid-path.rb' }
+
+ it 'redirects' do
+ expect(subject)
+ .to redirect_to("/#{project.full_path}/tree/master")
+ end
+ end
+
+ context "invalid branch, valid file" do
+ let(:id) { 'invalid-branch/files/ruby/missing_file.rb'}
+
+ it { is_expected.to respond_with(:not_found) }
end
end
end
diff --git a/spec/controllers/projects/blob_controller_spec.rb b/spec/controllers/projects/blob_controller_spec.rb
index 17964c78e8d..086ec9dfbcf 100644
--- a/spec/controllers/projects/blob_controller_spec.rb
+++ b/spec/controllers/projects/blob_controller_spec.rb
@@ -24,26 +24,34 @@ describe Projects::BlobController do
context "valid branch, valid file" do
let(:id) { 'master/README.md' }
+
it { is_expected.to respond_with(:success) }
end
context "valid branch, invalid file" do
let(:id) { 'master/invalid-path.rb' }
- it { is_expected.to respond_with(:not_found) }
+
+ it 'redirects' do
+ expect(subject)
+ .to redirect_to("/#{project.full_path}/tree/master")
+ end
end
context "invalid branch, valid file" do
let(:id) { 'invalid-branch/README.md' }
+
it { is_expected.to respond_with(:not_found) }
end
context "binary file" do
let(:id) { 'binary-encoding/encoding/binary-1.bin' }
+
it { is_expected.to respond_with(:success) }
end
context "Markdown file" do
let(:id) { 'master/README.md' }
+
it { is_expected.to respond_with(:success) }
end
end
@@ -104,6 +112,7 @@ describe Projects::BlobController do
context 'redirect to tree' do
let(:id) { 'markdown/doc' }
+
it 'redirects' do
expect(subject)
.to redirect_to("/#{project.full_path}/tree/markdown/doc")
diff --git a/spec/controllers/projects/tree_controller_spec.rb b/spec/controllers/projects/tree_controller_spec.rb
index 7f7cabe3b0c..c0c11db5dd6 100644
--- a/spec/controllers/projects/tree_controller_spec.rb
+++ b/spec/controllers/projects/tree_controller_spec.rb
@@ -30,46 +30,61 @@ describe Projects::TreeController do
context "valid branch, no path" do
let(:id) { 'master' }
+
it { is_expected.to respond_with(:success) }
end
context "valid branch, valid path" do
let(:id) { 'master/encoding/' }
+
it { is_expected.to respond_with(:success) }
end
context "valid branch, invalid path" do
let(:id) { 'master/invalid-path/' }
- it { is_expected.to respond_with(:not_found) }
+
+ it 'redirects' do
+ expect(subject)
+ .to redirect_to("/#{project.full_path}/tree/master")
+ end
end
context "invalid branch, valid path" do
let(:id) { 'invalid-branch/encoding/' }
+
it { is_expected.to respond_with(:not_found) }
end
context "valid empty branch, invalid path" do
let(:id) { 'empty-branch/invalid-path/' }
- it { is_expected.to respond_with(:not_found) }
+
+ it 'redirects' do
+ expect(subject)
+ .to redirect_to("/#{project.full_path}/tree/empty-branch")
+ end
end
context "valid empty branch" do
let(:id) { 'empty-branch' }
+
it { is_expected.to respond_with(:success) }
end
context "invalid SHA commit ID" do
let(:id) { 'ff39438/.gitignore' }
+
it { is_expected.to respond_with(:not_found) }
end
context "valid SHA commit ID" do
let(:id) { '6d39438' }
+
it { is_expected.to respond_with(:success) }
end
context "valid SHA commit ID with path" do
let(:id) { '6d39438/.gitignore' }
+
it { expect(response).to have_gitlab_http_status(302) }
end
end
@@ -108,6 +123,7 @@ describe Projects::TreeController do
context 'redirect to blob' do
let(:id) { 'master/README.md' }
+
it 'redirects' do
redirect_url = "/#{project.full_path}/blob/master/README.md"
expect(subject)
diff --git a/spec/features/search/user_uses_header_search_field_spec.rb b/spec/features/search/user_uses_header_search_field_spec.rb
index 7e7c09e4a13..d386e489739 100644
--- a/spec/features/search/user_uses_header_search_field_spec.rb
+++ b/spec/features/search/user_uses_header_search_field_spec.rb
@@ -28,8 +28,7 @@ describe 'User uses header search field', :js do
context 'when clicking the search field' do
before do
- page.find('#search').click
- wait_for_all_requests
+ page.find('#search.js-autocomplete-disabled').click
end
it 'shows category search dropdown' do
diff --git a/spec/finders/todos_finder_spec.rb b/spec/finders/todos_finder_spec.rb
index 044e135fa0b..a4b076bc367 100644
--- a/spec/finders/todos_finder_spec.rb
+++ b/spec/finders/todos_finder_spec.rb
@@ -36,10 +36,18 @@ describe TodosFinder do
expect(todos).to match_array([todo1, todo2])
end
- it 'returns correct todos when filtered by a type' do
- todos = finder.new(user, { type: 'Issue' }).execute
+ context 'when filtering by type' do
+ it 'returns correct todos when filtered by a type' do
+ todos = finder.new(user, { type: 'Issue' }).execute
- expect(todos).to match_array([todo1])
+ expect(todos).to match_array([todo1])
+ end
+
+ it 'returns the correct todos when filtering for multiple types' do
+ todos = finder.new(user, { type: %w[Issue MergeRequest] }).execute
+
+ expect(todos).to match_array([todo1, todo2])
+ end
end
context 'when filtering for actions' do
@@ -53,12 +61,10 @@ describe TodosFinder do
expect(todos).to match_array([todo2])
end
- context 'multiple actions' do
- it 'returns the expected todos' do
- todos = finder.new(user, { action_id: [Todo::DIRECTLY_ADDRESSED, Todo::ASSIGNED] }).execute
+ it 'returns the expected todos when filtering for multiple action ids' do
+ todos = finder.new(user, { action_id: [Todo::DIRECTLY_ADDRESSED, Todo::ASSIGNED] }).execute
- expect(todos).to match_array([todo2, todo1])
- end
+ expect(todos).to match_array([todo2, todo1])
end
end
@@ -69,12 +75,10 @@ describe TodosFinder do
expect(todos).to match_array([todo2])
end
- context 'multiple actions' do
- it 'returns the expected todos' do
- todos = finder.new(user, { action: [:directly_addressed, :assigned] }).execute
+ it 'returns the expected todos when filtering for multiple action names' do
+ todos = finder.new(user, { action: [:directly_addressed, :assigned] }).execute
- expect(todos).to match_array([todo2, todo1])
- end
+ expect(todos).to match_array([todo2, todo1])
end
end
end
diff --git a/spec/frontend/ide/components/jobs/__snapshots__/stage_spec.js.snap b/spec/frontend/ide/components/jobs/__snapshots__/stage_spec.js.snap
new file mode 100644
index 00000000000..5d6c31f01d9
--- /dev/null
+++ b/spec/frontend/ide/components/jobs/__snapshots__/stage_spec.js.snap
@@ -0,0 +1,61 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`IDE pipeline stage renders stage details & icon 1`] = `
+<div
+ class="ide-stage card prepend-top-default"
+>
+ <div
+ class="card-header"
+ >
+ <ciicon-stub
+ cssclasses=""
+ size="24"
+ status="[object Object]"
+ />
+
+ <strong
+ class="prepend-left-8 ide-stage-title"
+ data-container="body"
+ data-original-title=""
+ title=""
+ >
+
+ build
+
+ </strong>
+
+ <div
+ class="append-right-8 prepend-left-4"
+ >
+ <span
+ class="badge badge-pill"
+ >
+ 4
+ </span>
+ </div>
+
+ <icon-stub
+ class="ide-stage-collapse-icon"
+ name="angle-down"
+ size="16"
+ />
+ </div>
+
+ <div
+ class="card-body"
+ >
+ <item-stub
+ job="[object Object]"
+ />
+ <item-stub
+ job="[object Object]"
+ />
+ <item-stub
+ job="[object Object]"
+ />
+ <item-stub
+ job="[object Object]"
+ />
+ </div>
+</div>
+`;
diff --git a/spec/frontend/ide/components/jobs/stage_spec.js b/spec/frontend/ide/components/jobs/stage_spec.js
new file mode 100644
index 00000000000..2e42ab26d27
--- /dev/null
+++ b/spec/frontend/ide/components/jobs/stage_spec.js
@@ -0,0 +1,86 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlLoadingIcon } from '@gitlab/ui';
+import Stage from '~/ide/components/jobs/stage.vue';
+import Item from '~/ide/components/jobs/item.vue';
+import { stages, jobs } from '../../mock_data';
+
+describe('IDE pipeline stage', () => {
+ let wrapper;
+ const defaultProps = {
+ stage: {
+ ...stages[0],
+ id: 0,
+ dropdownPath: stages[0].dropdown_path,
+ jobs: [...jobs],
+ isLoading: false,
+ isCollapsed: false,
+ },
+ };
+
+ const findHeader = () => wrapper.find({ ref: 'cardHeader' });
+ const findJobList = () => wrapper.find({ ref: 'jobList' });
+
+ const createComponent = props => {
+ wrapper = shallowMount(Stage, {
+ propsData: {
+ ...defaultProps,
+ ...props,
+ },
+ sync: false,
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ it('emits fetch event when mounted', () => {
+ createComponent();
+ expect(wrapper.emitted().fetch).toBeDefined();
+ });
+
+ it('renders loading icon when no jobs and isLoading is true', () => {
+ createComponent({
+ stage: { ...defaultProps.stage, isLoading: true, jobs: [] },
+ });
+
+ expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
+ });
+
+ it('emits toggleCollaped event with stage id when clicking header', () => {
+ const id = 5;
+ createComponent({ stage: { ...defaultProps.stage, id } });
+ findHeader().trigger('click');
+ expect(wrapper.emitted().toggleCollapsed[0][0]).toBe(id);
+ });
+
+ it('emits clickViewLog entity with job', () => {
+ const [job] = defaultProps.stage.jobs;
+ createComponent();
+ wrapper
+ .findAll(Item)
+ .at(0)
+ .vm.$emit('clickViewLog', job);
+ expect(wrapper.emitted().clickViewLog[0][0]).toBe(job);
+ });
+
+ it('renders stage details & icon', () => {
+ createComponent();
+ expect(wrapper.element).toMatchSnapshot();
+ });
+
+ describe('when collapsed', () => {
+ beforeEach(() => {
+ createComponent({ stage: { ...defaultProps.stage, isCollapsed: true } });
+ });
+
+ it('does not render job list', () => {
+ expect(findJobList().isVisible()).toBe(false);
+ });
+
+ it('sets border bottom class', () => {
+ expect(findHeader().classes('border-bottom-0')).toBe(true);
+ });
+ });
+});
diff --git a/spec/javascripts/ide/components/jobs/stage_spec.js b/spec/javascripts/ide/components/jobs/stage_spec.js
deleted file mode 100644
index fc3831f2d05..00000000000
--- a/spec/javascripts/ide/components/jobs/stage_spec.js
+++ /dev/null
@@ -1,95 +0,0 @@
-import Vue from 'vue';
-import Stage from '~/ide/components/jobs/stage.vue';
-import { stages, jobs } from '../../mock_data';
-
-describe('IDE pipeline stage', () => {
- const Component = Vue.extend(Stage);
- let vm;
- let stage;
-
- beforeEach(() => {
- stage = {
- ...stages[0],
- id: 0,
- dropdownPath: stages[0].dropdown_path,
- jobs: [...jobs],
- isLoading: false,
- isCollapsed: false,
- };
-
- vm = new Component({
- propsData: { stage },
- });
-
- spyOn(vm, '$emit');
-
- vm.$mount();
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- it('emits fetch event when mounted', () => {
- expect(vm.$emit).toHaveBeenCalledWith('fetch', vm.stage);
- });
-
- it('renders stages details', () => {
- expect(vm.$el.textContent).toContain(vm.stage.name);
- });
-
- it('renders CI icon', () => {
- expect(vm.$el.querySelector('.ic-status_failed')).not.toBe(null);
- });
-
- describe('collapsed', () => {
- it('emits event when clicking header', done => {
- vm.$el.querySelector('.card-header').click();
-
- vm.$nextTick(() => {
- expect(vm.$emit).toHaveBeenCalledWith('toggleCollapsed', vm.stage.id);
-
- done();
- });
- });
-
- it('toggles collapse status when collapsed', done => {
- vm.stage.isCollapsed = true;
-
- vm.$nextTick(() => {
- expect(vm.$el.querySelector('.card-body').style.display).toBe('none');
-
- done();
- });
- });
-
- it('sets border bottom class when collapsed', done => {
- vm.stage.isCollapsed = true;
-
- vm.$nextTick(() => {
- expect(vm.$el.querySelector('.card-header').classList).toContain('border-bottom-0');
-
- done();
- });
- });
- });
-
- it('renders jobs count', () => {
- expect(vm.$el.querySelector('.badge').textContent).toContain('4');
- });
-
- it('renders loading icon when no jobs and isLoading is true', done => {
- vm.stage.isLoading = true;
- vm.stage.jobs = [];
-
- vm.$nextTick(() => {
- expect(vm.$el.querySelector('.loading-container')).not.toBe(null);
-
- done();
- });
- });
-
- it('renders list of jobs', () => {
- expect(vm.$el.querySelectorAll('.ide-job-item').length).toBe(4);
- });
-});
diff --git a/spec/requests/git_http_spec.rb b/spec/requests/git_http_spec.rb
index e58f1b7d9dc..07e56619f40 100644
--- a/spec/requests/git_http_spec.rb
+++ b/spec/requests/git_http_spec.rb
@@ -843,8 +843,8 @@ describe 'Git HTTP requests' do
get "/#{project.full_path}/blob/master/info/refs"
end
- it "returns not found" do
- expect(response).to have_gitlab_http_status(:not_found)
+ it "redirects" do
+ expect(response).to have_gitlab_http_status(302)
end
end
end