Skip to content

Commit c816697

Browse files
Add comprehensive unit tests for Query class, specifically for the greaterThanOrEqualTo method, covering various scenarios including null keys, existing keys, chaining, and different value types to enhance test coverage.
1 parent 12bfaa6 commit c816697

File tree

2 files changed

+273
-0
lines changed

2 files changed

+273
-0
lines changed

src/test/java/com/contentstack/sdk/TestQuery.java

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1518,4 +1518,188 @@ void testEmptyArrayValidation() {
15181518
// Empty array should not create objectUidForExcept
15191519
assertNull(query.objectUidForExcept);
15201520
}
1521+
1522+
// ========== COMPREHENSIVE TESTS FOR greaterThanOrEqualTo ==========
1523+
1524+
@Test
1525+
void testGreaterThanOrEqualToWithNullKeyInQueryValueJSON() {
1526+
// Test the first branch: queryValueJSON.isNull(key) is true
1527+
// AND queryValue.length() == 0
1528+
query.queryValue = new JSONObject(); // Empty queryValue
1529+
query.queryValueJSON.put("price", JSONObject.NULL);
1530+
1531+
Query result = query.greaterThanOrEqualTo("price", 50);
1532+
1533+
assertNotNull(result);
1534+
assertTrue(query.queryValueJSON.has("price"));
1535+
assertNotEquals(JSONObject.NULL, query.queryValueJSON.get("price"));
1536+
1537+
// Verify the $gte operator was added
1538+
JSONObject priceQuery = query.queryValueJSON.getJSONObject("price");
1539+
assertTrue(priceQuery.has("$gte"));
1540+
assertEquals(50, priceQuery.get("$gte"));
1541+
}
1542+
1543+
@Test
1544+
void testGreaterThanOrEqualToWithNullKeyAndNonEmptyQueryValue() {
1545+
// Test the first branch: queryValueJSON.isNull(key) is true
1546+
// AND queryValue.length() > 0 (should reset queryValue)
1547+
query.queryValue = new JSONObject();
1548+
query.queryValue.put("existing_operator", "some_value"); // Make queryValue non-empty
1549+
query.queryValueJSON.put("rating", JSONObject.NULL);
1550+
1551+
Query result = query.greaterThanOrEqualTo("rating", 4.5);
1552+
1553+
assertNotNull(result);
1554+
assertTrue(query.queryValueJSON.has("rating"));
1555+
1556+
// Verify the $gte operator was added
1557+
JSONObject ratingQuery = query.queryValueJSON.getJSONObject("rating");
1558+
assertTrue(ratingQuery.has("$gte"));
1559+
assertEquals(4.5, ratingQuery.get("$gte"));
1560+
// The queryValue should have been reset, so it shouldn't have the old key
1561+
assertFalse(ratingQuery.has("existing_operator"));
1562+
}
1563+
1564+
@Test
1565+
void testGreaterThanOrEqualToWithExistingKeyInQueryValueJSON() {
1566+
// Test the second branch: queryValueJSON.has(key) is true
1567+
// First set up queryValue with an existing operator
1568+
query.queryValue = new JSONObject();
1569+
query.queryValue.put("$lt", 100);
1570+
query.queryValueJSON.put("age", query.queryValue);
1571+
1572+
Query result = query.greaterThanOrEqualTo("age", 18);
1573+
1574+
assertNotNull(result);
1575+
assertTrue(query.queryValueJSON.has("age"));
1576+
1577+
// Verify both operators exist in the same JSONObject
1578+
JSONObject ageQuery = query.queryValueJSON.getJSONObject("age");
1579+
assertTrue(ageQuery.has("$gte"));
1580+
assertEquals(18, ageQuery.get("$gte"));
1581+
// The previous operator should still be there since queryValue was reused
1582+
assertTrue(ageQuery.has("$lt"));
1583+
assertEquals(100, ageQuery.get("$lt"));
1584+
}
1585+
1586+
@Test
1587+
void testGreaterThanOrEqualToWithIntegerValue() {
1588+
Query result = query.greaterThanOrEqualTo("count", 100);
1589+
1590+
assertNotNull(result);
1591+
assertTrue(query.queryValueJSON.has("count"));
1592+
1593+
JSONObject countQuery = query.queryValueJSON.getJSONObject("count");
1594+
assertEquals(100, countQuery.get("$gte"));
1595+
}
1596+
1597+
@Test
1598+
void testGreaterThanOrEqualToWithDoubleValue() {
1599+
Query result = query.greaterThanOrEqualTo("price", 99.99);
1600+
1601+
assertNotNull(result);
1602+
assertTrue(query.queryValueJSON.has("price"));
1603+
1604+
JSONObject priceQuery = query.queryValueJSON.getJSONObject("price");
1605+
assertEquals(99.99, priceQuery.get("$gte"));
1606+
}
1607+
1608+
@Test
1609+
void testGreaterThanOrEqualToWithStringValue() {
1610+
Query result = query.greaterThanOrEqualTo("name", "Alice");
1611+
1612+
assertNotNull(result);
1613+
assertTrue(query.queryValueJSON.has("name"));
1614+
1615+
JSONObject nameQuery = query.queryValueJSON.getJSONObject("name");
1616+
assertEquals("Alice", nameQuery.get("$gte"));
1617+
}
1618+
1619+
@Test
1620+
void testGreaterThanOrEqualToChaining() {
1621+
Query result = query
1622+
.greaterThanOrEqualTo("min_price", 10)
1623+
.greaterThanOrEqualTo("min_rating", 3.0)
1624+
.greaterThanOrEqualTo("min_stock", 5);
1625+
1626+
assertNotNull(result);
1627+
assertTrue(query.queryValueJSON.has("min_price"));
1628+
assertTrue(query.queryValueJSON.has("min_rating"));
1629+
assertTrue(query.queryValueJSON.has("min_stock"));
1630+
1631+
assertEquals(10, query.queryValueJSON.getJSONObject("min_price").get("$gte"));
1632+
assertEquals(3.0, query.queryValueJSON.getJSONObject("min_rating").get("$gte"));
1633+
assertEquals(5, query.queryValueJSON.getJSONObject("min_stock").get("$gte"));
1634+
}
1635+
1636+
@Test
1637+
void testGreaterThanOrEqualToWithZeroValue() {
1638+
Query result = query.greaterThanOrEqualTo("score", 0);
1639+
1640+
assertNotNull(result);
1641+
assertTrue(query.queryValueJSON.has("score"));
1642+
1643+
JSONObject scoreQuery = query.queryValueJSON.getJSONObject("score");
1644+
assertEquals(0, scoreQuery.get("$gte"));
1645+
}
1646+
1647+
@Test
1648+
void testGreaterThanOrEqualToWithNegativeValue() {
1649+
Query result = query.greaterThanOrEqualTo("temperature", -10);
1650+
1651+
assertNotNull(result);
1652+
assertTrue(query.queryValueJSON.has("temperature"));
1653+
1654+
JSONObject tempQuery = query.queryValueJSON.getJSONObject("temperature");
1655+
assertEquals(-10, tempQuery.get("$gte"));
1656+
}
1657+
1658+
@Test
1659+
void testGreaterThanOrEqualToReplacingExistingOperator() {
1660+
// Add an initial $gte operator
1661+
query.greaterThanOrEqualTo("age", 18);
1662+
1663+
// Add another $gte operator on the same key - should update
1664+
Query result = query.greaterThanOrEqualTo("age", 21);
1665+
1666+
assertNotNull(result);
1667+
assertTrue(query.queryValueJSON.has("age"));
1668+
1669+
JSONObject ageQuery = query.queryValueJSON.getJSONObject("age");
1670+
// Should have the updated value
1671+
assertEquals(21, ageQuery.get("$gte"));
1672+
}
1673+
1674+
@Test
1675+
void testGreaterThanOrEqualToCombinedWithOtherOperators() {
1676+
// Combine with lessThanOrEqualTo to create a range query
1677+
Query result = query
1678+
.greaterThanOrEqualTo("price", 10)
1679+
.lessThanOrEqualTo("price", 100);
1680+
1681+
assertNotNull(result);
1682+
assertTrue(query.queryValueJSON.has("price"));
1683+
1684+
JSONObject priceQuery = query.queryValueJSON.getJSONObject("price");
1685+
assertTrue(priceQuery.has("$gte"));
1686+
assertTrue(priceQuery.has("$lte"));
1687+
assertEquals(10, priceQuery.get("$gte"));
1688+
assertEquals(100, priceQuery.get("$lte"));
1689+
}
1690+
1691+
@Test
1692+
void testGreaterThanOrEqualToWithValidKeyFormat() {
1693+
// Test with various valid key formats
1694+
Query result1 = query.greaterThanOrEqualTo("simple_key", 10);
1695+
Query result2 = query.greaterThanOrEqualTo("nested.field", 20);
1696+
Query result3 = query.greaterThanOrEqualTo("key_with_123", 30);
1697+
1698+
assertNotNull(result1);
1699+
assertNotNull(result2);
1700+
assertNotNull(result3);
1701+
assertTrue(query.queryValueJSON.has("simple_key"));
1702+
assertTrue(query.queryValueJSON.has("nested.field"));
1703+
assertTrue(query.queryValueJSON.has("key_with_123"));
1704+
}
15211705
}

