diff options
Diffstat (limited to 'spec/support/helpers')
20 files changed, 490 insertions, 45 deletions
diff --git a/spec/support/helpers/database/migration_testing_helpers.rb b/spec/support/helpers/database/migration_testing_helpers.rb new file mode 100644 index 00000000000..916446e66b7 --- /dev/null +++ b/spec/support/helpers/database/migration_testing_helpers.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +module Database + module MigrationTestingHelpers + def define_background_migration(name) + klass = Class.new do + # Can't simply def perform here as we won't have access to the block, + # similarly can't define_method(:perform, &block) here as it would change the block receiver + define_method(:perform) { |*args| yield(*args) } + end + stub_const("Gitlab::BackgroundMigration::#{name}", klass) + klass + end + + def expect_migration_call_counts(migrations_to_calls) + migrations_to_calls.each do |migration, calls| + expect_next_instances_of(migration, calls) do |m| + expect(m).to receive(:perform).and_call_original + end + end + end + + def expect_recorded_migration_runs(migrations_to_runs) + migrations_to_runs.each do |migration, runs| + path = File.join(result_dir, migration.name.demodulize) + if runs.zero? + expect(Pathname(path)).not_to be_exist + else + num_subdirs = Pathname(path).children.count(&:directory?) + expect(num_subdirs).to eq(runs) + end + end + end + + def expect_migration_runs(migrations_to_run_counts) + expect_migration_call_counts(migrations_to_run_counts) + + yield + + expect_recorded_migration_runs(migrations_to_run_counts) + end + end +end diff --git a/spec/support/helpers/features/snippet_helpers.rb b/spec/support/helpers/features/snippet_helpers.rb index dc718b1b212..3e32b0e4c67 100644 --- a/spec/support/helpers/features/snippet_helpers.rb +++ b/spec/support/helpers/features/snippet_helpers.rb @@ -67,14 +67,19 @@ module Spec end def snippet_fill_in_form(title: nil, content: nil, file_name: nil, description: nil, visibility: nil) + if content + snippet_fill_in_content(content) + # It takes some time after sending keys for the vue component to + # update so let Capybara wait for the content before proceeding + expect(page).to have_content(content) + end + snippet_fill_in_title(title) if title snippet_fill_in_description(description) if description snippet_fill_in_file_name(file_name) if file_name - snippet_fill_in_content(content) if content - snippet_fill_in_visibility(visibility) if visibility end end diff --git a/spec/support/helpers/features/sorting_helpers.rb b/spec/support/helpers/features/sorting_helpers.rb index a6428bf8573..50b8083ebb3 100644 --- a/spec/support/helpers/features/sorting_helpers.rb +++ b/spec/support/helpers/features/sorting_helpers.rb @@ -21,6 +21,14 @@ module Spec click_link(value) end end + + # pajamas_sort_by is used to sort new pajamas dropdowns. When + # all of the dropdowns are converted, pajamas_sort_by can be renamed to sort_by + # https://gitlab.com/groups/gitlab-org/-/epics/7551 + def pajamas_sort_by(value) + find('.filter-dropdown-container .dropdown').click + find('.dropdown-item', text: value).click + end end end end diff --git a/spec/support/helpers/filtered_search_helpers.rb b/spec/support/helpers/filtered_search_helpers.rb index b6cf78b9046..93122ca3d0c 100644 --- a/spec/support/helpers/filtered_search_helpers.rb +++ b/spec/support/helpers/filtered_search_helpers.rb @@ -187,4 +187,116 @@ module FilteredSearchHelpers toggle.click if toggle.visible? end end + + ## + # For use with gl-filtered-search + def select_tokens(*args, submit: false) + within '[data-testid="filtered-search-input"]' do + find_field('Search').click + + args.each do |token| + # Move mouse away to prevent invoking tooltips on usernames, which blocks the search input + find_button('Search').hover + + if token == '=' + click_on '= is' + else + click_on token + end + + wait_for_requests + end + end + + if submit + send_keys :enter + end + end + + def get_suggestion_count + all('.gl-filtered-search-suggestion').size + end + + def submit_search_term(value) + click_filtered_search_bar + send_keys(value, :enter) + end + + def click_filtered_search_bar + find('.gl-filtered-search-last-item').click + end + + def click_token_segment(value) + find('.gl-filtered-search-token-segment', text: value).click + end + + def expect_visible_suggestions_list + expect(page).to have_css('.gl-filtered-search-suggestion-list') + end + + def expect_hidden_suggestions_list + expect(page).not_to have_css('.gl-filtered-search-suggestion-list') + end + + def expect_suggestion(value) + expect(page).to have_css('.gl-filtered-search-suggestion', text: value) + end + + def expect_no_suggestion(value) + expect(page).not_to have_css('.gl-filtered-search-suggestion', text: value) + end + + def expect_suggestion_count(count) + expect(page).to have_css('.gl-filtered-search-suggestion', count: count) + end + + def expect_assignee_token(value) + expect(page).to have_css '.gl-filtered-search-token', text: "Assignee = #{value}" + end + + def expect_author_token(value) + expect(page).to have_css '.gl-filtered-search-token', text: "Author = #{value}" + end + + def expect_label_token(value) + expect(page).to have_css '.gl-filtered-search-token', text: "Label = ~#{value}" + end + + def expect_negated_label_token(value) + expect(page).to have_css '.gl-filtered-search-token', text: "Label != ~#{value}" + end + + def expect_milestone_token(value) + expect(page).to have_css '.gl-filtered-search-token', text: "Milestone = %#{value}" + end + + def expect_negated_milestone_token(value) + expect(page).to have_css '.gl-filtered-search-token', text: "Milestone != %#{value}" + end + + def expect_epic_token(value) + expect(page).to have_css '.gl-filtered-search-token', text: "Epic = #{value}" + end + + def expect_search_term(value) + value.split(' ').each do |term| + expect(page).to have_css '.gl-filtered-search-term', text: term + end + end + + def expect_empty_search_term + expect(page).to have_css '.gl-filtered-search-term', text: '' + end + + def expect_token_segment(value) + expect(page).to have_css '.gl-filtered-search-token-segment', text: value + end + + def expect_recent_searches_history_item(value) + expect(page).to have_css '.gl-search-box-by-click-history-item', text: value + end + + def expect_recent_searches_history_item_count(count) + expect(page).to have_css '.gl-search-box-by-click-history-item', count: count + end end diff --git a/spec/support/helpers/gitaly_setup.rb b/spec/support/helpers/gitaly_setup.rb index 0ad83bdeeb2..264281ef94a 100644 --- a/spec/support/helpers/gitaly_setup.rb +++ b/spec/support/helpers/gitaly_setup.rb @@ -31,6 +31,10 @@ module GitalySetup expand_path('tmp/tests/gitaly') end + def runtime_dir + expand_path('tmp/run') + end + def tmp_tests_gitaly_bin_dir File.join(tmp_tests_gitaly_dir, '_build', 'bin') end @@ -102,12 +106,14 @@ module GitalySetup Gitlab.config.repositories.storages[REPOS_STORAGE].legacy_disk_path end - def service_binary(service) + def service_cmd(service, toml = nil) + toml ||= config_path(service) + case service when :gitaly, :gitaly2 - 'gitaly' + [File.join(tmp_tests_gitaly_bin_dir, 'gitaly'), toml] when :praefect - 'praefect' + [File.join(tmp_tests_gitaly_bin_dir, 'praefect'), '-config', toml] end end @@ -132,14 +138,18 @@ module GitalySetup end def start_praefect - start(:praefect) + if ENV['GITALY_PRAEFECT_WITH_DB'] + LOGGER.debug 'Starting Praefect with database election strategy' + start(:praefect, File.join(tmp_tests_gitaly_dir, 'praefect-db.config.toml')) + else + LOGGER.debug 'Starting Praefect with in-memory election strategy' + start(:praefect) + end end def start(service, toml = nil) toml ||= config_path(service) - args = ["#{tmp_tests_gitaly_bin_dir}/#{service_binary(service)}"] - args.push("-config") if service == :praefect - args.push(toml) + args = service_cmd(service, toml) # Ensure user configuration does not affect Git # Context: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58776#note_547613780 @@ -259,6 +269,7 @@ module GitalySetup { 'default' => repos_path }, force: true, options: { + runtime_dir: runtime_dir, prometheus_listen_addr: 'localhost:9236' } ) @@ -267,12 +278,47 @@ module GitalySetup { 'default' => repos_path }, force: true, options: { - runtime_dir: File.join(gitaly_dir, "run2"), + runtime_dir: runtime_dir, gitaly_socket: "gitaly2.socket", config_filename: "gitaly2.config.toml" } ) - Gitlab::SetupHelper::Praefect.create_configuration(gitaly_dir, { 'praefect' => repos_path }, force: true) + + # In CI we need to pre-generate both config files. + # For local testing we'll create the correct file on-demand. + if ENV['CI'] || ENV['GITALY_PRAEFECT_WITH_DB'].nil? + Gitlab::SetupHelper::Praefect.create_configuration( + gitaly_dir, + { 'praefect' => repos_path }, + force: true + ) + end + + if ENV['CI'] || ENV['GITALY_PRAEFECT_WITH_DB'] + Gitlab::SetupHelper::Praefect.create_configuration( + gitaly_dir, + { 'praefect' => repos_path }, + force: true, + options: { + per_repository: true, + config_filename: 'praefect-db.config.toml', + pghost: ENV['CI'] ? 'postgres' : ENV.fetch('PGHOST'), + pgport: ENV['CI'] ? 5432 : ENV.fetch('PGPORT').to_i, + pguser: ENV['CI'] ? 'postgres' : ENV.fetch('USER') + } + ) + end + + # In CI no database is running when Gitaly is set up + # so scripts/gitaly-test-spawn will take care of it instead. + setup_praefect unless ENV['CI'] + end + + def setup_praefect + return unless ENV['GITALY_PRAEFECT_WITH_DB'] + + migrate_cmd = service_cmd(:praefect, File.join(tmp_tests_gitaly_dir, 'praefect-db.config.toml')) + ['sql-migrate'] + system(env, *migrate_cmd, [:out, :err] => 'log/praefect-test.log') end def socket_path(service) @@ -325,7 +371,7 @@ module GitalySetup message += "- The `praefect` binary does not exist: #{praefect_binary}\n" unless File.exist?(praefect_binary) message += "- The `git` binary does not exist: #{git_binary}\n" unless File.exist?(git_binary) - message += "\nCheck log/gitaly-test.log for errors.\n" + message += "\nCheck log/gitaly-test.log & log/praefect-test.log for errors.\n" unless ENV['CI'] message += "\nIf binaries are missing, try running `make -C tmp/tests/gitaly all WITH_BUNDLED_GIT=YesPlease`.\n" diff --git a/spec/support/helpers/graphql_helpers.rb b/spec/support/helpers/graphql_helpers.rb index ff8908e531a..db8d45f61ea 100644 --- a/spec/support/helpers/graphql_helpers.rb +++ b/spec/support/helpers/graphql_helpers.rb @@ -244,15 +244,16 @@ module GraphqlHelpers def graphql_mutation(name, input, fields = nil, &block) raise ArgumentError, 'Please pass either `fields` parameter or a block to `#graphql_mutation`, but not both.' if fields.present? && block_given? + name = name.graphql_name if name.respond_to?(:graphql_name) mutation_name = GraphqlHelpers.fieldnamerize(name) input_variable_name = "$#{input_variable_name_for_mutation(name)}" mutation_field = GitlabSchema.mutation.fields[mutation_name] fields = yield if block_given? - fields ||= all_graphql_fields_for(mutation_field.type.to_graphql) + fields ||= all_graphql_fields_for(mutation_field.type.to_type_signature) query = <<~MUTATION - mutation(#{input_variable_name}: #{mutation_field.arguments['input'].type.to_graphql}) { + mutation(#{input_variable_name}: #{mutation_field.arguments['input'].type.to_type_signature}) { #{mutation_name}(input: #{input_variable_name}) { #{fields} } @@ -264,7 +265,7 @@ module GraphqlHelpers end def variables_for_mutation(name, input) - graphql_input = prepare_input_for_mutation(input) + graphql_input = prepare_variables(input) { input_variable_name_for_mutation(name) => graphql_input } end @@ -273,25 +274,35 @@ module GraphqlHelpers return unless variables return variables if variables.is_a?(String) - ::Gitlab::Utils::MergeHash.merge(Array.wrap(variables).map(&:to_h)).to_json + # Combine variables into a single hash. + hash = ::Gitlab::Utils::MergeHash.merge(Array.wrap(variables).map(&:to_h)) + + prepare_variables(hash).to_json end - # Recursively convert a Hash with Ruby-style keys to GraphQL fieldname-style keys + # Recursively convert any ruby object we can pass as a variable value + # to an object we can serialize with JSON, using fieldname-style keys # - # prepare_input_for_mutation({ 'my_key' => 1 }) - # => { 'myKey' => 1} - def prepare_input_for_mutation(input) - input.to_h do |name, value| - value = prepare_input_for_mutation(value) if value.is_a?(Hash) + # prepare_variables({ 'my_key' => 1 }) + # => { 'myKey' => 1 } + # prepare_variables({ enums: [:FOO, :BAR], user_id: global_id_of(user) }) + # => { 'enums' => ['FOO', 'BAR'], 'userId' => "gid://User/123" } + # prepare_variables({ nested: { hash_values: { are_supported: true } } }) + # => { 'nested' => { 'hashValues' => { 'areSupported' => true } } } + def prepare_variables(input) + return input.map { prepare_variables(_1) } if input.is_a?(Array) + return input.to_s if input.is_a?(GlobalID) || input.is_a?(Symbol) + return input unless input.is_a?(Hash) - [GraphqlHelpers.fieldnamerize(name), value] + input.to_h do |name, value| + [GraphqlHelpers.fieldnamerize(name), prepare_variables(value)] end end def input_variable_name_for_mutation(mutation_name) mutation_name = GraphqlHelpers.fieldnamerize(mutation_name) mutation_field = GitlabSchema.mutation.fields[mutation_name] - input_type = field_type(mutation_field.arguments['input']) + input_type = mutation_field.arguments['input'].type.unwrap.to_type_signature GraphqlHelpers.fieldnamerize(input_type) end @@ -346,6 +357,10 @@ module GraphqlHelpers end end + def query_double(schema:) + double('query', schema: schema) + end + def wrap_fields(fields) fields = Array.wrap(fields).map do |field| case field @@ -646,11 +661,11 @@ module GraphqlHelpers end end - def global_id_of(model, id: nil, model_name: nil) + def global_id_of(model = nil, id: nil, model_name: nil) if id || model_name - ::Gitlab::GlobalId.build(model, id: id, model_name: model_name).to_s + ::Gitlab::GlobalId.as_global_id(id || model.id, model_name: model_name || model.class.name) else - model.to_global_id.to_s + model.to_global_id end end @@ -683,26 +698,94 @@ module GraphqlHelpers end end - # assumes query_string to be let-bound in the current context - def execute_query(query_type, schema: empty_schema, graphql: query_string) + # assumes query_string and user to be let-bound in the current context + def execute_query(query_type, schema: empty_schema, graphql: query_string, raise_on_error: false) schema.query(query_type) - schema.execute( + r = schema.execute( graphql, context: { current_user: user }, variables: {} ) + + if raise_on_error && r.to_h['errors'].present? + raise NoData, r.to_h['errors'] + end + + r end def empty_schema Class.new(GraphQL::Schema) do use GraphQL::Pagination::Connections use Gitlab::Graphql::Pagination::Connections + use BatchLoader::GraphQL lazy_resolve ::Gitlab::Graphql::Lazy, :force end end + # Wrapper around a_hash_including that supports unpacking with ** + class UnpackableMatcher < SimpleDelegator + include RSpec::Matchers + + attr_reader :to_hash + + def initialize(hash) + @to_hash = hash + super(a_hash_including(hash)) + end + + def to_json(_opts = {}) + to_hash.to_json + end + + def as_json(opts = {}) + to_hash.as_json(opts) + end + end + + # Construct a matcher for GraphQL entity response objects, of the form + # `{ "id" => "some-gid" }`. + # + # Usage: + # + # ```ruby + # expect(graphql_data_at(:path, :to, :entity)).to match a_graphql_entity_for(user) + # ``` + # + # This can be called as: + # + # ```ruby + # a_graphql_entity_for(project, :full_path) # also checks that `entity['fullPath'] == project.full_path + # a_graphql_entity_for(project, full_path: 'some/path') # same as above, with explicit values + # a_graphql_entity_for(user, :username, foo: 'bar') # combinations of the above + # a_graphql_entity_for(foo: 'bar') # if properties are defined, the model is not necessary + # ``` + # + # Note that the model instance must not be nil, unless some properties are + # explicitly passed in. The following are rejected with `ArgumentError`: + # + # ``` + # a_graphql_entity_for(nil, :username) + # a_graphql_entity_for(:username) + # a_graphql_entity_for + # ``` + # + def a_graphql_entity_for(model = nil, *fields, **attrs) + raise ArgumentError, 'model is nil' if model.nil? && fields.any? + + attrs.transform_keys! { GraphqlHelpers.fieldnamerize(_1) } + attrs['id'] = global_id_of(model).to_s if model + fields.each do |name| + attrs[GraphqlHelpers.fieldnamerize(name)] = model.public_send(name) + end + + raise ArgumentError, 'no attributes' if attrs.empty? + + UnpackableMatcher.new(attrs) + end + # A lookahead that selects everything def positive_lookahead double(selects?: true).tap do |selection| diff --git a/spec/support/helpers/migrations_helpers.rb b/spec/support/helpers/migrations_helpers.rb index afa7ee84bda..60097e301c4 100644 --- a/spec/support/helpers/migrations_helpers.rb +++ b/spec/support/helpers/migrations_helpers.rb @@ -1,12 +1,18 @@ # frozen_string_literal: true module MigrationsHelpers - def active_record_base - Gitlab::Database.database_base_models.fetch(self.class.metadata[:database] || :main) + def active_record_base(database: nil) + database_name = database || self.class.metadata[:database] || :main + + unless Gitlab::Database::DATABASE_NAMES.include?(database_name.to_s) + raise ArgumentError, "#{database_name} is not a valid argument" + end + + Gitlab::Database.database_base_models[database_name] || Gitlab::Database.database_base_models[:main] end - def table(name) - Class.new(active_record_base) do + def table(name, database: nil) + Class.new(active_record_base(database: database)) do self.table_name = name self.inheritance_column = :_type_disabled @@ -150,6 +156,13 @@ module MigrationsHelpers end def migrate! + open_transactions = ActiveRecord::Base.connection.open_transactions + allow_next_instance_of(described_class) do |migration| + allow(migration).to receive(:transaction_open?) do + ActiveRecord::Base.connection.open_transactions > open_transactions + end + end + migration_context.up do |migration| migration.name == described_class.name end diff --git a/spec/support/helpers/namespaces_test_helper.rb b/spec/support/helpers/namespaces_test_helper.rb new file mode 100644 index 00000000000..9762c38a9bb --- /dev/null +++ b/spec/support/helpers/namespaces_test_helper.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +module NamespacesTestHelper + def get_buy_minutes_path(namespace) + buy_minutes_subscriptions_path(selected_group: namespace.id) + end + + def get_buy_storage_path(namespace) + buy_storage_subscriptions_path(selected_group: namespace.id) + end +end + +NamespacesTestHelper.prepend_mod diff --git a/spec/support/helpers/navbar_structure_helper.rb b/spec/support/helpers/navbar_structure_helper.rb index 315303401cc..e11548d0b75 100644 --- a/spec/support/helpers/navbar_structure_helper.rb +++ b/spec/support/helpers/navbar_structure_helper.rb @@ -93,7 +93,7 @@ module NavbarStructureHelper ) end - def analytics_sub_nav_item + def project_analytics_sub_nav_item [ _('Value stream'), _('CI/CD'), @@ -102,6 +102,12 @@ module NavbarStructureHelper _('Repository') ] end + + def group_analytics_sub_nav_item + [ + _('Contribution') + ] + end end NavbarStructureHelper.prepend_mod diff --git a/spec/support/helpers/next_instance_of.rb b/spec/support/helpers/next_instance_of.rb index 95d8936588c..461d411a5ce 100644 --- a/spec/support/helpers/next_instance_of.rb +++ b/spec/support/helpers/next_instance_of.rb @@ -22,9 +22,15 @@ module NextInstanceOf def stub_new(target, number, ordered = false, *new_args, &blk) receive_new = receive(:new) receive_new.ordered if ordered - receive_new.exactly(number).times if number receive_new.with(*new_args) if new_args.any? + if number.is_a?(Range) + receive_new.at_least(number.begin).times if number.begin + receive_new.at_most(number.end).times if number.end + elsif number + receive_new.exactly(number).times + end + target.to receive_new.and_wrap_original do |method, *original_args| method.call(*original_args).tap(&blk) end diff --git a/spec/support/helpers/project_helpers.rb b/spec/support/helpers/project_helpers.rb index 89f0163b4b6..2ea6405e48c 100644 --- a/spec/support/helpers/project_helpers.rb +++ b/spec/support/helpers/project_helpers.rb @@ -24,4 +24,20 @@ module ProjectHelpers project.update!(params) end + + def create_project_with_statistics(namespace = nil, with_data: false, size_multiplier: 1) + project = namespace.present? ? create(:project, namespace: namespace) : create(:project) + project.tap do |p| + create(:project_statistics, project: p, with_data: with_data, size_multiplier: size_multiplier) + end + end + + def grace_months_after_deletion_notification + (::Gitlab::CurrentSettings.inactive_projects_delete_after_months - + ::Gitlab::CurrentSettings.inactive_projects_send_warning_email_after_months).months + end + + def deletion_date + Date.parse(grace_months_after_deletion_notification.from_now.to_s).to_s + end end diff --git a/spec/support/helpers/query_recorder.rb b/spec/support/helpers/query_recorder.rb index d18a1d23584..01839a74e65 100644 --- a/spec/support/helpers/query_recorder.rb +++ b/spec/support/helpers/query_recorder.rb @@ -80,7 +80,8 @@ module ActiveRecord if values[:cached] && skip_cached @cached << values[:sql] - elsif !skip_schema_queries || !values[:name]&.include?("SCHEMA") + elsif !ignorable?(values) + backtrace = @query_recorder_debug ? show_backtrace(values, duration) : nil @log << values[:sql] store_sql_by_source(values: values, duration: duration, backtrace: backtrace) @@ -102,5 +103,12 @@ module ActiveRecord def occurrences @occurrences ||= @log.group_by(&:to_s).transform_values(&:count) end + + def ignorable?(values) + return true if skip_schema_queries && values[:name]&.include?("SCHEMA") + return true if values[:name]&.match(/License Load/) + + false + end end end diff --git a/spec/support/helpers/rendered_helpers.rb b/spec/support/helpers/rendered_helpers.rb new file mode 100644 index 00000000000..137b7d5f708 --- /dev/null +++ b/spec/support/helpers/rendered_helpers.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +module RenderedHelpers + # Wraps the `rendered` in `expect` to make it the target of an expectation. + # Designed to read nicely for one-liners. + # rubocop:disable RSpec/VoidExpect + def expect_rendered + render + expect(rendered) + end + # rubocop:enable RSpec/VoidExpect +end diff --git a/spec/support/helpers/saas_test_helper.rb b/spec/support/helpers/saas_test_helper.rb new file mode 100644 index 00000000000..a8162603cd9 --- /dev/null +++ b/spec/support/helpers/saas_test_helper.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +module SaasTestHelper + def get_next_url + "https://next.gitlab.com" + end +end + +SaasTestHelper.prepend_mod diff --git a/spec/support/helpers/stub_feature_flags.rb b/spec/support/helpers/stub_feature_flags.rb index 77f31169ecb..f1654e55b7e 100644 --- a/spec/support/helpers/stub_feature_flags.rb +++ b/spec/support/helpers/stub_feature_flags.rb @@ -70,4 +70,18 @@ module StubFeatureFlags def skip_default_enabled_yaml_check allow(Feature::Definition).to receive(:default_enabled?).and_return(false) end + + def stub_feature_flag_definition(name, opts = {}) + opts = opts.with_defaults( + name: name, + type: 'development', + default_enabled: false + ) + + Feature::Definition.new("#{opts[:type]}/#{name}.yml", opts).tap do |definition| + all_definitions = Feature::Definition.definitions + all_definitions[definition.key] = definition + allow(Feature::Definition).to receive(:definitions).and_return(all_definitions) + end + end end diff --git a/spec/support/helpers/stub_object_storage.rb b/spec/support/helpers/stub_object_storage.rb index d49a14f7f5b..024f06cae1b 100644 --- a/spec/support/helpers/stub_object_storage.rb +++ b/spec/support/helpers/stub_object_storage.rb @@ -7,11 +7,6 @@ module StubObjectStorage **params) end - def stub_object_storage_pseudonymizer - stub_object_storage(connection_params: Pseudonymizer::Uploader.object_store_credentials, - remote_directory: Pseudonymizer::Uploader.remote_directory) - end - def stub_object_storage_uploader( config:, uploader:, diff --git a/spec/support/helpers/test_env.rb b/spec/support/helpers/test_env.rb index d81d0d436a1..11f469c1d27 100644 --- a/spec/support/helpers/test_env.rb +++ b/spec/support/helpers/test_env.rb @@ -374,7 +374,7 @@ module TestEnv end def seed_db - Gitlab::DatabaseImporters::WorkItems::BaseTypeImporter.import + Gitlab::DatabaseImporters::WorkItems::BaseTypeImporter.upsert_types end private diff --git a/spec/support/helpers/trial_status_widget_test_helper.rb b/spec/support/helpers/trial_status_widget_test_helper.rb new file mode 100644 index 00000000000..d75620d17ee --- /dev/null +++ b/spec/support/helpers/trial_status_widget_test_helper.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +module TrialStatusWidgetTestHelper + def purchase_href(group) + new_subscriptions_path(namespace_id: group.id, plan_id: 'ultimate-plan-id') + end +end + +TrialStatusWidgetTestHelper.prepend_mod diff --git a/spec/support/helpers/workhorse_helpers.rb b/spec/support/helpers/workhorse_helpers.rb index 83bda6e03b1..6f22df9ae0f 100644 --- a/spec/support/helpers/workhorse_helpers.rb +++ b/spec/support/helpers/workhorse_helpers.rb @@ -114,16 +114,18 @@ module WorkhorseHelpers end params["#{key}.remote_id"] = file.remote_id if file.respond_to?(:remote_id) && file.remote_id.present? + params["#{key}.sha256"] = file.sha256 if file.respond_to?(:sha256) && file.sha256.present? end end - def fog_to_uploaded_file(file) + def fog_to_uploaded_file(file, sha256: nil) filename = File.basename(file.key) UploadedFile.new(nil, filename: filename, remote_id: filename, - size: file.content_length + size: file.content_length, + sha256: sha256 ) end end diff --git a/spec/support/helpers/workhorse_lfs_helpers.rb b/spec/support/helpers/workhorse_lfs_helpers.rb new file mode 100644 index 00000000000..c9644826317 --- /dev/null +++ b/spec/support/helpers/workhorse_lfs_helpers.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +module WorkhorseLfsHelpers + extend self + + def put_finalize( + lfs_tmp = nil, with_tempfile: false, verified: true, remote_object: nil, + args: {}, to_project: nil, size: nil, sha256: nil) + + lfs_tmp ||= "#{sample_oid}012345678" + to_project ||= project + uploaded_file = + if with_tempfile + upload_path = LfsObjectUploader.workhorse_local_upload_path + file_path = upload_path + '/' + lfs_tmp + + FileUtils.mkdir_p(upload_path) + FileUtils.touch(file_path) + File.truncate(file_path, sample_size) + + UploadedFile.new(file_path, filename: File.basename(file_path), sha256: sample_oid) + elsif remote_object + fog_to_uploaded_file(remote_object, sha256: sample_oid) + else + UploadedFile.new( + nil, + size: size || sample_size, + sha256: sha256 || sample_oid, + remote_id: 'remote id' + ) + end + + finalize_headers = headers + finalize_headers.merge!(workhorse_internal_api_request_header) if verified + + workhorse_finalize( + objects_url(to_project, sample_oid, sample_size), + method: :put, + file_key: :file, + params: args.merge(file: uploaded_file), + headers: finalize_headers, + send_rewritten_field: include_workhorse_jwt_header + ) + end +end |