diff options
Diffstat (limited to 'spec/presenters')
4 files changed, 126 insertions, 172 deletions
diff --git a/spec/presenters/issue_email_participant_presenter_spec.rb b/spec/presenters/issue_email_participant_presenter_spec.rb index c270fae3058..993cc9c235b 100644 --- a/spec/presenters/issue_email_participant_presenter_spec.rb +++ b/spec/presenters/issue_email_participant_presenter_spec.rb @@ -3,54 +3,49 @@ require 'spec_helper' RSpec.describe IssueEmailParticipantPresenter, feature_category: :service_desk do - # See https://gitlab.com/gitlab-org/gitlab/-/issues/389247 - # for details around build_stubbed for access level - let_it_be(:non_member) { create(:user) } # rubocop:todo RSpec/FactoryBot/AvoidCreate - let_it_be(:guest) { create(:user) } # rubocop:todo RSpec/FactoryBot/AvoidCreate - let_it_be(:reporter) { create(:user) } # rubocop:todo RSpec/FactoryBot/AvoidCreate - let_it_be(:developer) { create(:user) } # rubocop:todo RSpec/FactoryBot/AvoidCreate - let_it_be(:group) { create(:group) } # rubocop:todo RSpec/FactoryBot/AvoidCreate - let_it_be(:project) { create(:project, group: group) } # rubocop:todo RSpec/FactoryBot/AvoidCreate - let_it_be(:issue) { build_stubbed(:issue, project: project) } - let_it_be(:participant) { build_stubbed(:issue_email_participant, issue: issue, email: 'any@email.com') } - - let(:user) { nil } - let(:presenter) { described_class.new(participant, current_user: user) } + let(:user) { build_stubbed(:user) } + let(:project) { build_stubbed(:project) } + let(:issue) { build_stubbed(:issue, project: project) } + let(:participant) { build_stubbed(:issue_email_participant, issue: issue, email: 'any@example.com') } let(:obfuscated_email) { 'an*****@e*****.c**' } - let(:email) { 'any@email.com' } + let(:email) { 'any@example.com' } - before_all do - group.add_guest(guest) - group.add_reporter(reporter) - group.add_developer(developer) - end + subject(:presenter) { described_class.new(participant, current_user: user) } describe '#email' do subject { presenter.email } - it { is_expected.to eq(obfuscated_email) } + context 'when anonymous' do + let(:user) { nil } + + it { is_expected.to eq(obfuscated_email) } + end context 'with signed in user' do + before do + stub_member_access_level(project, access_level => user) if access_level + end + context 'when user has no role in project' do - let(:user) { non_member } + let(:access_level) { nil } it { is_expected.to eq(obfuscated_email) } end context 'when user has guest role in project' do - let(:user) { guest } + let(:access_level) { :guest } it { is_expected.to eq(obfuscated_email) } end context 'when user has reporter role in project' do - let(:user) { reporter } + let(:access_level) { :reporter } it { is_expected.to eq(email) } end context 'when user has developer role in project' do - let(:user) { developer } + let(:access_level) { :developer } it { is_expected.to eq(email) } end diff --git a/spec/presenters/ml/candidates_csv_presenter_spec.rb b/spec/presenters/ml/candidates_csv_presenter_spec.rb new file mode 100644 index 00000000000..fea00565859 --- /dev/null +++ b/spec/presenters/ml/candidates_csv_presenter_spec.rb @@ -0,0 +1,84 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe ::Ml::CandidatesCsvPresenter, feature_category: :mlops do + # rubocop:disable RSpec/FactoryBot/AvoidCreate + let_it_be(:project) { create(:project, :repository) } + let_it_be(:experiment) { create(:ml_experiments, user_id: project.creator, project: project) } + + let_it_be(:candidate0) do + create(:ml_candidates, experiment: experiment, user: project.creator, + project: project, start_time: 1234, end_time: 5678).tap do |c| + c.params.create!([{ name: 'param1', value: 'p1' }, { name: 'param2', value: 'p2' }]) + c.metrics.create!( + [{ name: 'metric1', value: 0.1 }, { name: 'metric2', value: 0.2 }, { name: 'metric3', value: 0.3 }] + ) + end + end + + let_it_be(:candidate1) do + create(:ml_candidates, experiment: experiment, user: project.creator, name: 'candidate1', + project: project, start_time: 1111, end_time: 2222).tap do |c| + c.params.create([{ name: 'param2', value: 'p3' }, { name: 'param3', value: 'p4' }]) + c.metrics.create!(name: 'metric3', value: 0.4) + end + end + # rubocop:enable RSpec/FactoryBot/AvoidCreate + + describe '.present' do + subject { described_class.new(::Ml::Candidate.where(id: [candidate0.id, candidate1.id])).present } + + it 'generates header row correctly' do + expected_header = %w[project_id experiment_iid candidate_iid name external_id start_time end_time param1 param2 + param3 metric1 metric2 metric3].join(',') + header = subject.split("\n")[0] + + expect(header).to eq(expected_header) + end + + it 'generates the first row correctly' do + expected_row = [ + candidate0.project_id, + 1, # experiment.iid + 1, # candidate0.internal_id + '', # candidate0 has no name, column is empty + candidate0.eid, + candidate0.start_time, + candidate0.end_time, + candidate0.params[0].value, + candidate0.params[1].value, + '', # candidate0 has no param3, column is empty + candidate0.metrics[0].value, + candidate0.metrics[1].value, + candidate0.metrics[2].value + ].map(&:to_s) + + row = subject.split("\n")[1].split(",") + + expect(row).to match_array(expected_row) + end + + it 'generates the second row correctly' do + expected_row = [ + candidate1.project_id, + 1, # experiment.iid + 2, # candidate1.internal_id + 'candidate1', + candidate1.eid, + candidate1.start_time, + candidate1.end_time, + '', # candidate1 has no param1, column is empty + candidate1.params[0].value, + candidate1.params[1].value, + '', # candidate1 has no metric1, column is empty + '', # candidate1 has no metric2, column is empty + candidate1.metrics[0].value + ].map(&:to_s) + + row = subject.split("\n")[2].split(",") + + expect(row).to match_array(expected_row) + end + end +end diff --git a/spec/presenters/packages/npm/package_presenter_spec.rb b/spec/presenters/packages/npm/package_presenter_spec.rb index 4fa469c7cd2..fe4773a9cad 100644 --- a/spec/presenters/packages/npm/package_presenter_spec.rb +++ b/spec/presenters/packages/npm/package_presenter_spec.rb @@ -2,157 +2,32 @@ require 'spec_helper' -RSpec.describe ::Packages::Npm::PackagePresenter do - using RSpec::Parameterized::TableSyntax - - let_it_be(:project) { create(:project) } - let_it_be(:package_name) { "@#{project.root_namespace.path}/test" } - let_it_be(:package1) { create(:npm_package, version: '2.0.4', project: project, name: package_name) } - let_it_be(:package2) { create(:npm_package, version: '2.0.6', project: project, name: package_name) } - let_it_be(:latest_package) { create(:npm_package, version: '2.0.11', project: project, name: package_name) } - - let(:packages) { project.packages.npm.with_name(package_name).last_of_each_version } - let(:presenter) { described_class.new(package_name, packages) } - - describe '#versions' do - let_it_be('package_json') do - { - 'name': package_name, - 'version': '2.0.4', - 'deprecated': 'warning!', - 'bin': './cli.js', - 'directories': ['lib'], - 'engines': { 'npm': '^7.5.6' }, - '_hasShrinkwrap': false, - 'dist': { - 'tarball': 'http://localhost/tarball.tgz', - 'shasum': '1234567890' - }, - 'custom_field': 'foo_bar' - } - end - - let(:presenter) { described_class.new(package_name, packages) } - - subject { presenter.versions } - - where(:has_dependencies, :has_metadatum) do - true | true - false | true - true | false - false | false - end - - with_them do - if params[:has_dependencies] - ::Packages::DependencyLink.dependency_types.keys.each do |dependency_type| - let_it_be("package_dependency_link_for_#{dependency_type}") { create(:packages_dependency_link, package: package1, dependency_type: dependency_type) } - end - end - - if params[:has_metadatum] - let_it_be('package_metadatadum') { create(:npm_metadatum, package: package1, package_json: package_json) } - end - - it { is_expected.to be_a(Hash) } - it { expect(subject[package1.version].with_indifferent_access).to match_schema('public_api/v4/packages/npm_package_version') } - it { expect(subject[package2.version].with_indifferent_access).to match_schema('public_api/v4/packages/npm_package_version') } - it { expect(subject[package1.version]['custom_field']).to be_blank } - - context 'dependencies' do - ::Packages::DependencyLink.dependency_types.keys.each do |dependency_type| - if params[:has_dependencies] - it { expect(subject.dig(package1.version, dependency_type.to_s)).to be_any } - else - it { expect(subject.dig(package1.version, dependency_type)).to be nil } - end - - it { expect(subject.dig(package2.version, dependency_type)).to be nil } - end - end - - context 'metadatum' do - ::Packages::Npm::PackagePresenter::PACKAGE_JSON_ALLOWED_FIELDS.each do |metadata_field| - if params[:has_metadatum] - it { expect(subject.dig(package1.version, metadata_field)).not_to be nil } - else - it { expect(subject.dig(package1.version, metadata_field)).to be nil } - end - - it { expect(subject.dig(package2.version, metadata_field)).to be nil } - end - end +RSpec.describe Packages::Npm::PackagePresenter, feature_category: :package_registry do + let_it_be(:metadata) do + { + name: 'foo', + versions: { '1.0.0' => { 'dist' => { 'tarball' => 'http://localhost/tarball.tgz' } } }, + dist_tags: { 'latest' => '1.0.0' } + } + end - it 'avoids N+1 database queries' do - check_n_plus_one(:versions) do - create_list(:npm_package, 5, project: project, name: package_name).each do |npm_package| - next unless has_dependencies + subject { described_class.new(metadata) } - ::Packages::DependencyLink.dependency_types.keys.each do |dependency_type| - create(:packages_dependency_link, package: npm_package, dependency_type: dependency_type) - end - end - end - end + describe '#name' do + it 'returns the name' do + expect(subject.name).to eq('foo') end + end - context 'with package files pending destruction' do - let_it_be(:package_file_pending_destruction) { create(:package_file, :pending_destruction, package: package2, file_sha1: 'pending_destruction_sha1') } - - let(:shasums) { subject.values.map { |v| v.dig(:dist, :shasum) } } - - it 'does not return them' do - expect(shasums).not_to include(package_file_pending_destruction.file_sha1) - end + describe '#versions' do + it 'returns the versions' do + expect(subject.versions).to eq({ '1.0.0' => { 'dist' => { 'tarball' => 'http://localhost/tarball.tgz' } } }) end end describe '#dist_tags' do - subject { presenter.dist_tags } - - context 'for packages without tags' do - it { is_expected.to be_a(Hash) } - it { expect(subject["latest"]).to eq(latest_package.version) } - - it 'avoids N+1 database queries' do - check_n_plus_one(:dist_tags) do - create_list(:npm_package, 5, project: project, name: package_name) - end - end - end - - context 'for packages with tags' do - let_it_be(:package_tag1) { create(:packages_tag, package: package1, name: 'release_a') } - let_it_be(:package_tag2) { create(:packages_tag, package: package1, name: 'test_release') } - let_it_be(:package_tag3) { create(:packages_tag, package: package2, name: 'release_b') } - let_it_be(:package_tag4) { create(:packages_tag, package: latest_package, name: 'release_c') } - let_it_be(:package_tag5) { create(:packages_tag, package: latest_package, name: 'latest') } - - it { is_expected.to be_a(Hash) } - it { expect(subject[package_tag1.name]).to eq(package1.version) } - it { expect(subject[package_tag2.name]).to eq(package1.version) } - it { expect(subject[package_tag3.name]).to eq(package2.version) } - it { expect(subject[package_tag4.name]).to eq(latest_package.version) } - it { expect(subject[package_tag5.name]).to eq(latest_package.version) } - - it 'avoids N+1 database queries' do - check_n_plus_one(:dist_tags) do - create_list(:npm_package, 5, project: project, name: package_name).each_with_index do |npm_package, index| - create(:packages_tag, package: npm_package, name: "tag_#{index}") - end - end - end + it 'returns the dist_tags' do + expect(subject.dist_tags).to eq({ 'latest' => '1.0.0' }) end end - - def check_n_plus_one(field) - pkgs = project.packages.npm.with_name(package_name).last_of_each_version.preload_files - control = ActiveRecord::QueryRecorder.new { described_class.new(package_name, pkgs).public_send(field) } - - yield - - pkgs = project.packages.npm.with_name(package_name).last_of_each_version.preload_files - - expect { described_class.new(package_name, pkgs).public_send(field) }.not_to exceed_query_limit(control) - end end diff --git a/spec/presenters/project_clusterable_presenter_spec.rb b/spec/presenters/project_clusterable_presenter_spec.rb index dfe4a191ae5..4727bce02a5 100644 --- a/spec/presenters/project_clusterable_presenter_spec.rb +++ b/spec/presenters/project_clusterable_presenter_spec.rb @@ -2,15 +2,15 @@ require 'spec_helper' -RSpec.describe ProjectClusterablePresenter do +RSpec.describe ProjectClusterablePresenter, feature_category: :environment_management do include Gitlab::Routing.url_helpers let(:presenter) { described_class.new(project) } - let(:project) { create(:project) } - let(:cluster) { create(:cluster, :provided_by_gcp, projects: [project]) } + let(:project) { build_stubbed(:project) } + let(:cluster) { build_stubbed(:cluster, :provided_by_gcp, projects: [project]) } describe '#can_create_cluster?' do - let(:user) { create(:user) } + let(:user) { build_stubbed(:user) } subject { presenter.can_create_cluster? } @@ -20,7 +20,7 @@ RSpec.describe ProjectClusterablePresenter do context 'when user can create' do before do - project.add_maintainer(user) + stub_member_access_level(project, maintainer: user) end it { is_expected.to be_truthy } |