src/test/java/com/contentstack/sdk/TestTaxonomy.java

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package com.contentstack.sdk;
22

3+
import okhttp3.ResponseBody;
34
import org.json.JSONObject;
45
import org.junit.jupiter.api.BeforeEach;
56
import org.junit.jupiter.api.Test;
7+
import retrofit2.Call;
68

79
import java.lang.reflect.Field;
810
import java.util.ArrayList;
@@ -537,5 +539,92 @@ void testQueryToStringContainsAllOperators() {
537539
// Verify it's valid JSON
538540
assertDoesNotThrow(() -> new JSONObject(queryString));
539541
}
542+
543+
// ========== TESTS FOR FIND METHOD ERROR HANDLING ==========
544+
// Note: The find() method is network-dependent and requires actual API calls.
545+
// Comprehensive error handling tests (IOException -> RuntimeException,
546+
// HTTP error codes 400/401/404/500, error message/code/detail parsing)
547+
// should be covered in integration tests (TaxonomyIT.java) where actual
548+
// network responses can be tested with valid credentials.
549+
//
550+
// Without mocking framework, unit tests for find() are limited to:
551+
// 1. Verifying makeRequest() returns a non-null Call object
552+
// 2. Verifying the query is properly constructed before the call
553+
//
554+
// Full error path coverage requires integration testing with real API responses.
555+
556+
@Test
557+
void testMakeRequestReturnsNonNullCall() {
558+
taxonomy.in("taxonomies.color", Arrays.asList("red", "blue"))
559+
.exists("taxonomies.size", true);
560+
561+
Call<ResponseBody> call = taxonomy.makeRequest();
562+
563+
assertNotNull(call, "makeRequest should return a non-null Call object");
564+
}
565+
566+
@Test
567+
void testQueryIsProperlyConstructedBeforeMakeRequest() {
568+
taxonomy.in("taxonomies.color", Arrays.asList("red"))
569+
.or(Arrays.asList(
570+
new JSONObject().put("taxonomies.size", "large"),
571+
new JSONObject().put("taxonomies.brand", "nike")
572+
))
573+
.exists("taxonomies.stock", true);
574+
575+
// Verify query contains all expected keys
576+
assertTrue(taxonomy.query.has("taxonomies.color"));
577+
assertTrue(taxonomy.query.has("$or"));
578+
assertTrue(taxonomy.query.has("taxonomies.stock"));
579+
580+
// Verify query is valid JSON
581+
String queryString = taxonomy.query.toString();
582+
assertDoesNotThrow(() -> new JSONObject(queryString));
583+
584+
// Verify makeRequest can be called without error
585+
assertDoesNotThrow(() -> taxonomy.makeRequest());
586+
}
587+
588+
@Test
589+
void testFindMethodSignatureAndCallbackInterface() {
590+
// Verify TaxonomyCallback interface contract
591+
final boolean[] callbackCalled = {false};
592+
final JSONObject[] receivedResponse = new JSONObject[1];
593+
final Error[] receivedError = new Error[1];
594+
595+
TaxonomyCallback callback = new TaxonomyCallback() {
596+
@Override
597+
public void onResponse(JSONObject response, Error error) {
598+
callbackCalled[0] = true;
599+
receivedResponse[0] = response;
600+
receivedError[0] = error;
601+
}
602+
};
603+
604+
// Verify callback can be instantiated and methods are accessible
605+
assertNotNull(callback);
606+
607+
// Test callback with null error (success case)
608+
callback.onResponse(new JSONObject().put("test", "data"), null);
609+
assertTrue(callbackCalled[0]);
610+
assertNotNull(receivedResponse[0]);
611+
assertNull(receivedError[0]);
612+
613+
// Reset and test with error (failure case)
614+
callbackCalled[0] = false;
615+
receivedResponse[0] = null;
616+
receivedError[0] = null;
617+
618+
Error testError = new Error();
619+
testError.setErrorMessage("Test error");
620+
testError.setErrorCode(400);
621+
622+
callback.onResponse(null, testError);
623+
assertTrue(callbackCalled[0]);
624+
assertNull(receivedResponse[0]);
625+
assertNotNull(receivedError[0]);
626+
assertEquals("Test error", receivedError[0].getErrorMessage());
627+
assertEquals(400, receivedError[0].getErrorCode());
628+
}
540629
}
541630

0 commit comments

Comments
 (0)