Skip to content

Commit

Permalink
sort on issues endpoint per sort params
Browse files Browse the repository at this point in the history
  • Loading branch information
mapra99 committed Jul 31, 2023
1 parent a760135 commit ba3b6a5
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 1 deletion.
6 changes: 5 additions & 1 deletion api/app/controllers/api/v1/issues_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def index
return head :bad_request if params[:product_slug].blank?
return head :not_found if product.blank?

issues = Issue.includes(:issue_category, :user, :issue_upvotes).where(product:)
issues = IssuesFeedBuilder.new(product:, sort_params:).call
render json: ::V1::IssuesBlueprint.render(issues, current_user:)
end

Expand Down Expand Up @@ -61,6 +61,10 @@ def issue_params
def validate_identifiers!
return head :not_found if issue.blank?
end

def sort_params
params.permit(:sort_by, :sort_direction)
end
end
end
end
4 changes: 4 additions & 0 deletions api/app/models/issue.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ class Issue < ApplicationRecord
validates :detail, presence: true
validates :status, presence: true, inclusion: { in: STATUSES.values }

scope :latest_first, -> { order(created_at: :desc) }
scope :sort_by_upvotes, -> (direction) { order(upvotes_count: direction) }

Check warning on line 23 in api/app/models/issue.rb

View workflow job for this annotation

GitHub Actions / rubocop

[rubocop] reported by reviewdog 🐶 Do not use spaces between `->` and `(` in lambda literals. Raw Output: app/models/issue.rb:23:29: C: Layout/SpaceInLambdaLiteral: Do not use spaces between `->` and `(` in lambda literals.
scope :sort_by_comments, -> (direction) { order(comments_count: direction) }

Check warning on line 24 in api/app/models/issue.rb

View workflow job for this annotation

GitHub Actions / rubocop

[rubocop] reported by reviewdog 🐶 Do not use spaces between `->` and `(` in lambda literals. Raw Output: app/models/issue.rb:24:30: C: Layout/SpaceInLambdaLiteral: Do not use spaces between `->` and `(` in lambda literals.

def upvoted_by?(user)
issue_upvotes.exists?(user_id: user.id)
end
Expand Down
33 changes: 33 additions & 0 deletions api/app/services/issues_feed_builder.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
class IssuesFeedBuilder
attr_reader :product, :sort_params, :issues

def initialize(product:, sort_params:)
@product = product
@sort_params = sort_params
end

def call
@issues = Issue.includes(:issue_category, :user, :issue_upvotes).latest_first
@issues = filtered_by_product if product.present?
@issues = sorted if sort_params.present?

issues
end

private

def filtered_by_product
issues.where(product:)
end

def sorted
byebug

Check warning on line 24 in api/app/services/issues_feed_builder.rb

View workflow job for this annotation

GitHub Actions / rubocop

[rubocop] reported by reviewdog 🐶 Remove debugger entry point `byebug`. Raw Output: app/services/issues_feed_builder.rb:24:5: W: Lint/Debugger: Remove debugger entry point `byebug`.
if sort_params[:sort_by] == 'upvotes'
issues.sort_by_upvotes(sort_params[:sort_direction] == 'desc' ? :desc : :asc)
elsif sort_params[:sort_by] == 'comments'
issues.sort_by_comments(sort_params[:sort_direction] == 'desc' ? :desc : :asc)
else
raise StandardError, 'Invalid sort_by param'
end
end
end
24 changes: 24 additions & 0 deletions api/spec/models/issue_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,28 @@
end
end
end

describe '.latest_first' do
subject(:latest_first) { described_class.latest_first }

let!(:issue_1) { create(:issue, created_at: 1.day.ago) }

Check warning on line 62 in api/spec/models/issue_spec.rb

View workflow job for this annotation

GitHub Actions / rubocop

[rubocop] reported by reviewdog 🐶 Use normalcase for symbol numbers. Raw Output: spec/models/issue_spec.rb:62:10: C: Naming/VariableNumber: Use normalcase for symbol numbers.
let!(:issue_2) { create(:issue, created_at: 2.days.ago) }

Check warning on line 63 in api/spec/models/issue_spec.rb

View workflow job for this annotation

GitHub Actions / rubocop

[rubocop] reported by reviewdog 🐶 Use normalcase for symbol numbers. Raw Output: spec/models/issue_spec.rb:63:10: C: Naming/VariableNumber: Use normalcase for symbol numbers.

it 'returns issues sorted by created_at desc' do
expect(latest_first).to eq [issue_1, issue_2]
end
end

describe '.sort_by_upvotes' do
subject(:sort_by_upvotes) { described_class.sort_by_upvotes(direction) }

let(:direction) { :desc }

let!(:issue_1) { create(:issue, upvotes_count: 5) }

Check warning on line 75 in api/spec/models/issue_spec.rb

View workflow job for this annotation

GitHub Actions / rubocop

[rubocop] reported by reviewdog 🐶 Use normalcase for symbol numbers. Raw Output: spec/models/issue_spec.rb:75:10: C: Naming/VariableNumber: Use normalcase for symbol numbers.
let!(:issue_2) { create(:issue, upvotes_count: 10) }

Check warning on line 76 in api/spec/models/issue_spec.rb

View workflow job for this annotation

GitHub Actions / rubocop

[rubocop] reported by reviewdog 🐶 Use normalcase for symbol numbers. Raw Output: spec/models/issue_spec.rb:76:10: C: Naming/VariableNumber: Use normalcase for symbol numbers.

it 'returns issues sorted by upvotes desc' do
expect(sort_by_upvotes).to eq [issue_1, issue_2]
end
end
end
40 changes: 40 additions & 0 deletions api/spec/services/issues_feed_builder_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
require 'rails_helper'

RSpec.describe IssuesFeedBuilder do
subject(:service) { described_class.new(product:, sort_params:) }

let(:product) { create(:product) }

describe '#call' do
subject(:result) { service.call }

before do
create(:issue, upvotes_count: 10, comments_count: 5, product: product)

Check warning on line 12 in api/spec/services/issues_feed_builder_spec.rb

View workflow job for this annotation

GitHub Actions / rubocop

[rubocop] reported by reviewdog 🐶 Omit the hash value. Raw Output: spec/services/issues_feed_builder_spec.rb:12:69: C: Style/HashSyntax: Omit the hash value.
create(:issue, upvotes_count: 5, comments_count: 10, product: product)

Check warning on line 13 in api/spec/services/issues_feed_builder_spec.rb

View workflow job for this annotation

GitHub Actions / rubocop

[rubocop] reported by reviewdog 🐶 Omit the hash value. Raw Output: spec/services/issues_feed_builder_spec.rb:13:69: C: Style/HashSyntax: Omit the hash value.
end

context 'when sort params are not present' do
let(:sort_params) { nil }

it 'returns issues sorted by created_at desc' do
expect(result.pluck(:created_at)).to eq result.pluck(:created_at).sort.reverse
end
end

context 'when sorting by upvotes' do
let(:sort_params) { { sort_by: 'upvotes', sort_direction: 'desc' } }

it 'returns issues sorted by upvotes desc' do
expect(result.pluck(:upvotes_count)).to eq [10, 5]
end
end

context 'when sorting by comments' do
let(:sort_params) { { sort_by: 'comments', sort_direction: 'desc' } }

it 'returns issues sorted by comments desc' do
expect(result.pluck(:comments_count)).to eq [10, 5]
end
end
end
end

0 comments on commit ba3b6a5

Please sign in to comment.