Skip to content

Commit a767810

Browse files
committed
fix: add required sort kwarg to ProductAttributes#list
The OpenAPI spec marks sort as required: true on listProductAttributes, but the gem method signature only took page: and size:. A real API call would have come back 400. The existing test passed because WebMock's query matcher is a subset match — the stub had only page+size and didn't notice the missing sort. Also adds a ProductAttributes#each method for full-iteration ergonomics, mirroring the each helpers on Products and Structures. The shared paginate_through helper in Resources::Base forwards only kwargs, so a custom each is needed for resources whose list method takes a positional id (in this case product_id). Found via a systematic spec-vs-gem audit script. All other operations had their required query params declared correctly.
1 parent 3085131 commit a767810

2 files changed

Lines changed: 36 additions & 5 deletions

File tree

lib/feed_pim/resources/product_attributes.rb

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,27 @@ module FeedPim
44
module Resources
55
class ProductAttributes < Base
66
operation :listProductAttributes
7-
def list(product_id, page:, size:)
7+
def list(product_id, page:, size:, sort:)
88
request(
99
:get, "/v2/products/#{product_id}/attributes",
10-
params: { page: page, size: size },
10+
params: { page: page, size: size, sort: sort },
1111
decoder: :decode_page_of_product_attribute
1212
)
1313
end
1414

15+
def each(product_id, size: 100, sort: ["sortNo,asc"], &block)
16+
return to_enum(:each, product_id, size: size, sort: sort) unless block_given?
17+
18+
page_index = 0
19+
loop do
20+
page = list(product_id, page: page_index, size: size, sort: sort)
21+
page.content.each(&block)
22+
break if page.last?
23+
24+
page_index += 1
25+
end
26+
end
27+
1528
operation :getProductAttribute
1629
def get(product_id, attribute_id)
1730
request(

spec/feed_pim/resources/product_attributes_spec.rb

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,37 @@
33
RSpec.describe FeedPim::Resources::ProductAttributes do
44
include_context "with client"
55

6-
it "lists product attributes (paginated)" do
6+
it "lists product attributes (paginated, with required sort)" do
77
stub_request(:get, "#{api_url}/v2/products/p1/attributes")
8-
.with(query: { page: "0", size: "100" })
8+
.with(query: { page: "0", size: "100", sort: "sortNo,asc" })
99
.to_return(status: 200,
1010
body: { content: [{ attributeId: "a", dataType: "TEXT" }],
1111
totalElements: 1, totalPages: 1, size: 100, number: 0 }.to_json,
1212
headers: { "Content-Type" => "application/json" })
1313

14-
page = client.product_attributes.list("p1", page: 0, size: 100)
14+
page = client.product_attributes.list("p1", page: 0, size: 100, sort: ["sortNo,asc"])
1515
expect(page.content.first).to be_a(FeedPim::Types::ProductAttribute)
1616
expect(page.content.first.attribute_id).to eq("a")
1717
end
1818

19+
it "iterates every attribute across all pages with #each" do
20+
stub_request(:get, "#{api_url}/v2/products/p1/attributes")
21+
.with(query: { page: "0", size: "200", sort: "sortNo,asc" })
22+
.to_return(status: 200,
23+
body: { content: [{ attributeId: "a1" }], totalElements: 2,
24+
totalPages: 2, size: 200, number: 0 }.to_json,
25+
headers: { "Content-Type" => "application/json" })
26+
stub_request(:get, "#{api_url}/v2/products/p1/attributes")
27+
.with(query: { page: "1", size: "200", sort: "sortNo,asc" })
28+
.to_return(status: 200,
29+
body: { content: [{ attributeId: "a2" }], totalElements: 2,
30+
totalPages: 2, size: 200, number: 1 }.to_json,
31+
headers: { "Content-Type" => "application/json" })
32+
33+
ids = client.product_attributes.each("p1", size: 200).map(&:attribute_id)
34+
expect(ids).to eq(%w[a1 a2])
35+
end
36+
1937
it "gets a single product attribute" do
2038
stub_request(:get, "#{api_url}/v2/products/p1/attributes/a")
2139
.to_return(status: 200,

0 commit comments

Comments
 (0)