From 6c31b607de3528f78f340a2bc5bfdb163378981c Mon Sep 17 00:00:00 2001 From: Semyon Pupkov Date: Thu, 20 Sep 2018 21:47:34 +0500 Subject: Fix SpaceBeforeFirstArg cop --- spec/features/search/user_uses_search_filters_spec.rb | 4 ++-- spec/routing/project_routing_spec.rb | 8 ++++---- spec/services/system_note_service_spec.rb | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'spec') diff --git a/spec/features/search/user_uses_search_filters_spec.rb b/spec/features/search/user_uses_search_filters_spec.rb index 66afe163447..0725ff178ac 100644 --- a/spec/features/search/user_uses_search_filters_spec.rb +++ b/spec/features/search/user_uses_search_filters_spec.rb @@ -14,7 +14,7 @@ describe 'User uses search filters', :js do visit(search_path) end - context' when filtering by group' do + context 'when filtering by group' do it 'shows group projects' do find('.js-search-group-dropdown').click @@ -36,7 +36,7 @@ describe 'User uses search filters', :js do end end - context' when filtering by project' do + context 'when filtering by project' do it 'shows a project' do page.within('.project-filter') do find('.js-search-project-dropdown').click diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb index 5abc6d81958..56df8dddbc1 100644 --- a/spec/routing/project_routing_spec.rb +++ b/spec/routing/project_routing_spec.rb @@ -258,10 +258,10 @@ describe 'project routing' do end it 'to #logs_tree' do - expect(get('/gitlab/gitlabhq/refs/stable/logs_tree')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'stable') - expect(get('/gitlab/gitlabhq/refs/feature%2345/logs_tree')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature#45') - expect(get('/gitlab/gitlabhq/refs/feature%2B45/logs_tree')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature+45') - expect(get('/gitlab/gitlabhq/refs/feature@45/logs_tree')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature@45') + expect(get('/gitlab/gitlabhq/refs/stable/logs_tree')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'stable') + expect(get('/gitlab/gitlabhq/refs/feature%2345/logs_tree')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature#45') + expect(get('/gitlab/gitlabhq/refs/feature%2B45/logs_tree')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature+45') + expect(get('/gitlab/gitlabhq/refs/feature@45/logs_tree')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature@45') expect(get('/gitlab/gitlabhq/refs/stable/logs_tree/foo/bar/baz')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'stable', path: 'foo/bar/baz') expect(get('/gitlab/gitlabhq/refs/feature%2345/logs_tree/foo/bar/baz')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature#45', path: 'foo/bar/baz') expect(get('/gitlab/gitlabhq/refs/feature%2B45/logs_tree/foo/bar/baz')).to route_to('projects/refs#logs_tree', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'feature+45', path: 'foo/bar/baz') diff --git a/spec/services/system_note_service_spec.rb b/spec/services/system_note_service_spec.rb index f4b7cb8c90a..a18126ee339 100644 --- a/spec/services/system_note_service_spec.rb +++ b/spec/services/system_note_service_spec.rb @@ -324,7 +324,7 @@ describe SystemNoteService do end it "posts the 'merge when pipeline succeeds' system note" do - expect(subject.note).to eq "canceled the automatic merge" + expect(subject.note).to eq "canceled the automatic merge" end end -- cgit v1.2.1 From 6c0907894f920c7681cff671542c69b914d4d03b Mon Sep 17 00:00:00 2001 From: Semyon Pupkov Date: Thu, 20 Sep 2018 21:49:26 +0500 Subject: Fix SpaceInsideArrayLiteralBrackets cop --- spec/lib/gitlab/import_export/relation_factory_spec.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'spec') diff --git a/spec/lib/gitlab/import_export/relation_factory_spec.rb b/spec/lib/gitlab/import_export/relation_factory_spec.rb index cf9e0f71910..a31f77484d8 100644 --- a/spec/lib/gitlab/import_export/relation_factory_spec.rb +++ b/spec/lib/gitlab/import_export/relation_factory_spec.rb @@ -191,9 +191,7 @@ describe Gitlab::ImportExport::RelationFactory do "author" => { "name" => "Administrator" }, - "events" => [ - - ] + "events" => [] } end -- cgit v1.2.1 From 87b85ef81cadacc753a5c538280d045a1bf35549 Mon Sep 17 00:00:00 2001 From: Semyon Pupkov Date: Thu, 20 Sep 2018 22:02:36 +0500 Subject: Fix DynamicAttributeDefinedStatically cop --- spec/factories/broadcast_messages.rb | 12 ++++++------ spec/factories/ci/builds.rb | 6 +++--- spec/factories/ci/runners.rb | 2 +- spec/factories/clusters/applications/helm.rb | 2 +- spec/factories/clusters/platforms/kubernetes.rb | 3 +-- spec/factories/emails.rb | 2 +- spec/factories/gpg_keys.rb | 4 ++-- spec/factories/group_members.rb | 2 +- spec/factories/merge_requests.rb | 2 +- spec/factories/notes.rb | 2 +- spec/factories/oauth_access_grants.rb | 2 +- spec/factories/project_members.rb | 2 +- spec/factories/todos.rb | 2 +- spec/factories/uploads.rb | 10 +++++----- 14 files changed, 26 insertions(+), 27 deletions(-) (limited to 'spec') diff --git a/spec/factories/broadcast_messages.rb b/spec/factories/broadcast_messages.rb index 9a65e7f8a3f..1a2be5e9552 100644 --- a/spec/factories/broadcast_messages.rb +++ b/spec/factories/broadcast_messages.rb @@ -1,17 +1,17 @@ FactoryBot.define do factory :broadcast_message do message "MyText" - starts_at 1.day.ago - ends_at 1.day.from_now + starts_at { 1.day.ago } + ends_at { 1.day.from_now } trait :expired do - starts_at 5.days.ago - ends_at 3.days.ago + starts_at { 5.days.ago } + ends_at { 3.days.ago } end trait :future do - starts_at 5.days.from_now - ends_at 6.days.from_now + starts_at { 5.days.from_now } + ends_at { 6.days.from_now } end end end diff --git a/spec/factories/ci/builds.rb b/spec/factories/ci/builds.rb index 9813190925b..0baa4ecc4e0 100644 --- a/spec/factories/ci/builds.rb +++ b/spec/factories/ci/builds.rb @@ -159,12 +159,12 @@ FactoryBot.define do end trait :erased do - erased_at Time.now + erased_at { Time.now } erased_by factory: :user end trait :queued do - queued_at Time.now + queued_at { Time.now } runner factory: :ci_runner end @@ -194,7 +194,7 @@ FactoryBot.define do end trait :expired do - artifacts_expire_at 1.minute.ago + artifacts_expire_at { 1.minute.ago } end trait :with_commit do diff --git a/spec/factories/ci/runners.rb b/spec/factories/ci/runners.rb index 347e4f433e2..f564e7bee47 100644 --- a/spec/factories/ci/runners.rb +++ b/spec/factories/ci/runners.rb @@ -9,7 +9,7 @@ FactoryBot.define do runner_type :instance_type trait :online do - contacted_at Time.now + contacted_at { Time.now } end trait :instance do diff --git a/spec/factories/clusters/applications/helm.rb b/spec/factories/clusters/applications/helm.rb index c13b0249d94..d76d6a7334a 100644 --- a/spec/factories/clusters/applications/helm.rb +++ b/spec/factories/clusters/applications/helm.rb @@ -29,7 +29,7 @@ FactoryBot.define do trait :timeouted do installing - updated_at ClusterWaitForAppInstallationWorker::TIMEOUT.ago + updated_at { ClusterWaitForAppInstallationWorker::TIMEOUT.ago } end factory :clusters_applications_ingress, class: Clusters::Applications::Ingress do diff --git a/spec/factories/clusters/platforms/kubernetes.rb b/spec/factories/clusters/platforms/kubernetes.rb index 36ac2372204..4a0d1b181ea 100644 --- a/spec/factories/clusters/platforms/kubernetes.rb +++ b/spec/factories/clusters/platforms/kubernetes.rb @@ -3,11 +3,10 @@ FactoryBot.define do cluster namespace nil api_url 'https://kubernetes.example.com' - token 'a' * 40 + token { 'a' * 40 } trait :configured do api_url 'https://kubernetes.example.com' - token 'a' * 40 username 'xxxxxx' password 'xxxxxx' diff --git a/spec/factories/emails.rb b/spec/factories/emails.rb index d23ddf9d79b..feacd5ccf15 100644 --- a/spec/factories/emails.rb +++ b/spec/factories/emails.rb @@ -3,7 +3,7 @@ FactoryBot.define do user email { generate(:email_alias) } - trait(:confirmed) { confirmed_at Time.now } + trait(:confirmed) { confirmed_at { Time.now } } trait(:skip_validate) { to_create {|instance| instance.save(validate: false) } } end end diff --git a/spec/factories/gpg_keys.rb b/spec/factories/gpg_keys.rb index 51b8ddc9934..3c0f43cc1b6 100644 --- a/spec/factories/gpg_keys.rb +++ b/spec/factories/gpg_keys.rb @@ -2,11 +2,11 @@ require_relative '../support/helpers/gpg_helpers' FactoryBot.define do factory :gpg_key do - key GpgHelpers::User1.public_key + key { GpgHelpers::User1.public_key } user factory :gpg_key_with_subkeys do - key GpgHelpers::User1.public_key_with_extra_signing_key + key { GpgHelpers::User1.public_key_with_extra_signing_key } end end end diff --git a/spec/factories/group_members.rb b/spec/factories/group_members.rb index 47036560b9d..12be63e5d92 100644 --- a/spec/factories/group_members.rb +++ b/spec/factories/group_members.rb @@ -9,7 +9,7 @@ FactoryBot.define do trait(:developer) { access_level GroupMember::DEVELOPER } trait(:maintainer) { access_level GroupMember::MAINTAINER } trait(:owner) { access_level GroupMember::OWNER } - trait(:access_request) { requested_at Time.now } + trait(:access_request) { requested_at { Time.now } } trait(:invited) do user_id nil diff --git a/spec/factories/merge_requests.rb b/spec/factories/merge_requests.rb index b8b089b069b..8094c43b065 100644 --- a/spec/factories/merge_requests.rb +++ b/spec/factories/merge_requests.rb @@ -80,7 +80,7 @@ FactoryBot.define do trait :merge_when_pipeline_succeeds do merge_when_pipeline_succeeds true - merge_user author + merge_user { author } end trait :remove_source_branch do diff --git a/spec/factories/notes.rb b/spec/factories/notes.rb index 6844ed8aa4a..2d1f48bf249 100644 --- a/spec/factories/notes.rb +++ b/spec/factories/notes.rb @@ -90,7 +90,7 @@ FactoryBot.define do noteable nil noteable_type 'Commit' noteable_id nil - commit_id RepoHelpers.sample_commit.id + commit_id { RepoHelpers.sample_commit.id } end trait :legacy_diff_note do diff --git a/spec/factories/oauth_access_grants.rb b/spec/factories/oauth_access_grants.rb index 9e6af24c4eb..02c51cd9899 100644 --- a/spec/factories/oauth_access_grants.rb +++ b/spec/factories/oauth_access_grants.rb @@ -3,7 +3,7 @@ FactoryBot.define do resource_owner_id { create(:user).id } application token { Doorkeeper::OAuth::Helpers::UniqueToken.generate } - expires_in 2.hours + expires_in { 2.hours } redirect_uri { application.redirect_uri } scopes { application.scopes } diff --git a/spec/factories/project_members.rb b/spec/factories/project_members.rb index 22a8085ea45..c72e0487895 100644 --- a/spec/factories/project_members.rb +++ b/spec/factories/project_members.rb @@ -8,7 +8,7 @@ FactoryBot.define do trait(:reporter) { access_level ProjectMember::REPORTER } trait(:developer) { access_level ProjectMember::DEVELOPER } trait(:maintainer) { access_level ProjectMember::MAINTAINER } - trait(:access_request) { requested_at Time.now } + trait(:access_request) { requested_at { Time.now } } trait(:invited) do user_id nil diff --git a/spec/factories/todos.rb b/spec/factories/todos.rb index 14486c80341..ed3d87eb76b 100644 --- a/spec/factories/todos.rb +++ b/spec/factories/todos.rb @@ -49,7 +49,7 @@ FactoryBot.define do author user action { Todo::ASSIGNED } - commit_id RepoHelpers.sample_commit.id + commit_id { RepoHelpers.sample_commit.id } target_type "Commit" end end diff --git a/spec/factories/uploads.rb b/spec/factories/uploads.rb index 81c485fba1a..7256f785e1f 100644 --- a/spec/factories/uploads.rb +++ b/spec/factories/uploads.rb @@ -1,7 +1,7 @@ FactoryBot.define do factory :upload do model { build(:project) } - size 100.kilobytes + size { 100.kilobytes } uploader "AvatarUploader" mount_point :avatar secret nil @@ -19,13 +19,13 @@ FactoryBot.define do uploader "PersonalFileUploader" path { File.join(secret, filename) } model { build(:personal_snippet) } - secret SecureRandom.hex + secret { SecureRandom.hex } end trait :issuable_upload do uploader "FileUploader" path { File.join(secret, filename) } - secret SecureRandom.hex + secret { SecureRandom.hex } end trait :with_file do @@ -43,14 +43,14 @@ FactoryBot.define do model { build(:group) } path { File.join(secret, filename) } uploader "NamespaceFileUploader" - secret SecureRandom.hex + secret { SecureRandom.hex } end trait :favicon_upload do model { build(:appearance) } path { File.join(secret, filename) } uploader "FaviconUploader" - secret SecureRandom.hex + secret { SecureRandom.hex } end trait :attachment_upload do -- cgit v1.2.1 From f09303b00aa61825d2fed22aa04d8c6d1dace1b0 Mon Sep 17 00:00:00 2001 From: Mark Chao Date: Fri, 28 Sep 2018 17:54:32 +0800 Subject: Fix MR discussion not loaded issue Display `formatter` as the sole content of `position` object. This means `diff_file` data is not referenced, which is the caseu of "IOError: not opened for reading". --- .../diffs/mock_data/diff_discussions.js | 16 ++-- spec/javascripts/diffs/store/actions_spec.js | 9 +-- spec/javascripts/diffs/store/mutations_spec.js | 16 +--- spec/javascripts/diffs/store/utils_spec.js | 16 +--- spec/javascripts/notes/mock_data.js | 24 ++---- spec/lib/gitlab/diff/position_spec.rb | 88 ++++++++++++++-------- 6 files changed, 82 insertions(+), 87 deletions(-) (limited to 'spec') diff --git a/spec/javascripts/diffs/mock_data/diff_discussions.js b/spec/javascripts/diffs/mock_data/diff_discussions.js index b29a22da7c2..0ad214ea4a4 100644 --- a/spec/javascripts/diffs/mock_data/diff_discussions.js +++ b/spec/javascripts/diffs/mock_data/diff_discussions.js @@ -2,15 +2,13 @@ export default { id: '6b232e05bea388c6b043ccc243ba505faac04ea8', reply_id: '6b232e05bea388c6b043ccc243ba505faac04ea8', position: { - formatter: { - old_line: null, - new_line: 2, - old_path: 'CHANGELOG', - new_path: 'CHANGELOG', - base_sha: 'e63f41fe459e62e1228fcef60d7189127aeba95a', - start_sha: 'd9eaefe5a676b820c57ff18cf5b68316025f7962', - head_sha: 'c48ee0d1bf3b30453f5b32250ce03134beaa6d13', - }, + old_line: null, + new_line: 2, + old_path: 'CHANGELOG', + new_path: 'CHANGELOG', + base_sha: 'e63f41fe459e62e1228fcef60d7189127aeba95a', + start_sha: 'd9eaefe5a676b820c57ff18cf5b68316025f7962', + head_sha: 'c48ee0d1bf3b30453f5b32250ce03134beaa6d13', }, line_code: '1c497fbb3a46b78edf04cc2a2fa33f67e3ffbe2a_1_2', expanded: true, diff --git a/spec/javascripts/diffs/store/actions_spec.js b/spec/javascripts/diffs/store/actions_spec.js index 05b39bad6ea..30cd6a09a0c 100644 --- a/spec/javascripts/diffs/store/actions_spec.js +++ b/spec/javascripts/diffs/store/actions_spec.js @@ -145,12 +145,8 @@ describe('DiffsStoreActions', () => { }, fileHash: 'ABC', resolvable: true, - position: { - formatter: diffPosition, - }, - original_position: { - formatter: diffPosition, - }, + position: diffPosition, + original_position: diffPosition, }; const discussions = reduceDiscussionsToLineCodes([singleDiscussion]); @@ -175,6 +171,7 @@ describe('DiffsStoreActions', () => { oldLine: 5, oldPath: 'file2', lineCode: 'ABC_1_1', + positionType: 'text', }, }, }, diff --git a/spec/javascripts/diffs/store/mutations_spec.js b/spec/javascripts/diffs/store/mutations_spec.js index 9a5d8dfbd15..26bf63c4b99 100644 --- a/spec/javascripts/diffs/store/mutations_spec.js +++ b/spec/javascripts/diffs/store/mutations_spec.js @@ -193,24 +193,16 @@ describe('DiffsStoreMutations', () => { line_code: 'ABC_1', diff_discussion: true, resolvable: true, - original_position: { - formatter: diffPosition, - }, - position: { - formatter: diffPosition, - }, + original_position: diffPosition, + position: diffPosition, }, { id: 2, line_code: 'ABC_1', diff_discussion: true, resolvable: true, - original_position: { - formatter: diffPosition, - }, - position: { - formatter: diffPosition, - }, + original_position: diffPosition, + position: diffPosition, }, ]; diff --git a/spec/javascripts/diffs/store/utils_spec.js b/spec/javascripts/diffs/store/utils_spec.js index 897cd1483aa..85009a5838c 100644 --- a/spec/javascripts/diffs/store/utils_spec.js +++ b/spec/javascripts/diffs/store/utils_spec.js @@ -333,20 +333,12 @@ describe('DiffsStoreUtils', () => { const discussions = { upToDateDiscussion1: { - original_position: { - formatter: diffPosition, - }, - position: { - formatter: wrongDiffPosition, - }, + original_position: diffPosition, + position: wrongDiffPosition, }, outDatedDiscussion1: { - original_position: { - formatter: wrongDiffPosition, - }, - position: { - formatter: wrongDiffPosition, - }, + original_position: wrongDiffPosition, + position: wrongDiffPosition, }, }; diff --git a/spec/javascripts/notes/mock_data.js b/spec/javascripts/notes/mock_data.js index 1f030e5af28..9a0e7f34a9c 100644 --- a/spec/javascripts/notes/mock_data.js +++ b/spec/javascripts/notes/mock_data.js @@ -1177,10 +1177,8 @@ export const discussion1 = { file_path: 'about.md', }, position: { - formatter: { - new_line: 50, - old_line: null, - }, + new_line: 50, + old_line: null, }, notes: [ { @@ -1197,10 +1195,8 @@ export const resolvedDiscussion1 = { file_path: 'about.md', }, position: { - formatter: { - new_line: 50, - old_line: null, - }, + new_line: 50, + old_line: null, }, notes: [ { @@ -1217,10 +1213,8 @@ export const discussion2 = { file_path: 'README.md', }, position: { - formatter: { - new_line: null, - old_line: 20, - }, + new_line: null, + old_line: 20, }, notes: [ { @@ -1237,10 +1231,8 @@ export const discussion3 = { file_path: 'README.md', }, position: { - formatter: { - new_line: 21, - old_line: null, - }, + new_line: 21, + old_line: null, }, notes: [ { diff --git a/spec/lib/gitlab/diff/position_spec.rb b/spec/lib/gitlab/diff/position_spec.rb index 677eb373d22..2d94356f386 100644 --- a/spec/lib/gitlab/diff/position_spec.rb +++ b/spec/lib/gitlab/diff/position_spec.rb @@ -5,6 +5,34 @@ describe Gitlab::Diff::Position do let(:project) { create(:project, :repository) } + let(:args_for_img) do + { + old_path: "files/any.img", + new_path: "files/any.img", + base_sha: nil, + head_sha: nil, + start_sha: nil, + width: 100, + height: 100, + x: 1, + y: 100, + position_type: "image" + } + end + + let(:args_for_text) do + { + old_path: "files/ruby/popen.rb", + new_path: "files/ruby/popen.rb", + old_line: nil, + new_line: 14, + base_sha: nil, + head_sha: nil, + start_sha: nil, + position_type: "text" + } + end + describe "position for an added text file" do let(:commit) { project.commit("2ea1f3dec713d940208fb5ce4a38765ecb5d3f73") } @@ -529,53 +557,49 @@ describe Gitlab::Diff::Position do end end + describe "#as_json" do + shared_examples "diff position json" do + let(:diff_position) { described_class.new(args) } + + it "returns the position as JSON" do + expect(diff_position.as_json).to eq(args.stringify_keys) + end + end + + context "for text positon" do + let(:args) { args_for_text } + + it_behaves_like "diff position json" + end + + context "for image positon" do + let(:args) { args_for_img } + + it_behaves_like "diff position json" + end + end + describe "#to_json" do shared_examples "diff position json" do + let(:diff_position) { described_class.new(args) } + it "returns the position as JSON" do - expect(JSON.parse(diff_position.to_json)).to eq(hash.stringify_keys) + expect(JSON.parse(diff_position.to_json)).to eq(args.stringify_keys) end it "works when nested under another hash" do - expect(JSON.parse(JSON.generate(pos: diff_position))).to eq('pos' => hash.stringify_keys) + expect(JSON.parse(JSON.generate(pos: diff_position))).to eq('pos' => args.stringify_keys) end end context "for text positon" do - let(:hash) do - { - old_path: "files/ruby/popen.rb", - new_path: "files/ruby/popen.rb", - old_line: nil, - new_line: 14, - base_sha: nil, - head_sha: nil, - start_sha: nil, - position_type: "text" - } - end - - let(:diff_position) { described_class.new(hash) } + let(:args) { args_for_text } it_behaves_like "diff position json" end context "for image positon" do - let(:hash) do - { - old_path: "files/any.img", - new_path: "files/any.img", - base_sha: nil, - head_sha: nil, - start_sha: nil, - width: 100, - height: 100, - x: 1, - y: 100, - position_type: "image" - } - end - - let(:diff_position) { described_class.new(hash) } + let(:args) { args_for_img } it_behaves_like "diff position json" end -- cgit v1.2.1 From d49397f747bee52db9d6593e5656f98eb41953e2 Mon Sep 17 00:00:00 2001 From: Tiago Botelho Date: Wed, 3 Oct 2018 15:08:56 +0100 Subject: Instance Configuration page now displays correct SSH fingerprints Replaces the use of OpenSSL::Digest for Gitlab::SSHPublicKey#fingerprint --- spec/fixtures/ssh_host_example_key.pub | 2 +- spec/models/instance_configuration_spec.rb | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'spec') diff --git a/spec/fixtures/ssh_host_example_key.pub b/spec/fixtures/ssh_host_example_key.pub index 6bac42b3ad0..d43315ddae8 100644 --- a/spec/fixtures/ssh_host_example_key.pub +++ b/spec/fixtures/ssh_host_example_key.pub @@ -1 +1 @@ -random content +ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCuRkAgwaap/pXThwCpjX8Wd5tR36Tqx3sW2sVVHs3UKB7kd+xNknw7e4qpuEATv56xHrhKm2+ye/JidTuQ/1EwFhjaz7I5wTslfVawQpeH1ZqAGmvdO/xTw+l7fgEFVlGVx9y0HV3m52y2C9yw82qmg+BohbTVgPtjjutpFc+CwLQxLTnTrRhZf5udQgz+YlwLv+Y0kDx6+DWWOl8N9+TWuGyFKBln79CyBgFcK5NFmF48kYn8W+r7rmawfw9XbuF1aa+6JF+6cNR1mCEonyrRLdXP+vWcxpLKYfejB0NmA1y+W9M/K53AcIHA5zlRQ49tFh0P22eh/Gl8JQ6yyuin foo@bar.mynet diff --git a/spec/models/instance_configuration_spec.rb b/spec/models/instance_configuration_spec.rb index 34db94920f3..cb3d6c7cda2 100644 --- a/spec/models/instance_configuration_spec.rb +++ b/spec/models/instance_configuration_spec.rb @@ -1,11 +1,11 @@ require 'spec_helper' -RSpec.describe InstanceConfiguration do +describe InstanceConfiguration do context 'without cache' do describe '#settings' do describe '#ssh_algorithms_hashes' do - let(:md5) { '54:e0:f8:70:d6:4f:4c:b1:b3:02:44:77:cf:cd:0d:fc' } - let(:sha256) { '9327f0d15a48c4d9f6a3aee65a1825baf9a3412001c98169c5fd022ac27762fc' } + let(:md5) { '5a:65:6c:4d:d4:4c:6d:e6:59:25:b8:cf:ba:34:e7:64' } + let(:sha256) { 'SHA256:2KJDT7xf2i68mBgJ3TVsjISntg4droLbXYLfQj0VvSY' } it 'does not return anything if file does not exist' do stub_pub_file(exist: false) -- cgit v1.2.1 From f3834e9c2d00b20bb7c55cb8845a98f0d8c86443 Mon Sep 17 00:00:00 2001 From: Jacopo Date: Thu, 27 Sep 2018 17:35:15 +0200 Subject: Includes commit stats in POST project commits API --- spec/requests/api/commits_spec.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'spec') diff --git a/spec/requests/api/commits_spec.rb b/spec/requests/api/commits_spec.rb index 06ccf383362..98399471f9a 100644 --- a/spec/requests/api/commits_spec.rb +++ b/spec/requests/api/commits_spec.rb @@ -572,6 +572,20 @@ describe API::Commits do expect(json_response['title']).to eq(message) end + it 'includes the commit stats' do + post api(url, user), valid_mo_params + + expect(response).to have_gitlab_http_status(201) + expect(json_response).to include 'stats' + end + + it "doesn't include the commit stats when stats is false" do + post api(url, user), valid_mo_params.merge(stats: false) + + expect(response).to have_gitlab_http_status(201) + expect(json_response).not_to include 'stats' + end + it 'return a 400 bad request if there are any issues' do post api(url, user), invalid_mo_params -- cgit v1.2.1 From df6e9ed38e7fd4c985a4809b09eedc886ebe6a54 Mon Sep 17 00:00:00 2001 From: Chantal Rollison Date: Fri, 28 Sep 2018 06:47:58 -0700 Subject: Create labels_as_hash_ concern, modify params for method --- spec/services/projects/autocomplete_service_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'spec') diff --git a/spec/services/projects/autocomplete_service_spec.rb b/spec/services/projects/autocomplete_service_spec.rb index e98df375d48..373fe7cb7dd 100644 --- a/spec/services/projects/autocomplete_service_spec.rb +++ b/spec/services/projects/autocomplete_service_spec.rb @@ -148,7 +148,7 @@ describe Projects::AutocompleteService do let!(:label1) { create(:label, project: project) } let!(:label2) { create(:label, project: project) } let!(:sub_group_label) { create(:group_label, group: sub_group) } - let!(:parent_group_label) { create(:group_label, group: group.parent) } + let!(:parent_group_label) { create(:group_label, group: group.parent, group_id: group.id) } before do create(:group_member, group: group, user: user) @@ -156,7 +156,7 @@ describe Projects::AutocompleteService do it 'returns labels from project and ancestor groups' do service = described_class.new(project, user) - results = service.labels_as_hash + results = service.labels_as_hash(nil) expected_labels = [label1, label2, parent_group_label] expect_labels_to_equal(results, expected_labels) -- cgit v1.2.1 From 5a286eb7a3a0c395d35c722ce6a067aca47473f2 Mon Sep 17 00:00:00 2001 From: Paul Slaughter Date: Wed, 3 Oct 2018 01:44:18 -0500 Subject: Add signature badge to diffs/commit_item **Notes:** - Also exposes commit.signature_html in diffs.json --- spec/javascripts/diffs/components/commit_item_spec.js | 18 ++++++++++++++++++ spec/serializers/commit_entity_spec.rb | 16 +++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) (limited to 'spec') diff --git a/spec/javascripts/diffs/components/commit_item_spec.js b/spec/javascripts/diffs/components/commit_item_spec.js index 627fb8c490a..50651d67172 100644 --- a/spec/javascripts/diffs/components/commit_item_spec.js +++ b/spec/javascripts/diffs/components/commit_item_spec.js @@ -9,6 +9,7 @@ import getDiffWithCommit from '../mock_data/diff_with_commit'; const TEST_AUTHOR_NAME = 'test'; const TEST_AUTHOR_EMAIL = 'test+test@gitlab.com'; const TEST_AUTHOR_GRAVATAR = `${TEST_HOST}/avatar/test?s=36`; +const TEST_SIGNATURE_HTML = 'Legit commit'; const getTitleElement = vm => vm.$el.querySelector('.commit-row-message.item-title'); const getDescElement = vm => vm.$el.querySelector('pre.commit-row-description'); @@ -16,6 +17,7 @@ const getDescExpandElement = vm => vm.$el.querySelector('.commit-content .text-e const getShaElement = vm => vm.$el.querySelector('.commit-sha-group'); const getAvatarElement = vm => vm.$el.querySelector('.user-avatar-link'); const getCommitterElement = vm => vm.$el.querySelector('.commiter'); +const getCommitActionsElement = vm => vm.$el.querySelector('.commit-actions'); describe('diffs/components/commit_widget', () => { const Component = Vue.extend(CommitItem); @@ -125,4 +127,20 @@ describe('diffs/components/commit_widget', () => { expect(nameElement).toHaveText(TEST_AUTHOR_NAME); }); }); + + describe('with signature', () => { + beforeEach(done => { + vm.commit.signatureHtml = TEST_SIGNATURE_HTML; + + vm.$nextTick() + .then(done) + .catch(done.fail); + }); + + it('renders signature html', () => { + const actionsElement = getCommitActionsElement(vm); + + expect(actionsElement).toContainHtml(TEST_SIGNATURE_HTML); + }); + }); }); diff --git a/spec/serializers/commit_entity_spec.rb b/spec/serializers/commit_entity_spec.rb index 35215e06f5f..b8cd24c69a6 100644 --- a/spec/serializers/commit_entity_spec.rb +++ b/spec/serializers/commit_entity_spec.rb @@ -1,10 +1,11 @@ require 'spec_helper' describe CommitEntity do + SIGNATURE_HTML = 'TEST'.freeze + let(:entity) do described_class.new(commit, request: request) end - let(:request) { double('request') } let(:project) { create(:project, :repository) } let(:commit) { project.commit } @@ -12,7 +13,11 @@ describe CommitEntity do subject { entity.as_json } before do + render = double('render') + allow(render).to receive(:call).and_return(SIGNATURE_HTML) + allow(request).to receive(:project).and_return(project) + allow(request).to receive(:render).and_return(render) end context 'when commit author is a user' do @@ -70,6 +75,15 @@ describe CommitEntity do expect(subject.fetch(:description_html)).not_to be_nil expect(subject.fetch(:title_html)).not_to be_nil end + + context 'when commit has signature' do + let(:commit) { project.commit(TestEnv::BRANCH_SHA['signed-commits']) } + + it 'exposes "signature_html"' do + expect(request.render).to receive(:call) + expect(subject.fetch(:signature_html)).to be SIGNATURE_HTML + end + end end context 'when commit_url_params is set' do -- cgit v1.2.1 From becb86ea4e8032788b151caac004b2635b57c6a4 Mon Sep 17 00:00:00 2001 From: Paul Slaughter Date: Wed, 3 Oct 2018 04:08:00 -0500 Subject: Add pipeline status to diffs/commit_item **Notes:** - Also exposes commit.pipeline_status_path in diffs.json --- spec/javascripts/diffs/components/commit_item_spec.js | 17 +++++++++++++++++ spec/serializers/commit_entity_spec.rb | 12 +++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) (limited to 'spec') diff --git a/spec/javascripts/diffs/components/commit_item_spec.js b/spec/javascripts/diffs/components/commit_item_spec.js index 50651d67172..8c3376c0eb3 100644 --- a/spec/javascripts/diffs/components/commit_item_spec.js +++ b/spec/javascripts/diffs/components/commit_item_spec.js @@ -10,6 +10,7 @@ const TEST_AUTHOR_NAME = 'test'; const TEST_AUTHOR_EMAIL = 'test+test@gitlab.com'; const TEST_AUTHOR_GRAVATAR = `${TEST_HOST}/avatar/test?s=36`; const TEST_SIGNATURE_HTML = 'Legit commit'; +const TEST_PIPELINE_STATUS_PATH = `${TEST_HOST}/pipeline/status`; const getTitleElement = vm => vm.$el.querySelector('.commit-row-message.item-title'); const getDescElement = vm => vm.$el.querySelector('pre.commit-row-description'); @@ -143,4 +144,20 @@ describe('diffs/components/commit_widget', () => { expect(actionsElement).toContainHtml(TEST_SIGNATURE_HTML); }); }); + + describe('with pipeline status', () => { + beforeEach(done => { + vm.commit.pipelineStatusPath = TEST_PIPELINE_STATUS_PATH; + + vm.$nextTick() + .then(done) + .catch(done.fail); + }); + + it('renders pipeline status', () => { + const actionsElement = getCommitActionsElement(vm); + + expect(actionsElement).toContainElement('.ci-status-link'); + }); + }); }); diff --git a/spec/serializers/commit_entity_spec.rb b/spec/serializers/commit_entity_spec.rb index b8cd24c69a6..b9995818e98 100644 --- a/spec/serializers/commit_entity_spec.rb +++ b/spec/serializers/commit_entity_spec.rb @@ -66,7 +66,7 @@ describe CommitEntity do context 'when type is "full"' do let(:entity) do - described_class.new(commit, request: request, type: :full) + described_class.new(commit, request: request, type: :full, pipeline_ref: project.default_branch, pipeline_project: project) end it 'exposes extra properties' do @@ -84,6 +84,16 @@ describe CommitEntity do expect(subject.fetch(:signature_html)).to be SIGNATURE_HTML end end + + context 'when commit has pipeline' do + before do + create(:ci_pipeline, project: project, sha: commit.id) + end + + it 'exposes "pipeline_status_path"' do + expect(subject.fetch(:pipeline_status_path)).not_to be_nil + end + end end context 'when commit_url_params is set' do -- cgit v1.2.1 From 56f309dd53619b688415b62625a9baa86c837560 Mon Sep 17 00:00:00 2001 From: Thong Kuah Date: Thu, 4 Oct 2018 10:07:28 +1300 Subject: Remove `rbac_clusters` feature flag Now that Auto DevOps can run in a RBAC enabled cluster from https://gitlab.com/gitlab-org/gitlab-ce/issues/51942, we can now remove the FF. As the flag only governed if UI elements would appear or not when creating/adding existing clusters; the effect of removing the FF would be that the checkbox to choose to enable RBAC clusters will now always appear. Remove FF stubs from specs Improve spec context names --- spec/features/projects/clusters/gcp_spec.rb | 4 +--- spec/features/projects/clusters/user_spec.rb | 4 +--- spec/support/services/clusters/create_service_shared.rb | 4 ---- 3 files changed, 2 insertions(+), 10 deletions(-) (limited to 'spec') diff --git a/spec/features/projects/clusters/gcp_spec.rb b/spec/features/projects/clusters/gcp_spec.rb index edc763ad0ad..8b92b9fc869 100644 --- a/spec/features/projects/clusters/gcp_spec.rb +++ b/spec/features/projects/clusters/gcp_spec.rb @@ -84,10 +84,8 @@ describe 'Gcp Cluster', :js do it_behaves_like 'valid cluster gcp form' - context 'rbac_clusters feature flag is enabled' do + context 'RBAC is enabled for the cluster' do before do - stub_feature_flags(rbac_clusters: true) - check 'cluster_provider_gcp_attributes_legacy_abac' end diff --git a/spec/features/projects/clusters/user_spec.rb b/spec/features/projects/clusters/user_spec.rb index 2b4998ed5ac..9ae1dba60b5 100644 --- a/spec/features/projects/clusters/user_spec.rb +++ b/spec/features/projects/clusters/user_spec.rb @@ -44,10 +44,8 @@ describe 'User Cluster', :js do it_behaves_like 'valid cluster user form' - context 'rbac_clusters feature flag is enabled' do + context 'RBAC is enabled for the cluster' do before do - stub_feature_flags(rbac_clusters: true) - check 'cluster_platform_kubernetes_attributes_authorization_type' end diff --git a/spec/support/services/clusters/create_service_shared.rb b/spec/support/services/clusters/create_service_shared.rb index 22f712f3fcf..b0bf942aa09 100644 --- a/spec/support/services/clusters/create_service_shared.rb +++ b/spec/support/services/clusters/create_service_shared.rb @@ -30,10 +30,6 @@ shared_context 'invalid cluster create params' do end shared_examples 'create cluster service success' do - before do - stub_feature_flags(rbac_clusters: false) - end - it 'creates a cluster object and performs a worker' do expect(ClusterProvisionWorker).to receive(:perform_async) -- cgit v1.2.1 From 8661a35e5f20943ff749093f7f8aeb2758d2a993 Mon Sep 17 00:00:00 2001 From: Olivier Gonzalez Date: Thu, 4 Oct 2018 02:23:29 -0400 Subject: Add pipeline.default_branch? mehod Helps to know if the pipeline ref matches the project's default branch --- spec/models/ci/pipeline_spec.rb | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'spec') diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb index 4755702c0e9..ec0bf580115 100644 --- a/spec/models/ci/pipeline_spec.rb +++ b/spec/models/ci/pipeline_spec.rb @@ -1968,4 +1968,34 @@ describe Ci::Pipeline, :mailer do end end end + + describe '#default_branch?' do + let(:default_branch) { 'master'} + + subject { pipeline.default_branch? } + + before do + allow(project).to receive(:default_branch).and_return(default_branch) + end + + context 'when pipeline ref is the default branch of the project' do + let(:pipeline) do + build(:ci_empty_pipeline, status: :created, project: project, ref: default_branch) + end + + it "returns true" do + expect(subject).to be_truthy + end + end + + context 'when pipeline ref is not the default branch of the project' do + let(:pipeline) do + build(:ci_empty_pipeline, status: :created, project: project, ref: 'another_branch') + end + + it "returns false" do + expect(subject).to be_falsey + end + end + end end -- cgit v1.2.1 From 42af229510adfef78772d5ec1cba9b990a645ac3 Mon Sep 17 00:00:00 2001 From: Tomasz Maczukin Date: Mon, 10 Sep 2018 23:57:03 +0200 Subject: Simplify runner registration token resetting This icommit adds several changes related to the same topic - resetting a Runner registration token: 1. On Project settings page it adds a button for resetting the registration token and it removes the Runner token field that was confusing all GitLab users. 2. On Group settings page it adds the same button for resetting the registration token. 3. On Admin Runners settings page it moves the button to the same place as in Project and Group settings and it changes slightly the page layout to make it more similar to Group and Project setting pages. 4. It refactorizes a little the partial that prints runner registration description. Thanks to this Project, Group and Admin settings of the Runner are re-using the same code to generate the button. 5. Updates the translations of changed text. --- .../admin/application_settings_controller_spec.rb | 18 ++++++++++ .../groups/settings/ci_cd_controller_spec.rb | 14 ++++++++ .../projects/settings/ci_cd_controller_spec.rb | 13 ++++++++ spec/features/groups/settings/ci_cd_spec.rb | 39 ++++++++++++++++++++++ .../projects/settings/pipelines_settings_spec.rb | 24 +++++++++++++ 5 files changed, 108 insertions(+) create mode 100644 spec/features/groups/settings/ci_cd_spec.rb (limited to 'spec') diff --git a/spec/controllers/admin/application_settings_controller_spec.rb b/spec/controllers/admin/application_settings_controller_spec.rb index 10e1bfc30f9..2e0f79cd313 100644 --- a/spec/controllers/admin/application_settings_controller_spec.rb +++ b/spec/controllers/admin/application_settings_controller_spec.rb @@ -86,4 +86,22 @@ describe Admin::ApplicationSettingsController do expect(ApplicationSetting.current.receive_max_input_size).to eq(1024) end end + + describe 'PUT #reset_registration_token' do + before do + sign_in(admin) + end + + subject { put :reset_registration_token } + + it 'resets runner registration token' do + expect { subject }.to change { ApplicationSetting.current.runners_registration_token } + end + + it 'redirects the user to admin runners page' do + subject + + expect(response).to redirect_to(admin_runners_path) + end + end end diff --git a/spec/controllers/groups/settings/ci_cd_controller_spec.rb b/spec/controllers/groups/settings/ci_cd_controller_spec.rb index ea18122e0c3..06ccace8242 100644 --- a/spec/controllers/groups/settings/ci_cd_controller_spec.rb +++ b/spec/controllers/groups/settings/ci_cd_controller_spec.rb @@ -17,4 +17,18 @@ describe Groups::Settings::CiCdController do expect(response).to render_template(:show) end end + + describe 'PUT #reset_registration_token' do + subject { put :reset_registration_token, group_id: group } + + it 'resets runner registration token' do + expect { subject }.to change { group.reload.runners_token } + end + + it 'redirects the user to admin runners page' do + subject + + expect(response).to redirect_to(group_settings_ci_cd_path) + end + end end diff --git a/spec/controllers/projects/settings/ci_cd_controller_spec.rb b/spec/controllers/projects/settings/ci_cd_controller_spec.rb index 1f14a0cc381..4629929f9af 100644 --- a/spec/controllers/projects/settings/ci_cd_controller_spec.rb +++ b/spec/controllers/projects/settings/ci_cd_controller_spec.rb @@ -74,6 +74,19 @@ describe Projects::Settings::CiCdController do end end + describe 'PUT #reset_registration_token' do + subject { put :reset_registration_token, namespace_id: project.namespace, project_id: project } + it 'resets runner registration token' do + expect { subject }.to change { project.reload.runners_token } + end + + it 'redirects the user to admin runners page' do + subject + + expect(response).to redirect_to(namespace_project_settings_ci_cd_path) + end + end + describe 'PATCH update' do let(:params) { { ci_config_path: '' } } diff --git a/spec/features/groups/settings/ci_cd_spec.rb b/spec/features/groups/settings/ci_cd_spec.rb new file mode 100644 index 00000000000..d422fd18346 --- /dev/null +++ b/spec/features/groups/settings/ci_cd_spec.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'Group CI/CD settings' do + include WaitForRequests + + let(:user) {create(:user)} + let(:group) {create(:group)} + + before do + group.add_owner(user) + sign_in(user) + end + + describe 'runners registration token' do + let!(:token) { group.runners_token } + + before do + visit group_settings_ci_cd_path(group) + end + + it 'has a registration token' do + expect(page.find('#registration_token')).to have_content(token) + end + + describe 'reload registration token' do + let(:page_token) { find('#registration_token').text } + + before do + click_button 'Reset runners registration token' + end + + it 'changes registration token' do + expect(page_token).not_to eq token + end + end + end +end diff --git a/spec/features/projects/settings/pipelines_settings_spec.rb b/spec/features/projects/settings/pipelines_settings_spec.rb index 30b0a5578ea..6f8ec0015ad 100644 --- a/spec/features/projects/settings/pipelines_settings_spec.rb +++ b/spec/features/projects/settings/pipelines_settings_spec.rb @@ -137,5 +137,29 @@ describe "Projects > Settings > Pipelines settings" do end end end + + describe 'runners registration token' do + let!(:token) { project.runners_token } + + before do + visit project_settings_ci_cd_path(project) + end + + it 'has a registration token' do + expect(page.find('#registration_token')).to have_content(token) + end + + describe 'reload registration token' do + let(:page_token) { find('#registration_token').text } + + before do + click_button 'Reset runners registration token' + end + + it 'changes registration token' do + expect(page_token).not_to eq token + end + end + end end end -- cgit v1.2.1 From 337b2c80f32cbd9986843a04296252d40f9847c5 Mon Sep 17 00:00:00 2001 From: Martin Wortschack Date: Thu, 4 Oct 2018 07:55:37 +0000 Subject: Resolve "Add new "Overview" tab on user profile page" --- spec/features/calendar_spec.rb | 21 ++-- .../dashboard/datetime_on_tooltips_spec.rb | 2 +- spec/features/users/overview_spec.rb | 123 +++++++++++++++++++++ spec/features/users/show_spec.rb | 2 + 4 files changed, 138 insertions(+), 10 deletions(-) create mode 100644 spec/features/users/overview_spec.rb (limited to 'spec') diff --git a/spec/features/calendar_spec.rb b/spec/features/calendar_spec.rb index f08946b0593..aa3ca8923ff 100644 --- a/spec/features/calendar_spec.rb +++ b/spec/features/calendar_spec.rb @@ -64,7 +64,7 @@ describe 'Contributions Calendar', :js do end def selected_day_activities(visible: true) - find('.user-calendar-activities', visible: visible).text + find('.tab-pane#activity .user-calendar-activities', visible: visible).text end before do @@ -74,15 +74,16 @@ describe 'Contributions Calendar', :js do describe 'calendar day selection' do before do visit user.username + page.find('.js-activity-tab a').click wait_for_requests end it 'displays calendar' do - expect(page).to have_css('.js-contrib-calendar') + expect(find('.tab-pane#activity')).to have_css('.js-contrib-calendar') end describe 'select calendar day' do - let(:cells) { page.all('.user-contrib-cell') } + let(:cells) { page.all('.tab-pane#activity .user-contrib-cell') } before do cells[0].click @@ -108,6 +109,7 @@ describe 'Contributions Calendar', :js do describe 'deselect calendar day' do before do cells[0].click + page.find('.js-activity-tab a').click wait_for_requests end @@ -122,6 +124,7 @@ describe 'Contributions Calendar', :js do shared_context 'visit user page' do before do visit user.username + page.find('.js-activity-tab a').click wait_for_requests end end @@ -130,12 +133,12 @@ describe 'Contributions Calendar', :js do include_context 'visit user page' it 'displays calendar activity square color for 1 contribution' do - expect(page).to have_selector(get_cell_color_selector(contribution_count), count: 1) + expect(find('.tab-pane#activity')).to have_selector(get_cell_color_selector(contribution_count), count: 1) end it 'displays calendar activity square on the correct date' do today = Date.today.strftime(date_format) - expect(page).to have_selector(get_cell_date_selector(contribution_count, today), count: 1) + expect(find('.tab-pane#activity')).to have_selector(get_cell_date_selector(contribution_count, today), count: 1) end end @@ -150,7 +153,7 @@ describe 'Contributions Calendar', :js do include_context 'visit user page' it 'displays calendar activity log' do - expect(find('.content_list .event-note')).to have_content issue_title + expect(find('.tab-pane#activity .content_list .event-note')).to have_content issue_title end end end @@ -182,17 +185,17 @@ describe 'Contributions Calendar', :js do include_context 'visit user page' it 'displays calendar activity squares for both days' do - expect(page).to have_selector(get_cell_color_selector(1), count: 2) + expect(find('.tab-pane#activity')).to have_selector(get_cell_color_selector(1), count: 2) end it 'displays calendar activity square for yesterday' do yesterday = Date.yesterday.strftime(date_format) - expect(page).to have_selector(get_cell_date_selector(1, yesterday), count: 1) + expect(find('.tab-pane#activity')).to have_selector(get_cell_date_selector(1, yesterday), count: 1) end it 'displays calendar activity square for today' do today = Date.today.strftime(date_format) - expect(page).to have_selector(get_cell_date_selector(1, today), count: 1) + expect(find('.tab-pane#activity')).to have_selector(get_cell_date_selector(1, today), count: 1) end end end diff --git a/spec/features/dashboard/datetime_on_tooltips_spec.rb b/spec/features/dashboard/datetime_on_tooltips_spec.rb index d7234158fa1..0db8093411b 100644 --- a/spec/features/dashboard/datetime_on_tooltips_spec.rb +++ b/spec/features/dashboard/datetime_on_tooltips_spec.rb @@ -14,7 +14,7 @@ describe 'Tooltips on .timeago dates', :js do updated_at: created_date, created_at: created_date) sign_in user - visit user_path(user) + visit user_activity_path(user) wait_for_requests() page.find('.js-timeago').hover diff --git a/spec/features/users/overview_spec.rb b/spec/features/users/overview_spec.rb new file mode 100644 index 00000000000..11f357cbaa5 --- /dev/null +++ b/spec/features/users/overview_spec.rb @@ -0,0 +1,123 @@ +require 'spec_helper' + +describe 'Overview tab on a user profile', :js do + let(:user) { create(:user) } + let(:contributed_project) { create(:project, :public, :repository) } + + def push_code_contribution + event = create(:push_event, project: contributed_project, author: user) + + create(:push_event_payload, + event: event, + commit_from: '11f9ac0a48b62cef25eedede4c1819964f08d5ce', + commit_to: '1cf19a015df3523caf0a1f9d40c98a267d6a2fc2', + commit_count: 3, + ref: 'master') + end + + before do + sign_in user + end + + describe 'activities section' do + shared_context 'visit overview tab' do + before do + visit user.username + page.find('.js-overview-tab a').click + wait_for_requests + end + end + + describe 'user has no activities' do + include_context 'visit overview tab' + + it 'does not show any entries in the list of activities' do + page.within('.activities-block') do + expect(page).not_to have_selector('.event-item') + end + end + + it 'does not show a link to the activity list' do + expect(find('#js-overview .activities-block')).to have_selector('.js-view-all', visible: false) + end + end + + describe 'user has 3 activities' do + before do + 3.times { push_code_contribution } + end + + include_context 'visit overview tab' + + it 'display 3 entries in the list of activities' do + expect(find('#js-overview')).to have_selector('.event-item', count: 3) + end + end + + describe 'user has 10 activities' do + before do + 10.times { push_code_contribution } + end + + include_context 'visit overview tab' + + it 'displays 5 entries in the list of activities' do + expect(find('#js-overview')).to have_selector('.event-item', count: 5) + end + + it 'shows a link to the activity list' do + expect(find('#js-overview .activities-block')).to have_selector('.js-view-all', visible: true) + end + + it 'links to the activity tab' do + page.within('.activities-block') do + find('.js-view-all').click + wait_for_requests + expect(URI.parse(current_url).path).to eq("/users/#{user.username}/activity") + end + end + end + end + + describe 'projects section' do + shared_context 'visit overview tab' do + before do + visit user.username + page.find('.js-overview-tab a').click + wait_for_requests + end + end + + describe 'user has no personal projects' do + include_context 'visit overview tab' + + it 'it shows an empty project list with an info message' do + page.within('.projects-block') do + expect(page).to have_content('No projects found') + expect(page).not_to have_selector('.project-row') + end + end + + it 'does not show a link to the project list' do + expect(find('#js-overview .projects-block')).to have_selector('.js-view-all', visible: false) + end + end + + describe 'user has a personal project' do + let(:private_project) { create(:project, :private, namespace: user.namespace, creator: user) { |p| p.add_maintainer(user) } } + let!(:private_event) { create(:event, project: private_project, author: user) } + + include_context 'visit overview tab' + + it 'it shows one entry in the list of projects' do + page.within('.projects-block') do + expect(page).to have_selector('.project-row', count: 1) + end + end + + it 'shows a link to the project list' do + expect(find('#js-overview .projects-block')).to have_selector('.js-view-all', visible: true) + end + end + end +end diff --git a/spec/features/users/show_spec.rb b/spec/features/users/show_spec.rb index bc07ab48c39..86379164cf0 100644 --- a/spec/features/users/show_spec.rb +++ b/spec/features/users/show_spec.rb @@ -8,6 +8,7 @@ describe 'User page' do visit(user_path(user)) page.within '.nav-links' do + expect(page).to have_link('Overview') expect(page).to have_link('Activity') expect(page).to have_link('Groups') expect(page).to have_link('Contributed projects') @@ -44,6 +45,7 @@ describe 'User page' do visit(user_path(user)) page.within '.nav-links' do + expect(page).to have_link('Overview') expect(page).to have_link('Activity') expect(page).to have_link('Groups') expect(page).to have_link('Contributed projects') -- cgit v1.2.1 From 4edcb02f94ba832929c054097d2f8badc0a34060 Mon Sep 17 00:00:00 2001 From: Dennis Tang Date: Thu, 4 Oct 2018 08:19:51 +0000 Subject: Resolve "Add status message from within user menu" --- spec/features/profiles/user_edit_profile_spec.rb | 254 ++++++++++++++++++----- 1 file changed, 200 insertions(+), 54 deletions(-) (limited to 'spec') diff --git a/spec/features/profiles/user_edit_profile_spec.rb b/spec/features/profiles/user_edit_profile_spec.rb index 206a3a4fe9a..e168bb0fc89 100644 --- a/spec/features/profiles/user_edit_profile_spec.rb +++ b/spec/features/profiles/user_edit_profile_spec.rb @@ -61,83 +61,229 @@ describe 'User edit profile' do end context 'user status', :js do - def select_emoji(emoji_name) + def select_emoji(emoji_name, is_modal = false) + emoji_menu_class = is_modal ? '.js-modal-status-emoji-menu' : '.js-status-emoji-menu' toggle_button = find('.js-toggle-emoji-menu') toggle_button.click - emoji_button = find(%Q{.js-status-emoji-menu .js-emoji-btn gl-emoji[data-name="#{emoji_name}"]}) + emoji_button = find(%Q{#{emoji_menu_class} .js-emoji-btn gl-emoji[data-name="#{emoji_name}"]}) emoji_button.click end - it 'shows the user status form' do - visit(profile_path) + context 'profile edit form' do + it 'shows the user status form' do + visit(profile_path) - expect(page).to have_content('Current status') - end + expect(page).to have_content('Current status') + end - it 'adds emoji to user status' do - emoji = 'biohazard' - visit(profile_path) - select_emoji(emoji) - submit_settings + it 'adds emoji to user status' do + emoji = 'biohazard' + visit(profile_path) + select_emoji(emoji) + submit_settings - visit user_path(user) - within('.cover-status') do - expect(page).to have_emoji(emoji) + visit user_path(user) + within('.cover-status') do + expect(page).to have_emoji(emoji) + end end - end - it 'adds message to user status' do - message = 'I have something to say' - visit(profile_path) - fill_in 'js-status-message-field', with: message - submit_settings + it 'adds message to user status' do + message = 'I have something to say' + visit(profile_path) + fill_in 'js-status-message-field', with: message + submit_settings - visit user_path(user) - within('.cover-status') do - expect(page).to have_emoji('speech_balloon') - expect(page).to have_content message + visit user_path(user) + within('.cover-status') do + expect(page).to have_emoji('speech_balloon') + expect(page).to have_content message + end end - end - it 'adds message and emoji to user status' do - emoji = 'tanabata_tree' - message = 'Playing outside' - visit(profile_path) - select_emoji(emoji) - fill_in 'js-status-message-field', with: message - submit_settings + it 'adds message and emoji to user status' do + emoji = 'tanabata_tree' + message = 'Playing outside' + visit(profile_path) + select_emoji(emoji) + fill_in 'js-status-message-field', with: message + submit_settings - visit user_path(user) - within('.cover-status') do - expect(page).to have_emoji(emoji) - expect(page).to have_content message + visit user_path(user) + within('.cover-status') do + expect(page).to have_emoji(emoji) + expect(page).to have_content message + end end - end - it 'clears the user status' do - user_status = create(:user_status, user: user, message: 'Eating bread', emoji: 'stuffed_flatbread') + it 'clears the user status' do + user_status = create(:user_status, user: user, message: 'Eating bread', emoji: 'stuffed_flatbread') + + visit user_path(user) + within('.cover-status') do + expect(page).to have_emoji(user_status.emoji) + expect(page).to have_content user_status.message + end + + visit(profile_path) + click_button 'js-clear-user-status-button' + submit_settings - visit user_path(user) - within('.cover-status') do - expect(page).to have_emoji(user_status.emoji) - expect(page).to have_content user_status.message + visit user_path(user) + expect(page).not_to have_selector '.cover-status' end - visit(profile_path) - click_button 'js-clear-user-status-button' - submit_settings + it 'displays a default emoji if only message is entered' do + message = 'a status without emoji' + visit(profile_path) + fill_in 'js-status-message-field', with: message - visit user_path(user) - expect(page).not_to have_selector '.cover-status' + within('.js-toggle-emoji-menu') do + expect(page).to have_emoji('speech_balloon') + end + end end - it 'displays a default emoji if only message is entered' do - message = 'a status without emoji' - visit(profile_path) - fill_in 'js-status-message-field', with: message + context 'user menu' do + def open_user_status_modal + find('.header-user-dropdown-toggle').click + + page.within ".header-user" do + click_button 'Set status' + end + end + + def set_user_status_in_modal + page.within "#set-user-status-modal" do + click_button 'Set status' + end + end + + before do + visit root_path(user) + end + + it 'shows the "Set status" menu item in the user menu' do + find('.header-user-dropdown-toggle').click + + page.within ".header-user" do + expect(page).to have_content('Set status') + end + end + + it 'shows the "Edit status" menu item in the user menu' do + user_status = create(:user_status, user: user, message: 'Eating bread', emoji: 'stuffed_flatbread') + visit root_path(user) + + find('.header-user-dropdown-toggle').click + + page.within ".header-user" do + expect(page).to have_emoji(user_status.emoji) + expect(page).to have_content user_status.message + expect(page).to have_content('Edit status') + end + end + + it 'shows user status modal' do + open_user_status_modal + + expect(page.find('#set-user-status-modal')).to be_visible + expect(page).to have_content('Set a status') + end + + it 'adds emoji to user status' do + emoji = 'biohazard' + open_user_status_modal + select_emoji(emoji, true) + set_user_status_in_modal + + visit user_path(user) + within('.cover-status') do + expect(page).to have_emoji(emoji) + end + end + + it 'adds message to user status' do + message = 'I have something to say' + open_user_status_modal + find('.js-status-message-field').native.send_keys(message) + set_user_status_in_modal + + visit user_path(user) + within('.cover-status') do + expect(page).to have_emoji('speech_balloon') + expect(page).to have_content message + end + end + + it 'adds message and emoji to user status' do + emoji = 'tanabata_tree' + message = 'Playing outside' + open_user_status_modal + select_emoji(emoji, true) + find('.js-status-message-field').native.send_keys(message) + set_user_status_in_modal + + visit user_path(user) + within('.cover-status') do + expect(page).to have_emoji(emoji) + expect(page).to have_content message + end + end + + it 'clears the user status with the "X" button' do + user_status = create(:user_status, user: user, message: 'Eating bread', emoji: 'stuffed_flatbread') + + visit user_path(user) + within('.cover-status') do + expect(page).to have_emoji(user_status.emoji) + expect(page).to have_content user_status.message + end + + find('.header-user-dropdown-toggle').click + + page.within ".header-user" do + click_button 'Edit status' + end + + find('.js-clear-user-status-button').click + set_user_status_in_modal + + visit user_path(user) + expect(page).not_to have_selector '.cover-status' + end + + it 'clears the user status with the "Remove status" button' do + user_status = create(:user_status, user: user, message: 'Eating bread', emoji: 'stuffed_flatbread') + + visit user_path(user) + within('.cover-status') do + expect(page).to have_emoji(user_status.emoji) + expect(page).to have_content user_status.message + end + + find('.header-user-dropdown-toggle').click + + page.within ".header-user" do + click_button 'Edit status' + end + + page.within "#set-user-status-modal" do + click_button 'Remove status' + end + + visit user_path(user) + expect(page).not_to have_selector '.cover-status' + end + + it 'displays a default emoji if only message is entered' do + message = 'a status without emoji' + open_user_status_modal + find('.js-status-message-field').native.send_keys(message) - within('.js-toggle-emoji-menu') do - expect(page).to have_emoji('speech_balloon') + within('.js-toggle-emoji-menu') do + expect(page).to have_emoji('speech_balloon') + end end end end -- cgit v1.2.1 From c0e9eb0eaca198f5ae12d6bd693ddcd705f79369 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jarka=20Ko=C5=A1anov=C3=A1?= Date: Sat, 22 Sep 2018 10:07:20 +0200 Subject: Support short reference to group entities from project entities - add a direct project parent (group) to Banzai context - if an epic is referenced from a direct descendant -> change epic to_reference to use short reference --- spec/models/concerns/cache_markdown_field_spec.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'spec') diff --git a/spec/models/concerns/cache_markdown_field_spec.rb b/spec/models/concerns/cache_markdown_field_spec.rb index da26d802688..f8d50e89d40 100644 --- a/spec/models/concerns/cache_markdown_field_spec.rb +++ b/spec/models/concerns/cache_markdown_field_spec.rb @@ -331,11 +331,12 @@ describe CacheMarkdownField do end context 'with a project' do - let(:thing) { thing_subclass(:project).new(foo: markdown, foo_html: html, project: :project_value) } + let(:project) { create(:project, group: create(:group)) } + let(:thing) { thing_subclass(:project).new(foo: markdown, foo_html: html, project: project) } it 'sets the project in the context' do is_expected.to have_key(:project) - expect(context[:project]).to eq(:project_value) + expect(context[:project]).to eq(project) end it 'invalidates the cache when project changes' do -- cgit v1.2.1 From 600a10b9d14c0d581efd270a68944957af762a17 Mon Sep 17 00:00:00 2001 From: Dmitriy Zaporozhets Date: Thu, 27 Sep 2018 17:19:28 +0300 Subject: Add subscribe filter to labels page Signed-off-by: Dmitriy Zaporozhets --- spec/features/groups/labels/subscription_spec.rb | 50 +++++++++++++++++++++--- spec/finders/group_labels_finder_spec.rb | 19 ++++++--- spec/finders/labels_finder_spec.rb | 10 +++++ spec/models/label_spec.rb | 36 +++++++++++++++++ 4 files changed, 105 insertions(+), 10 deletions(-) (limited to 'spec') diff --git a/spec/features/groups/labels/subscription_spec.rb b/spec/features/groups/labels/subscription_spec.rb index d9543bfa97f..22b51b297a6 100644 --- a/spec/features/groups/labels/subscription_spec.rb +++ b/spec/features/groups/labels/subscription_spec.rb @@ -3,7 +3,8 @@ require 'spec_helper' describe 'Labels subscription' do let(:user) { create(:user) } let(:group) { create(:group) } - let!(:feature) { create(:group_label, group: group, title: 'feature') } + let!(:label1) { create(:group_label, group: group, title: 'foo') } + let!(:label2) { create(:group_label, group: group, title: 'bar') } context 'when signed in' do before do @@ -14,9 +15,9 @@ describe 'Labels subscription' do it 'users can subscribe/unsubscribe to group labels', :js do visit group_labels_path(group) - expect(page).to have_content('feature') + expect(page).to have_content(label1.title) - within "#group_label_#{feature.id}" do + within "#group_label_#{label1.id}" do expect(page).not_to have_button 'Unsubscribe' click_button 'Subscribe' @@ -30,15 +31,48 @@ describe 'Labels subscription' do expect(page).not_to have_button 'Unsubscribe' end end + + context 'subscription filter' do + before do + visit group_labels_path(group) + end + + it 'shows only subscribed labels' do + label1.subscribe(user) + + click_subscribed_tab + + page.within('.labels-container') do + expect(page).to have_content label1.title + end + end + + it 'shows no subscribed labels message' do + click_subscribed_tab + + page.within('.labels-container') do + expect(page).not_to have_content label1.title + expect(page).to have_content('You do not have any subscriptions yet') + end + end + end end context 'when not signed in' do - it 'users can not subscribe/unsubscribe to labels' do + before do visit group_labels_path(group) + end - expect(page).to have_content 'feature' + it 'users can not subscribe/unsubscribe to labels' do + expect(page).to have_content label1.title expect(page).not_to have_button('Subscribe') end + + it 'does not show subscribed tab' do + page.within('.nav-tabs') do + expect(page).not_to have_link 'Subscribed' + end + end end def click_link_on_dropdown(text) @@ -48,4 +82,10 @@ describe 'Labels subscription' do find('a.js-subscribe-button', text: text).click end end + + def click_subscribed_tab + page.within('.nav-tabs') do + click_link 'Subscribed' + end + end end diff --git a/spec/finders/group_labels_finder_spec.rb b/spec/finders/group_labels_finder_spec.rb index ef68fc105e4..7bdd312eff0 100644 --- a/spec/finders/group_labels_finder_spec.rb +++ b/spec/finders/group_labels_finder_spec.rb @@ -4,29 +4,38 @@ require 'spec_helper' describe GroupLabelsFinder, '#execute' do let!(:group) { create(:group) } + let!(:user) { create(:user) } let!(:label1) { create(:group_label, title: 'Foo', description: 'Lorem ipsum', group: group) } let!(:label2) { create(:group_label, title: 'Bar', description: 'Fusce consequat', group: group) } it 'returns all group labels sorted by name if no params' do - result = described_class.new(group).execute + result = described_class.new(user, group).execute expect(result.to_a).to match_array([label2, label1]) end it 'returns all group labels sorted by name desc' do - result = described_class.new(group, sort: 'name_desc').execute + result = described_class.new(user, group, sort: 'name_desc').execute expect(result.to_a).to match_array([label2, label1]) end - it 'returns group labels that march search' do - result = described_class.new(group, search: 'Foo').execute + it 'returns group labels that match search' do + result = described_class.new(user, group, search: 'Foo').execute expect(result.to_a).to match_array([label1]) end + it 'returns group labels user subscribed to' do + label2.subscribe(user) + + result = described_class.new(user, group, subscribed: 'true').execute + + expect(result.to_a).to match_array([label2]) + end + it 'returns second page of labels' do - result = described_class.new(group, page: '2').execute + result = described_class.new(user, group, page: '2').execute expect(result.to_a).to match_array([]) end diff --git a/spec/finders/labels_finder_spec.rb b/spec/finders/labels_finder_spec.rb index f5cec8e349a..9abc52aa664 100644 --- a/spec/finders/labels_finder_spec.rb +++ b/spec/finders/labels_finder_spec.rb @@ -210,5 +210,15 @@ describe LabelsFinder do expect(finder.execute).to eq [project_label_1] end end + + context 'filter by subscription' do + it 'returns labels user subscribed to' do + project_label_1.subscribe(user) + + finder = described_class.new(user, subscribed: 'true') + + expect(finder.execute).to eq [project_label_1] + end + end end end diff --git a/spec/models/label_spec.rb b/spec/models/label_spec.rb index 99670af786a..3fc6c06b7fa 100644 --- a/spec/models/label_spec.rb +++ b/spec/models/label_spec.rb @@ -155,4 +155,40 @@ describe Label do expect(described_class.search('feature')).to be_empty end end + + describe '.subscribed_by' do + let!(:user) { create(:user) } + let!(:label) { create(:label) } + let!(:label2) { create(:label) } + + before do + label.subscribe(user) + end + + it 'returns subscribed labels' do + expect(described_class.subscribed_by(user.id)).to eq([label]) + end + + it 'returns nothing' do + expect(described_class.subscribed_by(0)).to be_empty + end + end + + describe '.optionally_subscribed_by' do + let!(:user) { create(:user) } + let!(:label) { create(:label) } + let!(:label2) { create(:label) } + + before do + label.subscribe(user) + end + + it 'returns subscribed labels' do + expect(described_class.optionally_subscribed_by(user.id)).to eq([label]) + end + + it 'returns all labels if user_id is nil' do + expect(described_class.optionally_subscribed_by(nil)).to match_array([label, label2]) + end + end end -- cgit v1.2.1 From 81bff65fa8342b4e5d995825b1bb3266ff71d6ce Mon Sep 17 00:00:00 2001 From: Filipa Lacerda Date: Thu, 4 Oct 2018 09:27:56 +0100 Subject: Adds MR reference in job sidebar In the refactor the `!` reference was missed This commit adds it back and adds coverage for it. --- spec/javascripts/jobs/components/commit_block_spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'spec') diff --git a/spec/javascripts/jobs/components/commit_block_spec.js b/spec/javascripts/jobs/components/commit_block_spec.js index 61ee993f46a..0bcc4ff940f 100644 --- a/spec/javascripts/jobs/components/commit_block_spec.js +++ b/spec/javascripts/jobs/components/commit_block_spec.js @@ -56,7 +56,7 @@ describe('Commit block', () => { props.mergeRequest.path, ); expect(vm.$el.querySelector('.js-link-commit').textContent.trim()).toEqual( - props.mergeRequest.iid, + `!${props.mergeRequest.iid}`, ); }); }); -- cgit v1.2.1 From 7e3e895d744e3ee4ab3d209e08c835530a239874 Mon Sep 17 00:00:00 2001 From: Steve Azzopardi Date: Thu, 4 Oct 2018 10:59:20 +0200 Subject: Remove addtionalProperties in runners schema This resulted into failure on EE pipeline, for more information follow from https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/7600#note_105310648 onwards. --- spec/fixtures/api/schemas/job/runners.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'spec') diff --git a/spec/fixtures/api/schemas/job/runners.json b/spec/fixtures/api/schemas/job/runners.json index bebb0c88652..646bfd3a82d 100644 --- a/spec/fixtures/api/schemas/job/runners.json +++ b/spec/fixtures/api/schemas/job/runners.json @@ -8,6 +8,5 @@ "online": { "type": "boolean" }, "available": { "type": "boolean" }, "settings_path": { "type": "string" } - }, - "additionalProperties": false + } } -- cgit v1.2.1 From 36a7344901b0caa47083d3685e6044d68cd39c34 Mon Sep 17 00:00:00 2001 From: Sean McGivern Date: Thu, 4 Oct 2018 09:44:30 +0100 Subject: Allow Gitaly N+1s in MR finder spec These can be triggered by project creation in the setup phase if a spec uses the RequestStore, but we really don't care about that - it's not an N+1, it's just several projects being created! --- spec/finders/merge_requests_finder_spec.rb | 32 ++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) (limited to 'spec') diff --git a/spec/finders/merge_requests_finder_spec.rb b/spec/finders/merge_requests_finder_spec.rb index 33d01697c75..ff4c6b8dd42 100644 --- a/spec/finders/merge_requests_finder_spec.rb +++ b/spec/finders/merge_requests_finder_spec.rb @@ -3,21 +3,37 @@ require 'spec_helper' describe MergeRequestsFinder do include ProjectForksHelper + # We need to explicitly permit Gitaly N+1s because of the specs that use + # :request_store. Gitaly N+1 detection is only enabled when :request_store is, + # but we don't care about potential N+1s when we're just creating several + # projects in the setup phase. + def create_project_without_n_plus_1(*args) + Gitlab::GitalyClient.allow_n_plus_1_calls do + create(:project, :public, *args) + end + end + let(:user) { create :user } let(:user2) { create :user } let(:group) { create(:group) } let(:subgroup) { create(:group, parent: group) } - let(:project1) { create(:project, :public, group: group) } - let(:project2) { fork_project(project1, user) } + let(:project1) { create_project_without_n_plus_1(group: group) } + let(:project2) do + Gitlab::GitalyClient.allow_n_plus_1_calls do + fork_project(project1, user) + end + end let(:project3) do - p = fork_project(project1, user) - p.update!(archived: true) - p + Gitlab::GitalyClient.allow_n_plus_1_calls do + p = fork_project(project1, user) + p.update!(archived: true) + p + end end - let(:project4) { create(:project, :public, group: subgroup) } - let(:project5) { create(:project, :public, group: subgroup) } - let(:project6) { create(:project, :public, group: subgroup) } + let(:project4) { create_project_without_n_plus_1(group: subgroup) } + let(:project5) { create_project_without_n_plus_1(group: subgroup) } + let(:project6) { create_project_without_n_plus_1(group: subgroup) } let!(:merge_request1) { create(:merge_request, :simple, author: user, source_project: project2, target_project: project1) } let!(:merge_request2) { create(:merge_request, :conflict, author: user, source_project: project2, target_project: project1, state: 'closed') } -- cgit v1.2.1 From e13baff004810fba3b7fd6eeffc3e4de5af952a1 Mon Sep 17 00:00:00 2001 From: Filipa Lacerda Date: Thu, 4 Oct 2018 12:59:57 +0000 Subject: Renders empty states in the Vue app in Job page --- spec/features/projects/jobs_spec.rb | 12 +- .../jobs/components/empty_state_spec.js | 2 +- spec/javascripts/jobs/components/job_app_spec.js | 139 +++++++++++++++++++++ spec/javascripts/jobs/store/getters_spec.js | 92 ++++++++++++++ 4 files changed, 238 insertions(+), 7 deletions(-) (limited to 'spec') diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb index 6213cabfaad..9fe56d840e1 100644 --- a/spec/features/projects/jobs_spec.rb +++ b/spec/features/projects/jobs_spec.rb @@ -542,7 +542,7 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do visit project_job_path(project, job) end - it 'shows manual action empty state' do + it 'shows manual action empty state', :js do expect(page).to have_content(job.detailed_status(user).illustration[:title]) expect(page).to have_content('This job requires a manual action') expect(page).to have_content('This job depends on a user to trigger its process. Often they are used to deploy code to production environments') @@ -566,14 +566,14 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do visit project_job_path(project, job) end - it 'shows empty state' do + it 'shows empty state', :js do expect(page).to have_content(job.detailed_status(user).illustration[:title]) expect(page).to have_content('This job has not been triggered yet') expect(page).to have_content('This job depends on upstream jobs that need to succeed in order for this job to be triggered') end end - context 'Pending job' do + context 'Pending job', :js do let(:job) { create(:ci_build, :pending, pipeline: pipeline) } before do @@ -600,7 +600,7 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do end end - context 'without log' do + context 'without log', :js do let(:job) { create(:ci_build, :canceled, pipeline: pipeline) } before do @@ -615,7 +615,7 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do end end - context 'Skipped job' do + context 'Skipped job', :js do let(:job) { create(:ci_build, :skipped, pipeline: pipeline) } before do @@ -629,7 +629,7 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do end end - context 'when job is failed but has no trace' do + context 'when job is failed but has no trace', :js do let(:job) { create(:ci_build, :failed, pipeline: pipeline) } it 'renders empty state' do diff --git a/spec/javascripts/jobs/components/empty_state_spec.js b/spec/javascripts/jobs/components/empty_state_spec.js index 872cc1e3864..73488eaab9b 100644 --- a/spec/javascripts/jobs/components/empty_state_spec.js +++ b/spec/javascripts/jobs/components/empty_state_spec.js @@ -67,7 +67,7 @@ describe('Empty State', () => { content, action: { path: 'runner', - title: 'Check runner', + button_title: 'Check runner', method: 'post', }, }); diff --git a/spec/javascripts/jobs/components/job_app_spec.js b/spec/javascripts/jobs/components/job_app_spec.js index c31fa6f9887..e02eb9723fe 100644 --- a/spec/javascripts/jobs/components/job_app_spec.js +++ b/spec/javascripts/jobs/components/job_app_spec.js @@ -37,6 +37,7 @@ describe('Job App ', () => { available: false, }, tags: ['docker'], + has_trace: true, }; const props = { @@ -182,4 +183,142 @@ describe('Job App ', () => { expect(vm.$el.querySelector('.js-job-stuck')).toBeNull(); }); }); + + describe('environments block', () => { + it('renders environment block when job has environment', () => { + store.dispatch( + 'receiveJobSuccess', + Object.assign({}, job, { + deployment_status: { + environment: { + environment_path: '/path', + name: 'foo', + }, + }, + }), + ); + + vm = mountComponentWithStore(Component, { + props, + store, + }); + + expect(vm.$el.querySelector('.js-job-environment')).not.toBeNull(); + }); + + it('does not render environment block when job has environment', () => { + store.dispatch('receiveJobSuccess', job); + + vm = mountComponentWithStore(Component, { + props, + store, + }); + + expect(vm.$el.querySelector('.js-job-environment')).toBeNull(); + }); + }); + + describe('erased block', () => { + it('renders erased block when `erased` is true', () => { + store.dispatch( + 'receiveJobSuccess', + Object.assign({}, job, { + erased: true, + erased_by: { + username: 'root', + web_url: 'gitlab.com/root', + }, + erased_at: '2016-11-07T11:11:16.525Z', + }), + ); + + vm = mountComponentWithStore(Component, { + props, + store, + }); + + expect(vm.$el.querySelector('.js-job-erased')).not.toBeNull(); + }); + + it('does not render erased block when `erased` is false', () => { + store.dispatch('receiveJobSuccess', Object.assign({}, job, { erased: false })); + + vm = mountComponentWithStore(Component, { + props, + store, + }); + + expect(vm.$el.querySelector('.js-job-erased')).toBeNull(); + }); + }); + + describe('empty states block', () => { + it('renders empty state when job does not have trace and is not running', () => { + store.dispatch( + 'receiveJobSuccess', + Object.assign({}, job, { + has_trace: false, + status: { + group: 'pending', + icon: 'status_pending', + label: 'pending', + text: 'pending', + details_path: 'path', + illustration: { + image: 'path', + size: '340', + title: 'Empty State', + content: 'This is an empty state', + }, + action: { + button_title: 'Retry job', + method: 'post', + path: '/path', + }, + }, + }), + ); + + vm = mountComponentWithStore(Component, { + props, + store, + }); + + expect(vm.$el.querySelector('.js-job-empty-state')).not.toBeNull(); + }); + + it('does not render empty state when job does not have trace but it is running', () => { + store.dispatch( + 'receiveJobSuccess', + Object.assign({}, job, { + has_trace: false, + status: { + group: 'running', + icon: 'status_running', + label: 'running', + text: 'running', + details_path: 'path', + }, + }), + ); + + vm = mountComponentWithStore(Component, { + props, + store, + }); + + expect(vm.$el.querySelector('.js-job-empty-state')).toBeNull(); + }); + + it('does not render empty state when job has trace but it is not running', () => { + store.dispatch('receiveJobSuccess', Object.assign({}, job, { has_trace: true })); + + vm = mountComponentWithStore(Component, { + props, + store, + }); + + expect(vm.$el.querySelector('.js-job-empty-state')).toBeNull(); + }); + }); }); diff --git a/spec/javascripts/jobs/store/getters_spec.js b/spec/javascripts/jobs/store/getters_spec.js index 63ef4135d83..160b2f4b34a 100644 --- a/spec/javascripts/jobs/store/getters_spec.js +++ b/spec/javascripts/jobs/store/getters_spec.js @@ -99,12 +99,14 @@ describe('Job Store Getters', () => { expect(getters.hasEnvironment(localState)).toEqual(false); }); }); + describe('with an empty object for `deployment_status`', () => { it('returns false', () => { localState.job.deployment_status = {}; expect(getters.hasEnvironment(localState)).toEqual(false); }); }); + describe('when `deployment_status` is defined and not empty', () => { it('returns true', () => { localState.job.deployment_status = { @@ -118,4 +120,94 @@ describe('Job Store Getters', () => { }); }); }); + + describe('hasTrace', () => { + describe('when has_trace is true', () => { + it('returns true', () => { + localState.job.has_trace = true; + localState.job.status = {}; + + expect(getters.hasTrace(localState)).toEqual(true); + }); + }); + + describe('when job is running', () => { + it('returns true', () => { + localState.job.has_trace = false; + localState.job.status = { group: 'running' }; + + expect(getters.hasTrace(localState)).toEqual(true); + }); + }); + + describe('when has_trace is false and job is not running', () => { + it('returns false', () => { + localState.job.has_trace = false; + localState.job.status = { group: 'pending' }; + + expect(getters.hasTrace(localState)).toEqual(false); + }); + }); + }); + + describe('emptyStateIllustration', () => { + describe('with defined illustration', () => { + it('returns the state illustration object', () => { + localState.job.status = { + illustration: { + path: 'foo', + }, + }; + + expect(getters.emptyStateIllustration(localState)).toEqual({ path: 'foo' }); + }); + }); + + describe('when illustration is not defined', () => { + it('returns an empty object', () => { + expect(getters.emptyStateIllustration(localState)).toEqual({}); + }); + }); + }); + + describe('isJobStuck', () => { + describe('when job is pending and runners are not available', () => { + it('returns true', () => { + localState.job.status = { + group: 'pending', + }; + localState.job.runners = { + available: false, + }; + + expect(getters.isJobStuck(localState)).toEqual(true); + }); + }); + + describe('when job is not pending', () => { + it('returns false', () => { + localState.job.status = { + group: 'running', + }; + localState.job.runners = { + available: false, + }; + + expect(getters.isJobStuck(localState)).toEqual(false); + }); + }); + + describe('when runners are available', () => { + it('returns false', () => { + localState.job.status = { + group: 'pending', + }; + localState.job.runners = { + available: true, + }; + + expect(getters.isJobStuck(localState)).toEqual(false); + }); + }); + }); }); -- cgit v1.2.1 From 819ecd5fb01ab64cacc31253c51984a7564949d7 Mon Sep 17 00:00:00 2001 From: Sean McGivern Date: Tue, 2 Oct 2018 13:39:46 +0100 Subject: Fix N+1 for notification recipients in subscribers --- .../notification_recipient_service_spec.rb | 47 ++++++++++++++++------ 1 file changed, 35 insertions(+), 12 deletions(-) (limited to 'spec') diff --git a/spec/services/notification_recipient_service_spec.rb b/spec/services/notification_recipient_service_spec.rb index 14ba6b7bed2..9a24821860e 100644 --- a/spec/services/notification_recipient_service_spec.rb +++ b/spec/services/notification_recipient_service_spec.rb @@ -10,27 +10,50 @@ describe NotificationRecipientService do let(:issue) { create(:issue, project: project, assignees: [assignee]) } let(:note) { create(:note_on_issue, noteable: issue, project_id: issue.project_id) } - def create_watcher - watcher = create(:user) - create(:notification_setting, source: project, user: watcher, level: :watch) + context 'when there are multiple watchers' do + def create_watcher + watcher = create(:user) + create(:notification_setting, source: project, user: watcher, level: :watch) + + other_projects.each do |other_project| + create(:notification_setting, source: other_project, user: watcher, level: :watch) + end + end + + it 'avoids N+1 queries', :request_store do + create_watcher + + service.build_new_note_recipients(note) + + control_count = ActiveRecord::QueryRecorder.new do + service.build_new_note_recipients(note) + end - other_projects.each do |other_project| - create(:notification_setting, source: other_project, user: watcher, level: :watch) + create_watcher + + expect { service.build_new_note_recipients(note) }.not_to exceed_query_limit(control_count) end end - it 'avoids N+1 queries', :request_store do - create_watcher + context 'when there are multiple subscribers' do + def create_subscriber + subscriber = create(:user) + issue.subscriptions.create(user: subscriber, project: project, subscribed: true) + end - service.build_new_note_recipients(note) + it 'avoids N+1 queries' do + create_subscriber - control_count = ActiveRecord::QueryRecorder.new do service.build_new_note_recipients(note) - end - create_watcher + control_count = ActiveRecord::QueryRecorder.new do + service.build_new_note_recipients(note) + end - expect { service.build_new_note_recipients(note) }.not_to exceed_query_limit(control_count) + create_subscriber + + expect { service.build_new_note_recipients(note) }.not_to exceed_query_limit(control_count) + end end end end -- cgit v1.2.1 From 28e6af88aa16a33717dbdbe870a8423300aef042 Mon Sep 17 00:00:00 2001 From: Sean McGivern Date: Tue, 2 Oct 2018 15:29:45 +0100 Subject: Fix N+1 for notification recipients on private projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If we don't call #to_a, we're relying on the members already being loaded from elsewhere. Otherwise we'll do a separate query for each user: [1] pry(main)> Project.first.team.members.include?(User.first) Project Load (0.7ms) SELECT "projects".* FROM "projects" ORDER BY "projects"."id" ASC LIMIT 1 ↳ (pry):3 User Load (1.8ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1 ↳ (pry):3 User Exists (0.6ms) SELECT 1 AS one FROM "users" INNER JOIN "project_authorizations" ON "users"."id" = "project_authorizations"."user_id" WHERE "project_authorizations"."project_id" = $1 AND "users"."id" = $2 LIMIT 1 [["project_id", 1], ["id", 1]] ↳ (pry):3 => true [2] pry(main)> Project.first.team.members.to_a.include?(User.first) Project Load (12.8ms) SELECT "projects".* FROM "projects" ORDER BY "projects"."id" ASC LIMIT 1 ↳ (pry):1 User Load (9.6ms) SELECT "users".* FROM "users" INNER JOIN "project_authorizations" ON "users"."id" = "project_authorizations"."user_id" WHERE "project_authorizations"."project_id" = $1 [["project_id", 1]] ↳ (pry):1 User Load (0.6ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1 ↳ (pry):1 => true --- .../notification_recipient_service_spec.rb | 44 +++++++++++----------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'spec') diff --git a/spec/services/notification_recipient_service_spec.rb b/spec/services/notification_recipient_service_spec.rb index 9a24821860e..cea5ea125b9 100644 --- a/spec/services/notification_recipient_service_spec.rb +++ b/spec/services/notification_recipient_service_spec.rb @@ -10,18 +10,9 @@ describe NotificationRecipientService do let(:issue) { create(:issue, project: project, assignees: [assignee]) } let(:note) { create(:note_on_issue, noteable: issue, project_id: issue.project_id) } - context 'when there are multiple watchers' do - def create_watcher - watcher = create(:user) - create(:notification_setting, source: project, user: watcher, level: :watch) - - other_projects.each do |other_project| - create(:notification_setting, source: other_project, user: watcher, level: :watch) - end - end - + shared_examples 'no N+1 queries' do it 'avoids N+1 queries', :request_store do - create_watcher + create_user service.build_new_note_recipients(note) @@ -29,30 +20,39 @@ describe NotificationRecipientService do service.build_new_note_recipients(note) end - create_watcher + create_user expect { service.build_new_note_recipients(note) }.not_to exceed_query_limit(control_count) end end + context 'when there are multiple watchers' do + def create_user + watcher = create(:user) + create(:notification_setting, source: project, user: watcher, level: :watch) + + other_projects.each do |other_project| + create(:notification_setting, source: other_project, user: watcher, level: :watch) + end + end + + include_examples 'no N+1 queries' + end + context 'when there are multiple subscribers' do - def create_subscriber + def create_user subscriber = create(:user) issue.subscriptions.create(user: subscriber, project: project, subscribed: true) end - it 'avoids N+1 queries' do - create_subscriber + include_examples 'no N+1 queries' - service.build_new_note_recipients(note) - - control_count = ActiveRecord::QueryRecorder.new do - service.build_new_note_recipients(note) + context 'when the project is private' do + before do + project.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE) end - create_subscriber - - expect { service.build_new_note_recipients(note) }.not_to exceed_query_limit(control_count) + include_examples 'no N+1 queries' end end end -- cgit v1.2.1 From ca665d01e6a7f94fe75ef537577d3aecb2984d17 Mon Sep 17 00:00:00 2001 From: Marc Schwede Date: Thu, 4 Oct 2018 22:04:49 +0000 Subject: Resolve "2FA mobile options should be rephrased" --- spec/features/u2f_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'spec') diff --git a/spec/features/u2f_spec.rb b/spec/features/u2f_spec.rb index f1192f48b86..ae9b65d1a39 100644 --- a/spec/features/u2f_spec.rb +++ b/spec/features/u2f_spec.rb @@ -42,7 +42,7 @@ describe 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do it 'allows registering a new device with a name' do visit profile_account_path manage_two_factor_authentication - expect(page).to have_content("You've already enabled two-factor authentication using mobile") + expect(page).to have_content("You've already enabled two-factor authentication using one time password authenticators") u2f_device = register_u2f_device @@ -70,7 +70,7 @@ describe 'Using U2F (Universal 2nd Factor) Devices for Authentication', :js do it 'allows deleting a device' do visit profile_account_path manage_two_factor_authentication - expect(page).to have_content("You've already enabled two-factor authentication using mobile") + expect(page).to have_content("You've already enabled two-factor authentication using one time password authenticators") first_u2f_device = register_u2f_device second_u2f_device = register_u2f_device(name: 'My other device') -- cgit v1.2.1