diff --git a/app/models/concerns/rubygem_searchable.rb b/app/models/concerns/rubygem_searchable.rb index 27eee6ad34f..24532a7255e 100644 --- a/app/models/concerns/rubygem_searchable.rb +++ b/app/models/concerns/rubygem_searchable.rb @@ -2,8 +2,7 @@ module RubygemSearchable extend ActiveSupport::Concern included do - searchkick index_name: Gemcutter::SEARCH_INDEX_NAME, - callbacks: false, + searchkick callbacks: false, settings: { number_of_shards: 1, number_of_replicas: Gemcutter::SEARCH_NUM_REPLICAS, diff --git a/test/factories/rubygem.rb b/test/factories/rubygem.rb index 285e833a735..039102f025a 100644 --- a/test/factories/rubygem.rb +++ b/test/factories/rubygem.rb @@ -9,6 +9,12 @@ name + trait :reindex do + after(:create) do |rubygem, _evaluator| + rubygem.reindex(refresh: true) + end + end + after(:build) do |rubygem, evaluator| if evaluator.linkset rubygem.linkset = evaluator.linkset diff --git a/test/factories/version.rb b/test/factories/version.rb index 520cdb82c8e..dba960ef4d8 100644 --- a/test/factories/version.rb +++ b/test/factories/version.rb @@ -20,6 +20,12 @@ sha256 { "tdQEXD9Gb6kf4sxqvnkjKhpXzfEE96JucW4KHieJ33g=" } spec_sha256 { Digest::SHA2.base64digest("#{rubygem.name}-#{number}-#{platform}") } + trait :reindex do + after(:create) do |version| + version.rubygem.reindex(refresh: true) + end + end + trait :yanked do indexed { false } end diff --git a/test/functional/api/v1/searches_controller_test.rb b/test/functional/api/v1/searches_controller_test.rb index cb70b5c1aff..4132e123d83 100644 --- a/test/functional/api/v1/searches_controller_test.rb +++ b/test/functional/api/v1/searches_controller_test.rb @@ -39,9 +39,8 @@ def self.should_respond_to(format) setup do @match = create(:rubygem, name: "match") @other = create(:rubygem, name: "other") - create(:version, rubygem: @match) - create(:version, rubygem: @other) - import_and_refresh + create(:version, :reindex, rubygem: @match) + create(:version, :reindex, rubygem: @other) end should_respond_to(:json) do |body| @@ -79,10 +78,9 @@ def self.should_respond_to(format) @match1 = create(:rubygem, name: "match1") @match2 = create(:rubygem, name: "match2") @other = create(:rubygem, name: "other") - create(:version, rubygem: @match1) - create(:version, rubygem: @match2) - create(:version, rubygem: @other) - import_and_refresh + create(:version, :reindex, rubygem: @match1) + create(:version, :reindex, rubygem: @match2) + create(:version, :reindex, rubygem: @other) end context "with elasticsearch up" do diff --git a/test/functional/searches_controller_test.rb b/test/functional/searches_controller_test.rb index 050f11b5236..9420a9d486c 100644 --- a/test/functional/searches_controller_test.rb +++ b/test/functional/searches_controller_test.rb @@ -15,8 +15,7 @@ class SearchesControllerTest < ActionController::TestCase context "on GET to show with search parameters for a rubygem without versions" do setup do - @sinatra = create(:rubygem, name: "sinatra") - import_and_refresh + @sinatra = create(:rubygem, :reindex, name: "sinatra") assert_nil @sinatra.most_recent_version assert_predicate @sinatra.reload.versions.count, :zero? @@ -35,10 +34,10 @@ class SearchesControllerTest < ActionController::TestCase @sinatra = create(:rubygem, name: "sinatra") @sinatra_redux = create(:rubygem, name: "sinatra-redux") @brando = create(:rubygem, name: "brando") - create(:version, rubygem: @sinatra) - create(:version, rubygem: @sinatra_redux) - create(:version, rubygem: @brando) - import_and_refresh + create(:version, :reindex, rubygem: @sinatra) + create(:version, :reindex, rubygem: @sinatra_redux) + create(:version, :reindex, rubygem: @brando) + get :show, params: { query: "sinatra" } end @@ -61,10 +60,9 @@ class SearchesControllerTest < ActionController::TestCase @sinatra = create(:rubygem, name: "sinatra") @sinatra_redux = create(:rubygem, name: "sinatra-redux") @brando = create(:rubygem, name: "brando") - create(:version, rubygem: @sinatra) - create(:version, rubygem: @sinatra_redux) - create(:version, rubygem: @brando) - import_and_refresh + create(:version, :reindex, rubygem: @sinatra) + create(:version, :reindex, rubygem: @sinatra_redux) + create(:version, :reindex, rubygem: @brando) get :show, params: { query: "sinatra" } end @@ -103,10 +101,9 @@ class SearchesControllerTest < ActionController::TestCase @sinatra = create(:rubygem, name: "sinatra") @sinatra_redux = create(:rubygem, name: "sinatra-redux") @brando = create(:rubygem, name: "brando") - create(:version, rubygem: @sinatra) - create(:version, rubygem: @sinatra_redux) - create(:version, rubygem: @brando) - import_and_refresh + create(:version, :reindex, rubygem: @sinatra) + create(:version, :reindex, rubygem: @sinatra_redux) + create(:version, :reindex, rubygem: @brando) get :show, params: { query: "sinatre" } end @@ -132,9 +129,8 @@ class SearchesControllerTest < ActionController::TestCase setup do @sinatra = create(:rubygem, name: "sinatra") @sinatra_redux = create(:rubygem, name: "sinatra-redux") - create(:version, rubygem: @sinatra) - create(:version, :yanked, rubygem: @sinatra_redux) - import_and_refresh + create(:version, :reindex, rubygem: @sinatra) + create(:version, :yanked, :reindex, rubygem: @sinatra_redux) get :show, params: { query: @sinatra_redux.name.to_s, yanked: true } end diff --git a/test/helpers/es_helper.rb b/test/helpers/es_helper.rb index 47552fd0548..92aee617843 100644 --- a/test/helpers/es_helper.rb +++ b/test/helpers/es_helper.rb @@ -1,11 +1,4 @@ module SearchKickHelper - def import_and_refresh - Rubygem.searchkick_reindex - - # wait for indexing to finish - Searchkick.client.cluster.health wait_for_status: "yellow" - end - def es_downloads(id) response = get_response(id) response["_source"]["downloads"] @@ -17,7 +10,6 @@ def es_version_downloads(id) end def get_response(id) - Rubygem.searchkick_index.refresh - Searchkick.client.get index: "rubygems-#{Rails.env}", id: id + Searchkick.client.get index: Rubygem.search_index.name, id: id end end diff --git a/test/integration/gems_test.rb b/test/integration/gems_test.rb index 4a16312365f..362838d64aa 100644 --- a/test/integration/gems_test.rb +++ b/test/integration/gems_test.rb @@ -66,181 +66,4 @@ class GemsTest < ActionDispatch::IntegrationTest assert_response :success end -end - -class GemsSystemTest < SystemTest - setup do - @user = create(:user) - @rubygem = create(:rubygem, name: "sandworm", number: "1.0.0") - @version = create(:version, rubygem: @rubygem, number: "1.1.1") - end - - test "version navigation" do - visit rubygem_version_path(@rubygem.slug, "1.0.0") - click_link "Next version →" - - assert_equal page.current_path, rubygem_version_path(@rubygem.slug, "1.1.1") - click_link "← Previous version" - - assert_equal page.current_path, rubygem_version_path(@rubygem.slug, "1.0.0") - end - - test "subscribe to a gem" do - visit rubygem_path(@rubygem.slug, as: @user.id) - - assert page.has_css?("a#subscribe") - - click_link "Subscribe" - - assert page.has_content? "Unsubscribe" - assert_equal @user.subscribed_gems.first, @rubygem - end - - test "unsubscribe to a gem" do - create(:subscription, rubygem: @rubygem, user: @user) - - visit rubygem_path(@rubygem.slug, as: @user.id) - - assert page.has_css?("a#unsubscribe") - - click_link "Unsubscribe" - - assert page.has_content? "Subscribe" - assert_empty @user.subscribed_gems - end - - test "shows enable MFA instructions when logged in as owner with MFA disabled" do - create(:ownership, rubygem: @rubygem, user: @user) - - visit rubygem_path(@rubygem.slug, as: @user.id) - - assert page.has_selector?(".gem__users__mfa-disabled .gem__users a") - assert page.has_content? "Please consider enabling multi-factor" - end - - test "shows owners without mfa when logged in as owner" do - @user.enable_totp!("some-seed", "ui_and_api") - user_without_mfa = create(:user) - - create(:ownership, rubygem: @rubygem, user: @user) - create(:ownership, rubygem: @rubygem, user: user_without_mfa) - - visit rubygem_path(@rubygem.slug, as: @user.id) - - assert page.has_selector?(".gem__users__mfa-disabled .gem__users a") - assert page.has_selector?(".gem__users__mfa-text.mfa-warn") - end - - test "show mfa enabled when logged in as owner but everyone has mfa enabled" do - @user.enable_totp!("some-seed", "ui_and_api") - user_with_mfa = create(:user) - user_with_mfa.enable_totp!("some-seed", "ui_and_api") - - create(:ownership, rubygem: @rubygem, user: @user) - create(:ownership, rubygem: @rubygem, user: user_with_mfa) - - visit rubygem_path(@rubygem.slug, as: @user.id) - - assert page.has_no_selector?(".gem__users__mfa-text.mfa-warn") - assert page.has_selector?(".gem__users__mfa-text.mfa-info") - end - - test "does not show owners without mfa when not logged in as owner" do - @user.enable_totp!("some-seed", "ui_and_api") - user_without_mfa = create(:user) - - create(:ownership, rubygem: @rubygem, user: @user) - create(:ownership, rubygem: @rubygem, user: user_without_mfa) - - visit rubygem_path(@rubygem.slug) - - assert page.has_no_selector?(".gem__users__mfa-disabled .gem__users a") - assert page.has_no_selector?(".gem__users__mfa-text.mfa-warn") - assert page.has_no_selector?(".gem__users__mfa-text.mfa-info") - end - - test "shows github link when source_code_uri is set" do - github_link = "http://github.com/user/project" - create(:version, number: "3.0.1", rubygem: @rubygem, metadata: { "source_code_uri" => github_link }) - - visit rubygem_path(@rubygem.slug) - - assert page.has_selector?(".github-btn") - end - - test "shows github link when homepage_uri is set" do - github_link = "http://github.com/user/project" - create(:version, number: "3.0.1", rubygem: @rubygem, metadata: { "homepage_uri" => github_link }) - - visit rubygem_path(@rubygem.slug) - - assert page.has_selector?(".github-btn") - end - - test "does not show github link when homepage_uri is not github" do - notgithub_link = "http://notgithub.com/user/project" - create(:version, number: "3.0.1", rubygem: @rubygem, metadata: { "homepage_uri" => notgithub_link }) - - visit rubygem_path(@rubygem.slug) - - assert page.has_no_selector?(".github-btn") - end - - test "shows both mfa headers if latest AND viewed version require MFA" do - @version.update_attribute :metadata, { "rubygems_mfa_required" => "true" } - create(:version, :mfa_required, rubygem: @rubygem, number: "0.1.1") - - visit rubygem_version_path(@rubygem.slug, "0.1.1") - - assert page.has_content? "New versions require MFA" - assert page.has_content? "Version published with MFA" - end - - test "shows 'new' mfa header only if latest requires MFA but viewed version doesn't" do - @version.update_attribute :metadata, { "rubygems_mfa_required" => "true" } - create(:version, rubygem: @rubygem, number: "0.1.1") - - visit rubygem_version_path(@rubygem.slug, "0.1.1") - - assert page.has_content? "New versions require MFA" - refute page.has_content? "Version published with MFA" - end - - test "shows 'version' mfa header only if latest does not require MFA but viewed version does" do - @version.update_attribute :metadata, { "rubygems_mfa_required" => "false" } - create(:version, :mfa_required, rubygem: @rubygem, number: "0.1.1") - - visit rubygem_version_path(@rubygem.slug, "0.1.1") - - refute page.has_content? "New versions require MFA" - assert page.has_content? "Version published with MFA" - end - - test "does not show either mfa header if neither latest or viewed version require MFA" do - @version.update_attribute :metadata, { "rubygems_mfa_required" => "false" } - create(:version, rubygem: @rubygem, number: "0.1.1") - - visit rubygem_version_path(@rubygem.slug, "0.1.1") - - refute page.has_content? "New versions require MFA" - refute page.has_content? "Version published with MFA" - end - - test "shows both mfa headers if MFA enabled for latest version and viewing latest version" do - @version.update_attribute :metadata, { "rubygems_mfa_required" => "true" } - - visit rubygem_path(@rubygem.slug) - - assert page.has_content? "New versions require MFA" - assert page.has_content? "Version published with MFA" - end - - test "shows neither mfa header if MFA disabled for latest version and viewing latest version" do - @version.update_attribute :metadata, { "rubygems_mfa_required" => "false" } - - visit rubygem_path(@rubygem.slug) - - refute page.has_content? "New versions require MFA" - refute page.has_content? "Version published with MFA" - end -end +end \ No newline at end of file diff --git a/test/integration/locale_test.rb b/test/integration/locale_test.rb index 217ebf30c4d..17d5268abdb 100644 --- a/test/integration/locale_test.rb +++ b/test/integration/locale_test.rb @@ -1,6 +1,6 @@ require "test_helper" -class LocaleTest < SystemTest +class LocaleTest < ActionDispatch::IntegrationTest test "html lang attribute is set from locale" do I18n.available_locales.each do |locale| visit root_path(locale: locale) diff --git a/test/jobs/fastly_log_processor_job_test.rb b/test/jobs/fastly_log_processor_job_test.rb index ed5d46b048f..e240840925c 100644 --- a/test/jobs/fastly_log_processor_job_test.rb +++ b/test/jobs/fastly_log_processor_job_test.rb @@ -21,7 +21,6 @@ class FastlyLogProcessorJobTest < ActiveJob::TestCase @processor = FastlyLogProcessor.new("test-bucket", "fastly-fake.log") @job = FastlyLogProcessorJob.new(bucket: "test-bucket", key: "fastly-fake.log") create(:gem_download) - import_and_refresh end teardown do @@ -58,8 +57,6 @@ class FastlyLogProcessorJobTest < ActiveJob::TestCase create(:version, rubygem: json, number: "1.8.3", platform: "java") create(:version, rubygem: json, number: "1.8.3") create(:version, rubygem: json, number: "1.8.2") - - import_and_refresh end context "#perform" do @@ -69,6 +66,8 @@ class FastlyLogProcessorJobTest < ActiveJob::TestCase assert_equal 0, GemDownload.count_for_rubygem(json.id) 3.times { @job.perform_now } + json.reindex(refresh: true) + assert_equal 7, es_downloads(json.id) assert_equal 7, GemDownload.count_for_rubygem(json.id) end @@ -85,6 +84,7 @@ class FastlyLogProcessorJobTest < ActiveJob::TestCase end json = Rubygem.find_by_name("json") + json.reindex(refresh: true) assert_equal 7, GemDownload.count_for_rubygem(json.id) assert_equal 7, es_downloads(json.id) @@ -93,6 +93,7 @@ class FastlyLogProcessorJobTest < ActiveJob::TestCase should "not run if already processed" do json = Rubygem.find_by_name("json") + json.reindex(refresh: true) assert_equal 0, json.downloads assert_equal 0, es_downloads(json.id) @@ -119,6 +120,7 @@ class FastlyLogProcessorJobTest < ActiveJob::TestCase @job.perform_now json = Rubygem.find_by_name("json") + json.reindex(refresh: true) assert_equal 0, json.downloads assert_equal 0, es_downloads(json.id) diff --git a/test/models/concerns/rubygem_searchable_test.rb b/test/models/concerns/rubygem_searchable_test.rb index d7089196e78..35c9fa7906e 100644 --- a/test/models/concerns/rubygem_searchable_test.rb +++ b/test/models/concerns/rubygem_searchable_test.rb @@ -3,10 +3,6 @@ class RubygemSearchableTest < ActiveSupport::TestCase include SearchKickHelper - setup do - Rubygem.searchkick_index.delete if Rubygem.searchkick_index.exists? - end - context "#search_data" do setup do @rubygem = create(:rubygem, name: "example_gem", downloads: 10) @@ -29,6 +25,8 @@ class RubygemSearchableTest < ActiveSupport::TestCase run_gem = create(:rubygem, name: "example_gem_run_dep") @dev_dep = create(:dependency, :development, rubygem: dev_gem, version: version) @run_dep = create(:dependency, :runtime, rubygem: run_gem, version: version) + + @rubygem.reindex(refresh: true) end should "return a hash" do @@ -111,8 +109,7 @@ class RubygemSearchableTest < ActiveSupport::TestCase context "when the number of downloads exceeds a 32 bit integer" do setup do @rubygem = create(:rubygem, name: "large_downloads_example_gem", downloads: 10_000_000_000) # 10 Billion downloads - @version = create(:version, number: "1.0.0", rubygem: @rubygem) - import_and_refresh + @version = create(:version, :reindex, number: "1.0.0", rubygem: @rubygem) end should "allow the number of downloads to be stored as a 64 bit integer" do @@ -125,10 +122,9 @@ class RubygemSearchableTest < ActiveSupport::TestCase context "rubygems analyzer" do setup do - create(:rubygem, name: "example-gem", number: "0.0.1") - create(:rubygem, name: "example_1", number: "0.0.1") - create(:rubygem, name: "example.rb", number: "0.0.1") - import_and_refresh + create(:rubygem, :reindex, name: "example-gem", number: "0.0.1") + create(:rubygem, :reindex, name: "example_1", number: "0.0.1") + create(:rubygem, :reindex, name: "example.rb", number: "0.0.1") end should "find all gems with matching tokens" do @@ -145,9 +141,8 @@ class RubygemSearchableTest < ActiveSupport::TestCase setup do example_1 = create(:rubygem, name: "example_1") example_2 = create(:rubygem, name: "example_2") - create(:version, rubygem: example_1, indexed: false) - create(:version, rubygem: example_2) - import_and_refresh + create(:version, :reindex, rubygem: example_1, indexed: false) + create(:version, :reindex, rubygem: example_2) end should "filter yanked gems from the result" do @@ -164,10 +159,9 @@ class RubygemSearchableTest < ActiveSupport::TestCase example_gem1 = create(:rubygem, name: "keyword", downloads: 1) example_gem2 = create(:rubygem, name: "example_gem2", downloads: 1) example_gem3 = create(:rubygem, name: "example_gem3", downloads: 1) - create(:version, rubygem: example_gem1, description: "some", summary: "some") - create(:version, rubygem: example_gem2, description: "keyword", summary: "some") - create(:version, rubygem: example_gem3, summary: "keyword", description: "some") - import_and_refresh + create(:version, :reindex, rubygem: example_gem1, description: "some", summary: "some") + create(:version, :reindex, rubygem: example_gem2, description: "keyword", summary: "some") + create(:version, :reindex, rubygem: example_gem3, summary: "keyword", description: "some") end should "look for keyword in name, summary and description and order them in same priority order" do @@ -182,9 +176,8 @@ class RubygemSearchableTest < ActiveSupport::TestCase setup do (10..30).step(10) do |downloads| rubygem = create(:rubygem, name: "gem_#{downloads}", downloads: downloads) - create(:version, rubygem: rubygem) + create(:version, :reindex, rubygem: rubygem) end - import_and_refresh end should "boost score of result by downloads count" do @@ -198,8 +191,7 @@ class RubygemSearchableTest < ActiveSupport::TestCase context "source" do setup do rubygem = create(:rubygem, name: "example_gem", downloads: 10) - create(:version, rubygem: rubygem, summary: "some summary", description: "some description") - import_and_refresh + create(:version, :reindex, rubygem: rubygem, summary: "some summary", description: "some description") end should "return all terms of source" do @@ -224,8 +216,7 @@ class RubygemSearchableTest < ActiveSupport::TestCase example1 = create(:rubygem, name: "keyword") example2 = create(:rubygem, name: "keywordo") example3 = create(:rubygem, name: "keywo") - [example1, example2, example3].each { |gem| create(:version, rubygem: gem) } - import_and_refresh + [example1, example2, example3].each { |gem| create(:version, :reindex, rubygem: gem) } end should "suggest names of possible gems" do @@ -247,9 +238,8 @@ class RubygemSearchableTest < ActiveSupport::TestCase setup do rubygem1 = create(:rubygem, name: "example", downloads: 101) rubygem2 = create(:rubygem, name: "web-rubygem", downloads: 99) - create(:version, rubygem: rubygem1, summary: "special word with web-rubygem") - create(:version, rubygem: rubygem2, description: "example special word") - import_and_refresh + create(:version, :reindex, rubygem: rubygem1, summary: "special word with web-rubygem") + create(:version, :reindex, rubygem: rubygem2, description: "example special word") end should "filter gems on downloads" do @@ -303,7 +293,10 @@ class RubygemSearchableTest < ActiveSupport::TestCase create(:version, rubygem: rubygem2, description: "example gems set the example") rubygem1.update_column("updated_at", 2.days.ago) rubygem2.update_column("updated_at", 10.days.ago) - import_and_refresh + + rubygem1.reindex(refresh: true) + rubygem2.reindex(refresh: true) + _, @response = ElasticSearcher.new("example").search end @@ -326,8 +319,6 @@ class RubygemSearchableTest < ActiveSupport::TestCase context "#search" do context "exception handling" do - setup { import_and_refresh } - context "Searchkick::InvalidQueryError" do setup do @ill_formated_query = "updated:[2016-08-10 TO }" @@ -364,7 +355,6 @@ class RubygemSearchableTest < ActiveSupport::TestCase rubygem = create(:rubygem, name: gem_name, downloads: 10) create(:version, rubygem: rubygem) end - import_and_refresh end should "not affect results" do @@ -379,9 +369,8 @@ class RubygemSearchableTest < ActiveSupport::TestCase context "query matches gem name prefix" do setup do %w[term-ansicolor term-an].each do |gem_name| - create(:rubygem, name: gem_name, number: "0.0.1", downloads: 10) + create(:rubygem, :reindex, name: gem_name, number: "0.0.1", downloads: 10) end - import_and_refresh end should "return results" do diff --git a/test/models/deletion_test.rb b/test/models/deletion_test.rb index 032f82c923c..12e585b54dc 100644 --- a/test/models/deletion_test.rb +++ b/test/models/deletion_test.rb @@ -12,7 +12,6 @@ class DeletionTest < ActiveSupport::TestCase @gem_file.rewind @version = Version.last @spec_rz = RubygemFs.instance.get("quick/Marshal.4.8/#{@version.full_name}.gemspec.rz") - import_and_refresh end teardown do @@ -160,7 +159,7 @@ class DeletionTest < ActiveSupport::TestCase perform_enqueued_jobs - response = Searchkick.client.get index: "rubygems-#{Rails.env}", + response = Searchkick.client.get index: Rubygem.searchkick_index.name, id: @version.rubygem_id assert response["_source"]["yanked"] diff --git a/test/models/gem_download_test.rb b/test/models/gem_download_test.rb index fa52869b656..5c49865ea18 100644 --- a/test/models/gem_download_test.rb +++ b/test/models/gem_download_test.rb @@ -5,7 +5,6 @@ class GemDownloadTest < ActiveSupport::TestCase setup do create(:gem_download, count: 0) - import_and_refresh end context ".increment" do @@ -64,12 +63,13 @@ def test_update_the_count_atomically @counts = Array.new(3) { rand(100) } @data = @versions.map.with_index { |v, i| [v.full_name, @counts[i]] } @gem_downloads = [(@counts[0] + @counts[2]), @counts[1]] - import_and_refresh end should "write the proper values" do GemDownload.bulk_update(@data) + @gems.each { |g| g.reindex(refresh: true) } + 3.times do |i| assert_equal @counts[i], GemDownload.count_for_version(@versions[i].id) end @@ -104,8 +104,9 @@ def test_update_the_count_atomically @gem_downloads[i] += counts[i] end end - import_and_refresh GemDownload.bulk_update(data) + + @gems.each { |g| g.reindex(refresh: true) } end should "update rubygems downloads irrespective of rubygem_ids order" do @@ -127,10 +128,11 @@ def test_update_the_count_atomically context "with prerelease versions" do setup do @rubygem = create(:rubygem, number: "0.0.1.rc") - import_and_refresh most_recent_version = @rubygem.most_recent_version version_downloads = [most_recent_version.full_name, 40] GemDownload.bulk_update([version_downloads]) + + @rubygem.reindex(refresh: true) end should "set version_downloads of ES record with prerelease downloads" do @@ -141,9 +143,10 @@ def test_update_the_count_atomically context "with no ruby platform versions" do setup do @version = create(:version, platform: "java") - import_and_refresh version_downloads = [@version.full_name, 40] GemDownload.bulk_update([version_downloads]) + + @version.rubygem.reindex(refresh: true) end should "set version_downloads of ES record with platform downloads" do diff --git a/test/models/pusher_test.rb b/test/models/pusher_test.rb index 390a4e333d5..f1f5f3e4872 100644 --- a/test/models/pusher_test.rb +++ b/test/models/pusher_test.rb @@ -625,7 +625,7 @@ def two_cert_chain(signing_key:, root_not_before: Time.current, cert_not_before: should "create rubygem index" do @rubygem.update_column("updated_at", Date.new(2016, 07, 04)) perform_enqueued_jobs only: ReindexRubygemJob - response = Searchkick.client.get index: "rubygems-#{Rails.env}", + response = Searchkick.client.get index: Rubygem.searchkick_index.name, id: @rubygem.id expected_response = { "name" => "gemsgemsgems", @@ -731,7 +731,7 @@ def two_cert_chain(signing_key:, root_not_before: Time.current, cert_not_before: should "update rubygem index" do perform_enqueued_jobs only: ReindexRubygemJob - response = Searchkick.client.get index: "rubygems-#{Rails.env}", + response = Searchkick.client.get index: Rubygem.searchkick_index.name, id: @rubygem.id assert_equal "new summary", response["_source"]["summary"] diff --git a/test/system/advanced_search_test.rb b/test/system/advanced_search_test.rb index 95775a32a6f..73705d4cb19 100644 --- a/test/system/advanced_search_test.rb +++ b/test/system/advanced_search_test.rb @@ -9,9 +9,7 @@ class AdvancedSearchTest < ApplicationSystemTestCase test "searches for a gem while scoping advanced attributes" do rubygem = create(:rubygem, name: "LDAP", number: "1.0.0", downloads: 3) - create(:version, summary: "some summary", description: "Hello World", rubygem: rubygem) - - import_and_refresh + create(:version, :reindex, summary: "some summary", description: "Hello World", rubygem: rubygem) fill_in "query", with: "downloads: <5" click_button "advanced_search_submit" @@ -21,8 +19,6 @@ class AdvancedSearchTest < ApplicationSystemTestCase end test "enter inside any field will submit form" do - import_and_refresh - ["#name", "#summary", "#description", "#downloads", "#updated"].each do |el| visit advanced_search_path find(el).send_keys(:return) @@ -32,8 +28,6 @@ class AdvancedSearchTest < ApplicationSystemTestCase end test "forms search query out of advanced attributes" do - import_and_refresh - fill_in "name", with: "hello" fill_in "summary", with: "world" fill_in "description", with: "foo" diff --git a/test/system/autocompletes_test.rb b/test/system/autocompletes_test.rb index 5fa88a50fe0..d152d01f24f 100644 --- a/test/system/autocompletes_test.rb +++ b/test/system/autocompletes_test.rb @@ -5,10 +5,9 @@ class AutocompletesTest < ApplicationSystemTestCase setup do rubygem = create(:rubygem, name: "rubocop") - create(:version, rubygem: rubygem, indexed: true) + create(:version, :reindex, rubygem: rubygem, indexed: true) rubygem = create(:rubygem, name: "rubocop-performance") - create(:version, rubygem: rubygem, indexed: true) - import_and_refresh + create(:version, :reindex, rubygem: rubygem, indexed: true) visit root_path @fill_field = find_by_id "query" diff --git a/test/integration/email_confirmation_test.rb b/test/system/email_confirmation_test.rb similarity index 97% rename from test/integration/email_confirmation_test.rb rename to test/system/email_confirmation_test.rb index d55eaa3c727..24deca51ec8 100644 --- a/test/integration/email_confirmation_test.rb +++ b/test/system/email_confirmation_test.rb @@ -1,7 +1,7 @@ -require "test_helper" +require "application_system_test_case" require "helpers/email_helpers" -class EmailConfirmationTest < SystemTest +class EmailConfirmationTest < ApplicationSystemTestCase include ActiveJob::TestHelper setup do diff --git a/test/system/gems_system_test.rb b/test/system/gems_system_test.rb new file mode 100644 index 00000000000..a8b89b54a6f --- /dev/null +++ b/test/system/gems_system_test.rb @@ -0,0 +1,178 @@ +require "application_system_test_case" + +class GemsSystemTest < ApplicationSystemTestCase + setup do + @user = create(:user) + @rubygem = create(:rubygem, name: "sandworm", number: "1.0.0") + @version = create(:version, rubygem: @rubygem, number: "1.1.1") + end + + test "version navigation" do + visit rubygem_version_path(@rubygem.slug, "1.0.0") + click_link "Next version →" + + assert_equal page.current_path, rubygem_version_path(@rubygem.slug, "1.1.1") + click_link "← Previous version" + + assert_equal page.current_path, rubygem_version_path(@rubygem.slug, "1.0.0") + end + + test "subscribe to a gem" do + visit rubygem_path(@rubygem.slug, as: @user.id) + + assert page.has_css?("a#subscribe") + + click_link "Subscribe" + + assert page.has_content? "Unsubscribe" + assert_equal @user.subscribed_gems.first, @rubygem + end + + test "unsubscribe to a gem" do + create(:subscription, rubygem: @rubygem, user: @user) + + visit rubygem_path(@rubygem.slug, as: @user.id) + + assert page.has_css?("a#unsubscribe") + + click_link "Unsubscribe" + + assert page.has_content? "Subscribe" + assert_empty @user.subscribed_gems + end + + test "shows enable MFA instructions when logged in as owner with MFA disabled" do + create(:ownership, rubygem: @rubygem, user: @user) + + visit rubygem_path(@rubygem.slug, as: @user.id) + + assert page.has_selector?(".gem__users__mfa-disabled .gem__users a") + assert page.has_content? "Please consider enabling multi-factor" + end + + test "shows owners without mfa when logged in as owner" do + @user.enable_totp!("some-seed", "ui_and_api") + user_without_mfa = create(:user) + + create(:ownership, rubygem: @rubygem, user: @user) + create(:ownership, rubygem: @rubygem, user: user_without_mfa) + + visit rubygem_path(@rubygem.slug, as: @user.id) + + assert page.has_selector?(".gem__users__mfa-disabled .gem__users a") + assert page.has_selector?(".gem__users__mfa-text.mfa-warn") + end + + test "show mfa enabled when logged in as owner but everyone has mfa enabled" do + @user.enable_totp!("some-seed", "ui_and_api") + user_with_mfa = create(:user) + user_with_mfa.enable_totp!("some-seed", "ui_and_api") + + create(:ownership, rubygem: @rubygem, user: @user) + create(:ownership, rubygem: @rubygem, user: user_with_mfa) + + visit rubygem_path(@rubygem.slug, as: @user.id) + + assert page.has_no_selector?(".gem__users__mfa-text.mfa-warn") + assert page.has_selector?(".gem__users__mfa-text.mfa-info") + end + + test "does not show owners without mfa when not logged in as owner" do + @user.enable_totp!("some-seed", "ui_and_api") + user_without_mfa = create(:user) + + create(:ownership, rubygem: @rubygem, user: @user) + create(:ownership, rubygem: @rubygem, user: user_without_mfa) + + visit rubygem_path(@rubygem.slug) + + assert page.has_no_selector?(".gem__users__mfa-disabled .gem__users a") + assert page.has_no_selector?(".gem__users__mfa-text.mfa-warn") + assert page.has_no_selector?(".gem__users__mfa-text.mfa-info") + end + + test "shows github link when source_code_uri is set" do + github_link = "http://github.com/user/project" + create(:version, number: "3.0.1", rubygem: @rubygem, metadata: { "source_code_uri" => github_link }) + + visit rubygem_path(@rubygem.slug) + + assert page.has_selector?(".github-btn") + end + + test "shows github link when homepage_uri is set" do + github_link = "http://github.com/user/project" + create(:version, number: "3.0.1", rubygem: @rubygem, metadata: { "homepage_uri" => github_link }) + + visit rubygem_path(@rubygem.slug) + + assert page.has_selector?(".github-btn") + end + + test "does not show github link when homepage_uri is not github" do + notgithub_link = "http://notgithub.com/user/project" + create(:version, number: "3.0.1", rubygem: @rubygem, metadata: { "homepage_uri" => notgithub_link }) + + visit rubygem_path(@rubygem.slug) + + assert page.has_no_selector?(".github-btn") + end + + test "shows both mfa headers if latest AND viewed version require MFA" do + @version.update_attribute :metadata, { "rubygems_mfa_required" => "true" } + create(:version, :mfa_required, rubygem: @rubygem, number: "0.1.1") + + visit rubygem_version_path(@rubygem.slug, "0.1.1") + + assert page.has_content? "New versions require MFA" + assert page.has_content? "Version published with MFA" + end + + test "shows 'new' mfa header only if latest requires MFA but viewed version doesn't" do + @version.update_attribute :metadata, { "rubygems_mfa_required" => "true" } + create(:version, rubygem: @rubygem, number: "0.1.1") + + visit rubygem_version_path(@rubygem.slug, "0.1.1") + + assert page.has_content? "New versions require MFA" + refute page.has_content? "Version published with MFA" + end + + test "shows 'version' mfa header only if latest does not require MFA but viewed version does" do + @version.update_attribute :metadata, { "rubygems_mfa_required" => "false" } + create(:version, :mfa_required, rubygem: @rubygem, number: "0.1.1") + + visit rubygem_version_path(@rubygem.slug, "0.1.1") + + refute page.has_content? "New versions require MFA" + assert page.has_content? "Version published with MFA" + end + + test "does not show either mfa header if neither latest or viewed version require MFA" do + @version.update_attribute :metadata, { "rubygems_mfa_required" => "false" } + create(:version, rubygem: @rubygem, number: "0.1.1") + + visit rubygem_version_path(@rubygem.slug, "0.1.1") + + refute page.has_content? "New versions require MFA" + refute page.has_content? "Version published with MFA" + end + + test "shows both mfa headers if MFA enabled for latest version and viewing latest version" do + @version.update_attribute :metadata, { "rubygems_mfa_required" => "true" } + + visit rubygem_path(@rubygem.slug) + + assert page.has_content? "New versions require MFA" + assert page.has_content? "Version published with MFA" + end + + test "shows neither mfa header if MFA disabled for latest version and viewing latest version" do + @version.update_attribute :metadata, { "rubygems_mfa_required" => "false" } + + visit rubygem_path(@rubygem.slug) + + refute page.has_content? "New versions require MFA" + refute page.has_content? "Version published with MFA" + end +end diff --git a/test/integration/notification_settings_test.rb b/test/system/notification_settings_test.rb similarity index 97% rename from test/integration/notification_settings_test.rb rename to test/system/notification_settings_test.rb index 9c377ef51b4..c4512a67ebf 100644 --- a/test/integration/notification_settings_test.rb +++ b/test/system/notification_settings_test.rb @@ -1,7 +1,7 @@ -require "test_helper" +require "application_system_test_case" require "capybara/minitest" -class NotificationSettingsTest < SystemTest +class NotificationSettingsTest < ApplicationSystemTestCase include Capybara::Minitest::Assertions test "changing email notification settings" do diff --git a/test/integration/owner_test.rb b/test/system/owner_test.rb similarity index 99% rename from test/integration/owner_test.rb rename to test/system/owner_test.rb index e13015369cc..f000244e462 100644 --- a/test/integration/owner_test.rb +++ b/test/system/owner_test.rb @@ -1,6 +1,6 @@ -require "test_helper" +require "application_system_test_case" -class OwnerTest < SystemTest +class OwnerTest < ApplicationSystemTestCase include ActiveJob::TestHelper include RubygemsHelper diff --git a/test/integration/ownership_call_test.rb b/test/system/ownership_call_test.rb similarity index 97% rename from test/integration/ownership_call_test.rb rename to test/system/ownership_call_test.rb index 484e3428b78..824b5861cef 100644 --- a/test/integration/ownership_call_test.rb +++ b/test/system/ownership_call_test.rb @@ -1,7 +1,7 @@ -require "test_helper" +require "application_system_test_case" require "helpers/adoption_helpers" -class OwnershipCallsTest < SystemTest +class OwnershipCallsTest < ApplicationSystemTestCase include ActionMailer::TestHelper include AdoptionHelpers diff --git a/test/integration/ownership_request_test.rb b/test/system/ownership_request_test.rb similarity index 96% rename from test/integration/ownership_request_test.rb rename to test/system/ownership_request_test.rb index dba4aca0eb7..f25c41a7c9e 100644 --- a/test/integration/ownership_request_test.rb +++ b/test/system/ownership_request_test.rb @@ -1,7 +1,7 @@ -require "test_helper" +require "application_system_test_case" require "helpers/adoption_helpers" -class OwnershipRequestsTest < SystemTest +class OwnershipRequestsTest < ApplicationSystemTestCase include ActionMailer::TestHelper include AdoptionHelpers diff --git a/test/integration/page_params_test.rb b/test/system/page_params_test.rb similarity index 87% rename from test/integration/page_params_test.rb rename to test/system/page_params_test.rb index 95260aad9cd..d52e36b4eca 100644 --- a/test/integration/page_params_test.rb +++ b/test/system/page_params_test.rb @@ -1,6 +1,6 @@ -require "test_helper" +require "application_system_test_case" -class PageParamsTest < SystemTest +class PageParamsTest < ApplicationSystemTestCase include SearchKickHelper test "stats with page param more than 10" do @@ -36,8 +36,7 @@ class PageParamsTest < SystemTest end test "api search with page smaller than 1" do - create(:rubygem, name: "some", number: "1.0.0") - import_and_refresh + create(:rubygem, :reindex, name: "some", number: "1.0.0") visit api_v1_search_path(page: "0", query: "some", format: :json) assert redirect_to(api_v1_search_path(page: "1", query: "some", format: :json)) @@ -45,8 +44,7 @@ class PageParamsTest < SystemTest end test "api search with page is not a numer" do - create(:rubygem, name: "some", number: "1.0.0") - import_and_refresh + create(:rubygem, :reindex, name: "some", number: "1.0.0") visit api_v1_search_path(page: "foo", query: "some", format: :json) assert redirect_to(api_v1_search_path(page: "1", query: "some", format: :json)) @@ -54,8 +52,7 @@ class PageParamsTest < SystemTest end test "api search with page that can't be converted to a number" do - create(:rubygem, name: "some", number: "1.0.0") - import_and_refresh + create(:rubygem, :reindex, name: "some", number: "1.0.0") visit api_v1_search_path(page: { "$acunetix" => "1" }, query: "some", format: :json) assert redirect_to(api_v1_search_path(page: "1", query: "some", format: :json)) diff --git a/test/integration/pages_test.rb b/test/system/pages_test.rb similarity index 82% rename from test/integration/pages_test.rb rename to test/system/pages_test.rb index 25cce82ef58..e81312dcb49 100644 --- a/test/integration/pages_test.rb +++ b/test/system/pages_test.rb @@ -1,6 +1,6 @@ -require "test_helper" +require "application_system_test_case" -class PagesTest < SystemTest +class PagesTest < ApplicationSystemTestCase test "renders existing page" do visit "/" click_link "About" diff --git a/test/integration/password_reset_test.rb b/test/system/password_reset_test.rb similarity index 98% rename from test/integration/password_reset_test.rb rename to test/system/password_reset_test.rb index 327ff07a8a0..4c835799d58 100644 --- a/test/integration/password_reset_test.rb +++ b/test/system/password_reset_test.rb @@ -1,6 +1,6 @@ -require "test_helper" +require "application_system_test_case" -class PasswordResetTest < SystemTest +class PasswordResetTest < ApplicationSystemTestCase include ActiveJob::TestHelper def password_reset_link diff --git a/test/integration/profile_test.rb b/test/system/profile_test.rb similarity index 98% rename from test/integration/profile_test.rb rename to test/system/profile_test.rb index 34540ceee86..43596e18d62 100644 --- a/test/integration/profile_test.rb +++ b/test/system/profile_test.rb @@ -1,6 +1,6 @@ -require "test_helper" +require "application_system_test_case" -class ProfileTest < SystemTest +class ProfileTest < ApplicationSystemTestCase include ActiveJob::TestHelper setup do diff --git a/test/integration/search_test.rb b/test/system/search_test.rb similarity index 77% rename from test/integration/search_test.rb rename to test/system/search_test.rb index ad5c2c91b6f..1a9e766b07e 100644 --- a/test/integration/search_test.rb +++ b/test/system/search_test.rb @@ -1,12 +1,11 @@ -require "test_helper" +require "application_system_test_case" -class SearchTest < SystemTest +class SearchTest < ApplicationSystemTestCase include SearchKickHelper test "searching for a gem" do - create(:rubygem, name: "LDAP", number: "1.0.0") - create(:rubygem, name: "LDAP-PLUS", number: "1.0.0") - import_and_refresh + create(:rubygem, :reindex, name: "LDAP", number: "1.0.0") + create(:rubygem, :reindex, name: "LDAP-PLUS", number: "1.0.0") visit search_path @@ -20,8 +19,7 @@ class SearchTest < SystemTest test "searching for a yanked gem" do rubygem = create(:rubygem, name: "LDAP") - create(:version, rubygem: rubygem, indexed: false) - import_and_refresh + create(:version, :reindex, rubygem: rubygem, indexed: false) visit search_path @@ -39,9 +37,8 @@ class SearchTest < SystemTest test "searching for a gem with yanked versions" do rubygem = create(:rubygem, name: "LDAP") - create(:version, rubygem: rubygem, number: "1.1.1", indexed: true) - create(:version, rubygem: rubygem, number: "2.2.2", indexed: false) - import_and_refresh + create(:version, :reindex, rubygem: rubygem, number: "1.1.1", indexed: true) + create(:version, :reindex, rubygem: rubygem, number: "2.2.2", indexed: false) visit search_path @@ -60,9 +57,8 @@ class SearchTest < SystemTest test "params has non white listed keys" do Kaminari.configure { |c| c.default_per_page = 1 } - create(:rubygem, name: "ruby-ruby", number: "1.0.0") - create(:rubygem, name: "ruby-gems", number: "1.0.0") - import_and_refresh + create(:rubygem, :reindex, name: "ruby-ruby", number: "1.0.0") + create(:rubygem, :reindex, name: "ruby-gems", number: "1.0.0") visit "/search?query=ruby&original_script_name=javascript:alert(1)//&script_name=javascript:alert(1)//" @@ -77,10 +73,9 @@ class SearchTest < SystemTest orignal_val = Gemcutter::SEARCH_MAX_PAGES Gemcutter::SEARCH_MAX_PAGES = 2 - create(:rubygem, name: "ruby-ruby", number: "1.0.0") - create(:rubygem, name: "ruby-gems", number: "1.0.0") - create(:rubygem, name: "ruby-thing", number: "1.0.0") - import_and_refresh + create(:rubygem, :reindex, name: "ruby-ruby", number: "1.0.0") + create(:rubygem, :reindex, name: "ruby-gems", number: "1.0.0") + create(:rubygem, :reindex, name: "ruby-thing", number: "1.0.0") visit "/search?query=ruby" diff --git a/test/integration/sign_in_test.rb b/test/system/sign_in_test.rb similarity index 99% rename from test/integration/sign_in_test.rb rename to test/system/sign_in_test.rb index da222320e5d..8b24432b1f9 100644 --- a/test/integration/sign_in_test.rb +++ b/test/system/sign_in_test.rb @@ -1,6 +1,6 @@ -require "test_helper" +require "application_system_test_case" -class SignInTest < SystemTest +class SignInTest < ApplicationSystemTestCase setup do @user = create(:user, email: "nick@example.com", password: PasswordHelpers::SECURE_TEST_PASSWORD, handle: nil) @mfa_user = create(:user, email: "john@example.com", password: PasswordHelpers::SECURE_TEST_PASSWORD, diff --git a/test/integration/sign_up_test.rb b/test/system/sign_up_test.rb similarity index 97% rename from test/integration/sign_up_test.rb rename to test/system/sign_up_test.rb index 5b1128b5499..16a4e6ed866 100644 --- a/test/integration/sign_up_test.rb +++ b/test/system/sign_up_test.rb @@ -1,6 +1,6 @@ -require "test_helper" +require "application_system_test_case" -class SignUpTest < SystemTest +class SignUpTest < ApplicationSystemTestCase test "sign up" do visit sign_up_path diff --git a/test/integration/yank_test.rb b/test/system/yank_test.rb similarity index 97% rename from test/integration/yank_test.rb rename to test/system/yank_test.rb index 3d433b0da4d..a447539670c 100644 --- a/test/integration/yank_test.rb +++ b/test/system/yank_test.rb @@ -1,6 +1,6 @@ -require "test_helper" +require "application_system_test_case" -class YankTest < SystemTest +class YankTest < ApplicationSystemTestCase setup do @user = create(:user, password: PasswordHelpers::SECURE_TEST_PASSWORD) @rubygem = create(:rubygem, name: "sandworm") diff --git a/test/test_helper.rb b/test/test_helper.rb index 4d08b5d0cc0..0458b8a2615 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -68,8 +68,6 @@ c.strict_keyword_argument_matching = true end -Rubygem.searchkick_reindex(import: false) - OmniAuth.config.test_mode = true class ActiveSupport::TestCase @@ -78,8 +76,15 @@ class ActiveSupport::TestCase include EmailHelpers include PasswordHelpers - parallelize_setup do |_worker| + parallelize(workers: :number_of_processors) + + parallelize_setup do |worker| + Version.reset_column_information # TODO: Remove once https://github.com/rails/rails/pull/52703 is released + SemanticLogger.reopen + Searchkick.index_suffix = "_#{worker}" + Rubygem.reindex + Searchkick.disable_callbacks end setup do @@ -90,6 +95,9 @@ class ActiveSupport::TestCase Unpwn.offline = true OmniAuth.config.mock_auth.clear + Rubygem.reindex + Searchkick.disable_callbacks + @launch_darkly = LaunchDarkly::Integrations::TestData.data_source config = LaunchDarkly::Config.new(data_source: @launch_darkly, send_events: false) Rails.configuration.launch_darkly_client = LaunchDarkly::LDClient.new("", config) @@ -252,17 +260,6 @@ class ActionDispatch::IntegrationTest # Force loading of ActionDispatch::SystemTesting::* helpers _ = ActionDispatch::SystemTestCase -class SystemTest < ActionDispatch::IntegrationTest - include Capybara::DSL - include Capybara::Minitest::Assertions - include ActionDispatch::SystemTesting::TestHelpers::ScreenshotHelper - include ActionDispatch::SystemTesting::TestHelpers::SetupAndTeardown - - setup do - Capybara.current_driver = :rack_test - end -end - class AdminPolicyTestCase < ActiveSupport::TestCase def setup requires_avo_pro