Conversation
There was a problem hiding this comment.
🔵 Needs a closer look
One or more issues must be addressed before approval.
Pull request overview
Exposes HTTP response headers for Browse-related response objects and propagates them through synchronous and asynchronous requests.
Changes:
- Added header access to Browse, Browse Facets, and Facet Options responses.
- Propagated headers to successful responses and
ConstructorException. - Added success and error header tests for Browse endpoints.
File summaries
| File | Description |
|---|---|
| constructorio-client/src/test/java/io/constructor/client/ConstructorIOBrowseResponseHeadersTest.java | Updated as part of this pull request. |
| constructorio-client/src/main/java/io/constructor/client/models/BrowseResponse.java | Updated as part of this pull request. |
| constructorio-client/src/main/java/io/constructor/client/models/BrowseFacetsResponse.java | Updated as part of this pull request. |
| constructorio-client/src/main/java/io/constructor/client/models/BrowseFacetOptionsResponse.java | Updated as part of this pull request. |
| constructorio-client/src/main/java/io/constructor/client/ConstructorIO.java | Updated as part of this pull request. |
Review details
Suppressed comments (2)
constructorio-client/src/main/java/io/constructor/client/ConstructorIO.java:1467
- The new asynchronous
browsepath is not covered by the added header tests:ConstructorIOBrowseAsyncTestexercises callback success but never checksresponse.getHeaders()or the failure callback'sConstructorException.getHeaders(). Add MockWebServer-backed async success and error cases so this distinct propagation path cannot regress independently of the synchronous methods.
headers = response.headers().toMultimap();
String json = getResponseBody(response);
BrowseResponse res = createBrowseResponse(json, headers);
constructorio-client/src/main/java/io/constructor/client/ConstructorIO.java:1656
- The new asynchronous
browseItemspath is not covered by the added header tests: the existing async tests do not assert headers on either the response or the failure exception. Add MockWebServer-backed async success and error cases for this overload so its separate header propagation logic is verified.
headers = response.headers().toMultimap();
String json = getResponseBody(response);
BrowseResponse res = createBrowseResponse(json, headers);
- Files reviewed: 5/5 changed files
- Comments generated: 0
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Copilot's review flagged that the callback-based browse/browseItems paths have their own header-propagation logic in ConstructorIO.java that wasn't covered by any test, so a regression there could slip through independently of the synchronous methods. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Also removes the unused ExpectedException rule, which had no remaining purpose once none of the tests in the file used it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…e-headers-ootb-browse
TarekAlQaddy
left a comment
There was a problem hiding this comment.
LGTM, left one small comment.
side q, wondering why we didn't add the headers to the "AsJson" methods for Search, Autocomplete and Browse?
| ConstructorIO constructor = | ||
| new ConstructorIO("", apiKey, false, "127.0.0.1", mockServer.getPort()); | ||
| BrowseRequest request = new BrowseRequest("Color", "Blue"); | ||
| BrowseResponse response = constructor.browse(request, null); |
There was a problem hiding this comment.
Could you add another test to the browse() overload that takes a callback? Same applies to the browseItems() overload
|
A little weird to add the headers in the JSON string we return imo. Would require quite a bit more convoluted parsing and re-stringing which idt the JSON methods are really looking for. |
There was a problem hiding this comment.
Code Review
This PR mirrors the pattern from #187 to expose HTTP response headers on Browse-family responses (BrowseResponse, BrowseFacetsResponse, BrowseFacetOptionsResponse) and on ConstructorException, with solid test coverage using MockWebServer.
Inline comments: 4 discussions added
Overall Assessment:
| } | ||
| }); | ||
|
|
||
| await().atMost(2, SECONDS).until(responseIsResolved()); |
There was a problem hiding this comment.
Important Issue: The instance fields responseResolved and exceptionResolved are never reset between tests. JUnit does not create a new test-class instance per test by default (it does with JUnit 5's default lifecycle, but this is JUnit 4). If an async callback from a previous test fires late, it can set responseResolved or exceptionResolved before the next test's await() check, causing a false-positive assertion on stale data.
Add a @Before method to reset the fields before each test:
@Before
public void resetState() {
responseResolved = null;
exceptionResolved = null;
}(Also applies to all other async tests in this file that rely on these fields.)
Similar to #187, but just for Browse