Modify tags api index to allow for bulk GET of tags (#16417)

This commit is contained in:
Dwight Scott 2022-02-09 15:30:15 -05:00 committed by GitHub
parent 0e900fd4dd
commit 509e7d0e78
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 44 additions and 10 deletions

View file

@ -3,17 +3,19 @@ module Api
class TagsController < ApiController
before_action :set_cache_control_headers, only: %i[index]
ATTRIBUTES_FOR_SERIALIZATION = %i[id name bg_color_hex text_color_hex].freeze
ATTRIBUTES_FOR_SERIALIZATION = %i[id name bg_color_hex text_color_hex short_summary badge_id].freeze
private_constant :ATTRIBUTES_FOR_SERIALIZATION
def index
@tags = Tag.includes(:badge).select(ATTRIBUTES_FOR_SERIALIZATION)
page = params[:page]
per_page = (params[:per_page] || 10).to_i
num = [per_page, 1000].min
@tags = Tag.select(ATTRIBUTES_FOR_SERIALIZATION)
.order(taggings_count: :desc)
.page(page).per(num)
@tags = @tags.where(id: params[:tag_ids]) if params[:tag_ids].present?
@tags = @tags.order(taggings_count: :desc).page(page).per(num)
set_surrogate_key_header Tag.table_key, @tags.map(&:record_key)
end

View file

@ -1,3 +1,10 @@
json.array! @tags.each do |tag|
json.extract!(tag, :id, :name, :bg_color_hex, :text_color_hex)
json.extract!(tag, :id, :name, :bg_color_hex, :text_color_hex, :short_summary)
json.badge do
if tag.badge
json.badge_image tag.badge.badge_image
else
json.badge_image nil
end
end
end

View file

@ -11,16 +11,19 @@ RSpec.describe "Api::V0::Tags", type: :request do
end
it "returns tags with the correct json representation" do
badge = create(:badge)
tag = create(:tag, taggings_count: 10)
tag_with_badge = create(:tag, taggings_count: 5, badge: badge)
get api_tags_path
response_tag = response.parsed_body.first
expect(response_tag.keys).to match_array(%w[id name bg_color_hex text_color_hex])
expect(response_tag["id"]).to eq(tag.id)
expect(response_tag["name"]).to eq(tag.name)
expect(response_tag["bg_color_hex"]).to eq(tag.bg_color_hex)
expect(response_tag["text_color_hex"]).to eq(tag.text_color_hex)
response_tag_with_badge = response.parsed_body.last
expect_valid_json_body(response_tag, tag)
expect_valid_json_body(response_tag_with_badge, tag_with_badge)
expect(response_tag["badge"]["badge_image"]).to be_nil
expect(response_tag_with_badge["badge"]["badge_image"]["url"]).to eq(tag_with_badge.badge.badge_image.url)
end
it "orders tags by taggings_count in a descending order" do
@ -33,6 +36,15 @@ RSpec.describe "Api::V0::Tags", type: :request do
expect(response.parsed_body.map { |t| t["id"] }).to eq(expected_result)
end
it "finds tags from array of tag_ids" do
tags = create_list(:tag, 10, taggings_count: 10)
tag_ids = tags.sample(4).map(&:id)
get api_tags_path, params: { tag_ids: tag_ids }
expect(response.parsed_body.map { |t| t["id"] }).to match_array(tag_ids)
end
it "supports pagination" do
create_list(:tag, 3)
@ -52,4 +64,17 @@ RSpec.describe "Api::V0::Tags", type: :request do
expect(response.headers["surrogate-key"].split.to_set).to eq(expected_key)
end
end
private
def expect_valid_json_body(body, tag)
expect(body.keys).to match_array(%w[id name bg_color_hex text_color_hex short_summary badge])
expect(body["id"]).to eq(tag.id)
expect(body["name"]).to eq(tag.name)
expect(body["bg_color_hex"]).to eq(tag.bg_color_hex)
expect(body["text_color_hex"]).to eq(tag.text_color_hex)
expect(body["short_summary"]).to eq(tag.short_summary)
expect(body).to have_key("badge")
expect(body["badge"]).to have_key("badge_image")
end
end