diff --git a/app/models/control.rb b/app/models/control.rb index b61529d3..7b3ae03a 100644 --- a/app/models/control.rb +++ b/app/models/control.rb @@ -14,4 +14,31 @@ class Control < ApplicationRecord accepts_nested_attributes_for :action validates :display_name, presence: true + + # Returns a representation of this Control as a Discovery Engine control resource + def to_discovery_engine_control + { + name:, + display_name:, + **action.to_discovery_engine_control_action, + solution_type: Google::Cloud::DiscoveryEngine::V1::SolutionType::SOLUTION_TYPE_SEARCH, + # Trip hazard: despite the plural name, this expects _one_ use case in an array + use_cases: [Google::Cloud::DiscoveryEngine::V1::SearchUseCase::SEARCH_USE_CASE_SEARCH], + } + end + + # The fully qualified name of the control on Discovery Engine (like a path) + def name + [parent, "controls", discovery_engine_id].join("/") + end + + # The parent of the control on Discovery Engine (always the engine) + def parent + Rails.configuration.discovery_engine_engine + end + + # The ID of the resource on Discovery Engine + def discovery_engine_id + "search-admin-#{id}" + end end diff --git a/app/models/control/boost_action.rb b/app/models/control/boost_action.rb index 98f7ab44..10ef2ada 100644 --- a/app/models/control/boost_action.rb +++ b/app/models/control/boost_action.rb @@ -16,4 +16,15 @@ class Control::BoostAction < ApplicationRecord validates :filter_expression, presence: true validates :boost_factor, numericality: { in: BOOST_FACTOR_RANGE, other_than: 0 } + + # Returns a representation of this boost as part of a Discovery Engine control resource + def to_discovery_engine_control_action + { + boost_action: { + filter: filter_expression, + boost: boost_factor, + data_store: Rails.configuration.discovery_engine_datastore, + }, + } + end end diff --git a/app/models/control/filter_action.rb b/app/models/control/filter_action.rb index d4033a23..4956f70d 100644 --- a/app/models/control/filter_action.rb +++ b/app/models/control/filter_action.rb @@ -10,4 +10,14 @@ class Control::FilterAction < ApplicationRecord include Control::Actionable validates :filter_expression, presence: true + + # Returns a representation of this filter as part of a Discovery Engine control resource + def to_discovery_engine_control_action + { + filter_action: { + filter: filter_expression, + data_store: Rails.configuration.discovery_engine_datastore, + }, + } + end end diff --git a/spec/models/control/boost_action_spec.rb b/spec/models/control/boost_action_spec.rb index cf6f6d12..18036efc 100644 --- a/spec/models/control/boost_action_spec.rb +++ b/spec/models/control/boost_action_spec.rb @@ -48,4 +48,20 @@ end end end + + describe "#to_discovery_engine_control_action" do + subject(:boost) do + build_stubbed(:control_boost_action, filter_expression: "foo = 1", boost_factor: 0.13) + end + + it "returns a representation of the action for Discovery Engine" do + expect(boost.to_discovery_engine_control_action).to eq({ + boost_action: { + filter: "foo = 1", + boost: 0.13, + data_store: "[datastore]", + }, + }) + end + end end diff --git a/spec/models/control/filter_action_spec.rb b/spec/models/control/filter_action_spec.rb index 36a6218f..941dd508 100644 --- a/spec/models/control/filter_action_spec.rb +++ b/spec/models/control/filter_action_spec.rb @@ -15,4 +15,17 @@ end end end + + describe "#to_discovery_engine_control_action" do + subject(:filter) { build_stubbed(:control_filter_action, filter_expression: "foo = 1") } + + it "returns a representation of the action for Discovery Engine" do + expect(filter.to_discovery_engine_control_action).to eq({ + filter_action: { + filter: "foo = 1", + data_store: "[datastore]", + }, + }) + end + end end diff --git a/spec/models/control_spec.rb b/spec/models/control_spec.rb index aab7e585..86b3b0a6 100644 --- a/spec/models/control_spec.rb +++ b/spec/models/control_spec.rb @@ -26,4 +26,42 @@ end end end + + describe "Discovery Engine representation" do + subject(:control) { build_stubbed(:control, id: 42, display_name: "My boost control", action:) } + + let(:action) { build(:control_boost_action) } + + describe "#discovery_engine_id" do + it "builds an ID from the control's database ID" do + expect(control.discovery_engine_id).to eq("search-admin-42") + end + end + + describe "#parent" do + it "is the configured engine" do + expect(control.parent).to eq("[engine]") + end + end + + describe "#name" do + it "returns the fully qualified name of the control" do + expect(control.name).to eq("[engine]/controls/search-admin-42") + end + end + + describe "#to_discovery_engine_control" do + it "returns a representation of the control for Discovery Engine" do + expect(control.to_discovery_engine_control).to include( + name: "[engine]/controls/search-admin-42", + display_name: "My boost control", + # We don't care what's in the action (that's tested elsewhere), but we do care that the + # key is present + boost_action: hash_including, + solution_type: Google::Cloud::DiscoveryEngine::V1::SolutionType::SOLUTION_TYPE_SEARCH, + use_cases: [Google::Cloud::DiscoveryEngine::V1::SearchUseCase::SEARCH_USE_CASE_SEARCH], + ) + end + end + end end