docbrown/spec/models/articles/feeds/relevancy_lever_spec.rb
Jeremy Friesen 0d0464be2f
Allowing VariantQuery for Feed Generation (#17382)
* Allowing VariantQuery for Feed Generation

Apologies for the breadth of this pull request, I had considered many
small commits, but felt that would've been more effort for the value
provided.

This commit includes the following:

- Documentation updates to the feed variant (though not the final pass)
- Renaming and adding RelevancyLevers that help differentiate
- Adding RelevancyLever#range to provide documentation
- Reducing redundent controller logic by making a
  `Articles::Feeds.feed_for` method.
- Adding some configuration validation for RelevancyLevers
- Adding constants for better clarification
- Testing unhappy paths for feed configuration
- Adjusting the module namespace of some objects
- Exposing top-level configurations for variants (along with their
  defaults)
- Creating the VariantyQuery that at present inherits from the
  `Articles::Feeds::WeightedQueryStrategy`

As implemented, we can deploy this code to production without using the
new VariantQuery.  Once we toggle on the
`:feed_uses_variant_query_feature` FeatureFlag, it will switch to using
the VariantQuery.  The VariantQuery's two variants and the
internal configuration of `Articles::Feeds::WeightedQueryStrategy`
produce the same query.

The goal of this factor is to allow for a quick on and off toggle of the
feed query; to ensure that what we introduce remains performant.

- Closes forem/forem#17272
- Closes forem/forem#17276
- Closes forem/forem#17216

In addition, I will be recording a code-walkthrough and linking that
recording to the pull request.

* Apply suggestions from code review

Co-authored-by: Mac Siri <krairit.siri@gmail.com>

Co-authored-by: Mac Siri <krairit.siri@gmail.com>
2022-04-21 11:07:09 -04:00

48 lines
1.3 KiB
Ruby

require "rails_helper"
RSpec.describe Articles::Feeds::RelevancyLever do
subject { lever }
let(:lever) do
described_class.new(
key: :my_key,
range: "[0..10)",
label: "My label",
select_fragment: "articles.reaction_count",
user_required: true,
)
end
it { is_expected.to respond_to :key }
it { is_expected.to respond_to :label }
it { is_expected.to respond_to :select_fragment }
it { is_expected.to respond_to :joins_fragments }
it { is_expected.to respond_to :group_by_fragment }
it { is_expected.to respond_to :user_required }
it { is_expected.to respond_to :user_required? }
describe "#configure_with" do
subject { lever.configure_with(fallback: fallback, cases: cases) }
let(:cases) { [[0, 0]] }
let(:fallback) { 1 }
context "when fallback is not a number" do
let(:fallback) { "nope" }
it { within_block_is_expected.to raise_error described_class::InvalidFallbackError }
end
context "when cases is not an array" do
let(:cases) { "nope" }
it { within_block_is_expected.to raise_error described_class::InvalidCasesError }
end
context "when cases includes a non-number" do
let(:cases) { [[0, 1], [1, "a"]] }
it { within_block_is_expected.to raise_error described_class::InvalidCasesError }
end
end
end