From de6b4d6c91817a344eb357418a56d78498c502c0 Mon Sep 17 00:00:00 2001 From: arjunjain Date: Thu, 13 Aug 2026 11:49:55 +0530 Subject: [PATCH] Rename market symbol filter to market_id; model both in Article Sync with python-client: the /market and /market/count endpoints now take market_id instead of symbol. The old filter was removed upstream, so no alias is kept. Also add symbol and marketId to the Article record. The API returns both fields as string arrays; neither was modelled before. Article is only ever JSON-decoded, so appending record components is source-compatible. --- src/main/java/io/newsdata/api/Article.java | 4 ++- src/main/java/io/newsdata/api/Constants.java | 4 +-- .../newsdata/api/NewsDataApiClientTest.java | 26 +++++++++++++++++++ 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/main/java/io/newsdata/api/Article.java b/src/main/java/io/newsdata/api/Article.java index 4fb4024..85aae99 100644 --- a/src/main/java/io/newsdata/api/Article.java +++ b/src/main/java/io/newsdata/api/Article.java @@ -41,5 +41,7 @@ public record Article( @JsonProperty("ai_org") List aiOrg, @JsonProperty("sentiment") String sentiment, @JsonProperty("sentiment_stats") Map sentimentStats, - @JsonProperty("datatype") String dataType + @JsonProperty("datatype") String dataType, + @JsonProperty("symbol") List symbol, + @JsonProperty("market_id") List marketId ) {} diff --git a/src/main/java/io/newsdata/api/Constants.java b/src/main/java/io/newsdata/api/Constants.java index aff7122..87b7988 100644 --- a/src/main/java/io/newsdata/api/Constants.java +++ b/src/main/java/io/newsdata/api/Constants.java @@ -109,7 +109,7 @@ private Constants() {} "excludecountry", "domain", "domainurl", "excludedomain", "language", "excludelanguage", "prioritydomain", "timezone", "timeframe", "size", "full_content", "image", "video", "page", "tag", "sentiment", - "excludefield", "removeduplicate", "organization", "symbol", "id", "url", + "excludefield", "removeduplicate", "organization", "market_id", "id", "url", "sort", "creator", "datatype", "sentiment_score" )), Map.entry("count", Set.of( @@ -130,7 +130,7 @@ private Constants() {} "from_date", "to_date", "q", "qintitle", "qinmeta", "country", "excludecountry", "domain", "domainurl", "excludedomain", "language", "excludelanguage", "full_content", "image", "video", "organization", - "symbol", "prioritydomain", "page", "sentiment", "removeduplicate", "size", + "market_id", "prioritydomain", "page", "sentiment", "removeduplicate", "size", "sort", "tag", "interval", "creator", "datatype", "sentiment_score" )) ); diff --git a/src/test/java/io/newsdata/api/NewsDataApiClientTest.java b/src/test/java/io/newsdata/api/NewsDataApiClientTest.java index bef4a57..55944d0 100644 --- a/src/test/java/io/newsdata/api/NewsDataApiClientTest.java +++ b/src/test/java/io/newsdata/api/NewsDataApiClientTest.java @@ -2,6 +2,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; @@ -243,6 +244,31 @@ void articleFieldsDecodeFromSnakeCase() { assertEquals(1, art.sourcePriority()); } + // Market results carry both `symbol` and `market_id`; the two are separate + // response fields and both decode onto Article. + @Test + void articleDecodesSymbolAndMarketId() { + handle("market", exchange -> respond(exchange, 200, + successBody("[{\"article_id\":\"m1\",\"symbol\":[\"AAPL\",\"MSFT\"]," + + "\"market_id\":[\"NASDAQ:AAPL\",\"NASDAQ:MSFT\"]}]"))); + var client = defaultBuilder().build(); + var resp = client.market(Params.of().with("market_id", "AAPL")); + var art = resp.articles(client.objectMapper()).get(0); + assertEquals(List.of("AAPL", "MSFT"), art.symbol()); + assertEquals(List.of("NASDAQ:AAPL", "NASDAQ:MSFT"), art.marketId()); + } + + @Test + void articleSymbolAndMarketIdAreNullWhenAbsent() { + handle("latest", exchange -> respond(exchange, 200, + successBody("[{\"article_id\":\"a1\",\"title\":\"t\"}]"))); + var client = defaultBuilder().build(); + var art = client.latest(Params.of().with("q", "x")) + .articles(client.objectMapper()).get(0); + assertNull(art.symbol()); + assertNull(art.marketId()); + } + @Test void countReturnsAggregateMap() { handle("count", exchange -> respond(exchange, 200,