diff --git a/.env_sample b/.env_sample index e662d812d..a095c689c 100644 --- a/.env_sample +++ b/.env_sample @@ -152,6 +152,11 @@ TWITCH_CLIENT_ID="Optional" TWITCH_CLIENT_SECRET="Optional" TWITCH_WEBHOOK_SECRET="Optional" +# Algolia for search +ALGOLIA_APPLICATION_ID= +ALGOLIA_API_KEY= +ALGOLIA_SEARCH_ONLY_API_KEY= + # For calling the Stack Exchange API # (https://api.stackexchange.com/docs) STACK_EXCHANGE_APP_KEY="" diff --git a/Gemfile b/Gemfile index 233891985..a83bbbb92 100644 --- a/Gemfile +++ b/Gemfile @@ -16,6 +16,7 @@ gem "acts_as_follower", github: "forem/acts_as_follower", branch: "master" # All gem "addressable", "~> 2.8" # A replacement for the URI implementation that is part of Ruby's standard library gem "ahoy_email", "~> 2.2.0" # Email analytics for Rails gem "ahoy_matey", "~> 5.0.2" # Tracking analytics for Rails +gem "algoliasearch-rails", "~> 2.3" # Algolia Search API Client gem "ancestry", "~> 4.2" # Ancestry allows the records of a ActiveRecord model to be organized in a tree structure gem "blazer", "~> 2.6" # Allows admins to query data gem "bootsnap", ">= 1.1.0", require: false # Boot large ruby/rails apps faster diff --git a/Gemfile.lock b/Gemfile.lock index 90fe5d4ad..1d9ec4a16 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -89,6 +89,14 @@ GEM activesupport (>= 6.1) device_detector (>= 1) safely_block (>= 0.4) + algolia (2.3.4) + faraday (>= 0.15, < 3) + faraday-net_http_persistent (>= 0.15, < 3) + multi_json (~> 1.0) + net-http-persistent + algoliasearch-rails (2.3.2) + algolia (< 3.0.0) + json (>= 1.5.1) amazing_print (1.6.0) ancestry (4.3.3) activerecord (>= 5.2.6) @@ -279,6 +287,9 @@ GEM faraday-http-cache (2.5.0) faraday (>= 0.8) faraday-net_http (3.0.2) + faraday-net_http_persistent (2.1.0) + faraday (~> 2.5) + net-http-persistent (~> 4.0) faraday-retry (2.1.0) faraday (~> 2.0) fastimage (2.3.0) @@ -978,6 +989,7 @@ DEPENDENCIES addressable (~> 2.8) ahoy_email (~> 2.2.0) ahoy_matey (~> 5.0.2) + algoliasearch-rails (~> 2.3) amazing_print (~> 1.4) ancestry (~> 4.2) better_errors (~> 2.9) diff --git a/app/models/settings/general.rb b/app/models/settings/general.rb index 71e2a5dc1..e11fc288a 100644 --- a/app/models/settings/general.rb +++ b/app/models/settings/general.rb @@ -144,6 +144,15 @@ module Settings setting :default_content_language, type: :string, default: "en", validates: { inclusion: Languages::Detection.codes } + # Algolia + setting :algolia_application_id, type: :string, default: ApplicationConfig["ALGOLIA_APPLICATION_ID"] + setting :algolia_api_key, type: :string, default: ApplicationConfig["ALGOLIA_API_KEY"] + setting :algolia_search_only_api_key, type: :string, default: ApplicationConfig["ALGOLIA_SEARCH_ONLY_API_KEY"] + + def self.algolia_search_enabled? + algolia_application_id.present? && algolia_search_only_api_key.present? && algolia_api_key.present? + end + def self.custom_newsletter_configured? onboarding_newsletter_content_processed_html.present? && onboarding_newsletter_opt_in_head.present? && diff --git a/config/initializers/algoliasearch.rb b/config/initializers/algoliasearch.rb new file mode 100644 index 000000000..7dfd7547b --- /dev/null +++ b/config/initializers/algoliasearch.rb @@ -0,0 +1,4 @@ +AlgoliaSearch.configuration = { + application_id: ApplicationConfig["ALGOLIA_APPLICATION_ID"], + api_key: ApplicationConfig["ALGOLIA_API_KEY"] +} diff --git a/spec/models/settings/general_spec.rb b/spec/models/settings/general_spec.rb index 4523f4f1f..0ce0e072f 100644 --- a/spec/models/settings/general_spec.rb +++ b/spec/models/settings/general_spec.rb @@ -12,7 +12,7 @@ RSpec.describe Settings::General do it "accepts valid URLs" do url_fields.each do |attribute| expect do - described_class.public_send("#{attribute}=", "https://example.com") + described_class.public_send(:"#{attribute}=", "https://example.com") end.not_to raise_error end end @@ -20,7 +20,7 @@ RSpec.describe Settings::General do it "rejects invalid URLs and accepts valid ones", :aggregate_failures do url_fields.each do |attribute| expect do - described_class.public_send("#{attribute}=", "example.com") + described_class.public_send(:"#{attribute}=", "example.com") end.to raise_error(/is not a valid URL/) end end @@ -95,5 +95,27 @@ RSpec.describe Settings::General do end.to raise_error(ActiveRecord::RecordInvalid) end end + + describe "validating algolia settings" do + it "only accepts strings" do + expect(described_class.get_setting(:algolia_application_id)[:type]).to eq(:string) + expect(described_class.get_setting(:algolia_api_key)[:type]).to eq(:string) + expect(described_class.get_setting(:algolia_search_only_api_key)[:type]).to eq(:string) + end + end + + describe "::algolia_search_enabled?" do + it "returns true if all algolia settings are present" do + described_class.algolia_application_id = "app_id" + described_class.algolia_api_key = "api_key" + described_class.algolia_search_only_api_key = "search_only_api_key" + expect(described_class.algolia_search_enabled?).to be(true) + end + + it "returns false if any or all of the algolia settings are missing" do + described_class.algolia_application_id = "app_id" + expect(described_class.algolia_search_enabled?).to be(false) + end + end end end diff --git a/vendor/cache/algolia-2.3.4.gem b/vendor/cache/algolia-2.3.4.gem new file mode 100644 index 000000000..4c84657fc Binary files /dev/null and b/vendor/cache/algolia-2.3.4.gem differ diff --git a/vendor/cache/algoliasearch-rails-2.3.2.gem b/vendor/cache/algoliasearch-rails-2.3.2.gem new file mode 100644 index 000000000..551dcb7a3 Binary files /dev/null and b/vendor/cache/algoliasearch-rails-2.3.2.gem differ diff --git a/vendor/cache/faraday-net_http_persistent-2.1.0.gem b/vendor/cache/faraday-net_http_persistent-2.1.0.gem new file mode 100644 index 000000000..3732b78f5 Binary files /dev/null and b/vendor/cache/faraday-net_http_persistent-2.1.0.gem differ