diff --git a/app/services/articles/feed.rb b/app/services/articles/feed.rb index 30129c172..79db59fcc 100644 --- a/app/services/articles/feed.rb +++ b/app/services/articles/feed.rb @@ -16,12 +16,13 @@ module Articles # Timeframe values from Timeframer::DATETIMES def top_articles_by_timeframe(timeframe:) published_articles_by_tag.where("published_at > ?", Timeframer.new(timeframe).datetime). - order("score DESC") + order("score DESC").page(@page).per(@number_of_articles) end def latest_feed published_articles_by_tag.order("published_at DESC"). - where("featured_number > ? AND score > ?", 1_449_999_999, -40) + where("featured_number > ? AND score > ?", 1_449_999_999, -40). + page(@page).per(@number_of_articles) end def default_home_feed_and_featured_story(user_signed_in: false) @@ -51,7 +52,8 @@ module Articles article_points = score_single_article(article) result[article] = article_points end - ranked_articles.sort_by { |_article, article_points| -article_points }.map(&:first) + ranked_articles = ranked_articles.sort_by { |_article, article_points| -article_points }.map(&:first) + ranked_articles.to(@number_of_articles - 1) end def score_single_article(article) @@ -70,6 +72,8 @@ module Articles end def score_followed_tags(article) + return 0 unless @user + article_tags = article.decorate.cached_tag_list_array @user.decorate.cached_followed_tags.sum do |tag| article_tags.include?(tag.name) ? tag.points : 0 @@ -92,11 +96,11 @@ module Articles end def score_language(article) - @user.preferred_languages_array.include?(article.language || "en") ? 1 : -10 + @user&.preferred_languages_array&.include?(article.language || "en") ? 1 : -10 end def score_experience_level(article) - - ((article.experience_level_rating - (@user.experience_level || 5).abs) / 2) + - ((article.experience_level_rating - (@user&.experience_level || 5).abs) / 2) end end end diff --git a/spec/services/articles/feed_spec.rb b/spec/services/articles/feed_spec.rb index d2d8fc242..095770b69 100644 --- a/spec/services/articles/feed_spec.rb +++ b/spec/services/articles/feed_spec.rb @@ -287,4 +287,27 @@ RSpec.describe Articles::Feed, type: :service do end end end + + describe "#rank_and_sort_articles" do + let(:article1) { create(:article) } + let(:article2) { create(:article) } + let(:article3) { create(:article) } + let(:articles) { [article1, article2, article3] } + + context "when number of articles specified" do + let(:feed) { described_class.new(number_of_articles: 1) } + + it "only returns the requested number of articles" do + expect(feed.rank_and_sort_articles(articles).size).to eq 1 + end + end + + it "returns articles in scored order" do + allow(feed).to receive(:score_single_article).with(article1).and_return(1) + allow(feed).to receive(:score_single_article).with(article2).and_return(2) + allow(feed).to receive(:score_single_article).with(article3).and_return(3) + + expect(feed.rank_and_sort_articles(articles)).to eq [article3, article2, article1] + end + end end