From 509e7d0e7886592175aad5381551da609bfdc2a5 Mon Sep 17 00:00:00 2001 From: Dwight Scott Date: Wed, 9 Feb 2022 15:30:15 -0500 Subject: [PATCH] Modify tags api index to allow for bulk GET of tags (#16417) --- app/controllers/api/v0/tags_controller.rb | 10 ++++--- app/views/api/v0/tags/index.json.jbuilder | 9 +++++- spec/requests/api/v0/tags_spec.rb | 35 +++++++++++++++++++---- 3 files changed, 44 insertions(+), 10 deletions(-) diff --git a/app/controllers/api/v0/tags_controller.rb b/app/controllers/api/v0/tags_controller.rb index fe8e7a08a..461d548ac 100644 --- a/app/controllers/api/v0/tags_controller.rb +++ b/app/controllers/api/v0/tags_controller.rb @@ -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 diff --git a/app/views/api/v0/tags/index.json.jbuilder b/app/views/api/v0/tags/index.json.jbuilder index f95de7d02..aa7017efd 100644 --- a/app/views/api/v0/tags/index.json.jbuilder +++ b/app/views/api/v0/tags/index.json.jbuilder @@ -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 diff --git a/spec/requests/api/v0/tags_spec.rb b/spec/requests/api/v0/tags_spec.rb index 9e87196a9..cee0dca01 100644 --- a/spec/requests/api/v0/tags_spec.rb +++ b/spec/requests/api/v0/tags_spec.rb @@ -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