Skip to content

Commit b4bc72e

Browse files
authored
Merge pull request #62 from contentstack/feat/DX-199-Taxonomy-implementation-testcase
Feat/dx 199 taxonomy implementation testcase
2 parents d89986a + 5c5dfa2 commit b4bc72e

File tree

14 files changed

+697
-14
lines changed

14 files changed

+697
-14
lines changed

CHANGELOG.md

+8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# CHANGELOG
22

3+
## Version 3.16.0
4+
5+
### Date: 31-July-2024
6+
7+
- Taxonomy Support
8+
9+
---
10+
311
## Version 3.15.1
412

513
### Date: 24-June-2024

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ Or,
4141

4242
To add the Contentstack Android SDK to your existing project manually, perform the steps given below:
4343

44-
1. [Download the Android SDK](https://docs.contentstack.com/platforms/android/android_sdk_latest)
44+
1. [Download the Android SDK](https://github.com/contentstack/contentstack-android/archive/refs/heads/master.zip)
4545
and extract the ZIP file to your local disk.
4646
2. Add references/dependencies using Eclipse/Android Studio:
4747

contentstack/build.gradle

+27-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ android.buildFeatures.buildConfig true
1010
mavenPublishing {
1111
publishToMavenCentral(SonatypeHost.DEFAULT)
1212
signAllPublications()
13-
coordinates("com.contentstack.sdk", "android", "3.15.1")
13+
coordinates("com.contentstack.sdk", "android", "3.16.0")
1414

1515
pom {
1616
name = "contentstack-android"
@@ -67,6 +67,8 @@ android {
6767
exclude("META-INF/notice.txt")
6868
exclude("META-INF/ASL2.0")
6969
exclude("META-INF/*.kotlin_module")
70+
exclude("META-INF/LICENSE.md")
71+
exclude("META-INF/LICENSE-notice.md")
7072
}
7173

7274
testOptions {
@@ -99,7 +101,7 @@ android {
99101
defaultConfig {
100102
// Required when setting minSdkVersion to 20 or lower
101103
multiDexEnabled true
102-
minSdkVersion 23
104+
minSdk 24
103105
versionCode 1
104106
versionName "1.0"
105107
useLibrary 'org.apache.http.legacy'
@@ -137,13 +139,15 @@ android {
137139
}
138140
configurations { archives }
139141
dependencies {
142+
androidTestImplementation 'org.junit.jupiter:junit-jupiter:5.8.1'
140143
def multidex = "2.0.1"
141144
def volley = "1.2.1"
142145
def junit = "4.13.2"
143146
configurations.configureEach { resolutionStrategy.force 'com.android.support:support-annotations:23.1.0' }
144147
implementation fileTree(include: ['*.jar'], dir: 'libs')
145148
implementation "com.android.volley:volley:$volley"
146149
implementation "junit:junit:$junit"
150+
147151
// For AGP 7.4+
148152
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4'
149153
testImplementation 'junit:junit:4.13.2'
@@ -154,6 +158,27 @@ dependencies {
154158

155159
// implementation 'com.squareup.okio:okio:3.9.0'
156160
implementation 'com.github.rjeschke:txtmark:0.12'
161+
// // Retrofit
162+
implementation("com.squareup.retrofit2:retrofit:2.9.0")
163+
implementation 'com.squareup.retrofit2:converter-gson'
164+
// // OkHttp
165+
implementation 'com.squareup.okhttp3:okhttp'
166+
// implementation 'com.squareup.okhttp3:logging-interceptor:4.9.3'
167+
168+
constraints {
169+
implementation('com.squareup.retrofit2:converter-gson:2.9.0') {
170+
because 'gson 2.8.5 used by retrofit has a vulnerability'
171+
}
172+
implementation('com.google.code.gson:[email protected]') {
173+
because 'gson 2.8.5 used by retrofit has a vulnerability'
174+
}
175+
implementation('com.squareup.okhttp3:okhttp:4.9.3') {
176+
because 'kotlin stdlib 1.4.10 used by okhttp has a vulnerability'
177+
}
178+
implementation('org.jetbrains.kotlin:[email protected]') {
179+
because 'kotlin stdlib 1.4.10 used by okhttp has a vulnerability'
180+
}
181+
}
157182
}
158183
tasks.register('clearJar', Delete) { delete 'build/libs/contentstack.jar' }
159184
tasks.register('unzip', Copy) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
package com.contentstack.sdk;
2+
3+
import org.json.JSONArray;
4+
import org.json.JSONException;
5+
import org.json.JSONObject;
6+
import org.junit.runners.MethodSorters;
7+
import org.junit.*;
8+
9+
import java.io.IOException;
10+
import java.lang.reflect.Field;
11+
import java.util.ArrayList;
12+
import java.util.List;
13+
import java.util.Map;
14+
import java.util.concurrent.CountDownLatch;
15+
16+
import static junit.framework.TestCase.*;
17+
18+
import android.content.Context;
19+
import android.util.Log;
20+
21+
import androidx.test.core.app.ApplicationProvider;
22+
23+
import okhttp3.Request;
24+
import okhttp3.ResponseBody;
25+
import retrofit2.Call;
26+
import retrofit2.Response;
27+
28+
29+
public class TaxonomyTestCase {
30+
31+
private static Stack stack;
32+
private final static String TAG = TaxonomyTestCase.class.getSimpleName();
33+
34+
35+
@BeforeClass
36+
public static void oneTimeSetUp() throws Exception {
37+
Context appContext = ApplicationProvider.getApplicationContext();
38+
Config config = new Config();
39+
String DEFAULT_HOST = BuildConfig.host;
40+
config.setHost(DEFAULT_HOST);
41+
stack = Contentstack.stack(appContext, BuildConfig.APIKey, BuildConfig.deliveryToken, BuildConfig.environment, config);
42+
}
43+
44+
@Test
45+
public void testInstance() {
46+
assertNotNull(stack);
47+
}
48+
49+
@Test
50+
public void operationIn() {
51+
Taxonomy taxonomy = stack.taxonomy();
52+
List<String> listOfItems = new ArrayList<>();
53+
listOfItems.add("maroon");
54+
listOfItems.add("red");
55+
Request req = taxonomy.in("taxonomies.color", listOfItems).makeRequest().request();
56+
assertEquals("GET", req.method());
57+
assertEquals("cdn.contentstack.io", req.url().host());
58+
assertEquals("/v3/taxonomies/entries", req.url().encodedPath());
59+
assertEquals("query={\"taxonomies.color\":{\"$in\":[\"maroon\",\"red\"]}}", req.url().query());
60+
}
61+
62+
@Test
63+
public void operationOr() throws JSONException, IOException {
64+
// query={ $or: [
65+
// { "taxonomies.taxonomy_uid_1" : "term_uid1" },
66+
// { "taxonomies.taxonomy_uid_2" : "term_uid2" }
67+
// ]}
68+
Taxonomy taxonomy = stack.taxonomy();
69+
List<JSONObject> listOfItems = new ArrayList<>();
70+
JSONObject item1 = new JSONObject();
71+
item1.put("taxonomies.color", "orange");
72+
JSONObject item2 = new JSONObject();
73+
item2.put("taxonomies.country", "zambia");
74+
listOfItems.add(item1);
75+
listOfItems.add(item2);
76+
taxonomy.or(listOfItems);
77+
Request req = taxonomy.makeRequest().request();
78+
assertEquals("query={\"$or\":[{\"taxonomies.color\":\"orange\"},{\"taxonomies.country\":\"zambia\"}]}", req.url().query());
79+
80+
}
81+
82+
@Test
83+
public void operatorAnd() throws JSONException {
84+
Taxonomy taxonomy = stack.taxonomy();
85+
List<JSONObject> listOfItems = new ArrayList<>();
86+
JSONObject items1 = new JSONObject();
87+
items1.put("taxonomies.color", "green");
88+
JSONObject items2 = new JSONObject();
89+
items2.put("taxonomies.country", "india");
90+
listOfItems.add(items1);
91+
listOfItems.add(items2);
92+
taxonomy.and(listOfItems);
93+
Request req = taxonomy.makeRequest().request();
94+
assertEquals("query={\"$and\":[{\"taxonomies.color\":\"green\"},{\"taxonomies.country\":\"india\"}]}", req.url().query());
95+
}
96+
97+
98+
@Test
99+
public void operationExists() throws IOException {
100+
Taxonomy taxonomy = stack.taxonomy().exists("taxonomies.color", true);
101+
Request req = taxonomy.makeRequest().request();
102+
assertEquals("query={\"taxonomies.color\":{\"$exists\":true}}", req.url().query());
103+
}
104+
105+
106+
@Test
107+
public void operationEqualAndBelow() throws IOException {
108+
Taxonomy taxonomy = stack.taxonomy().equalAndBelow("taxonomies.color", "red");
109+
Request req = taxonomy.makeRequest().request();
110+
assertEquals("query={\"taxonomies.color\":{\"$eq_below\":\"red\"}}", req.url().query());
111+
}
112+
113+
114+
@Test
115+
public void operationEqualAbove() {
116+
Taxonomy taxonomy = stack.taxonomy().equalAbove("taxonomies.appliances", "led");
117+
Request req = taxonomy.makeRequest().request();
118+
assertEquals("query={\"taxonomies.appliances\":{\"$eq_above\":\"led\"}}", req.url().query());
119+
120+
}
121+
122+
@Test
123+
public void above() {
124+
Taxonomy taxonomy = stack.taxonomy().above("taxonomies.appliances", "led");
125+
Request req = taxonomy.makeRequest().request();
126+
assertEquals("query={\"taxonomies.appliances\":{\"$above\":\"led\"}}", req.url().query());
127+
}
128+
129+
@Test
130+
public void below() {
131+
Taxonomy taxonomy = stack.taxonomy().below("taxonomies.appliances", "TV");
132+
Request req = taxonomy.makeRequest().request();
133+
assertEquals("query={\"taxonomies.appliances\":{\"$below\":\"TV\"}}", req.url().query());
134+
}
135+
136+
@Test
137+
public void aboveAPI() {
138+
Taxonomy taxonomy = stack.taxonomy().below("taxonomies.color", "red");
139+
Request req = taxonomy.makeRequest().request();
140+
taxonomy.find(new TaxonomyCallback() {
141+
@Override
142+
public void onResponse(JSONObject response, Error error) {
143+
Log.d("Result",response.toString());
144+
}
145+
});
146+
assertEquals("query={\"taxonomies.color\":{\"$below\":\"red\"}}", req.url().query());
147+
}
148+
149+
150+
}
151+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.contentstack.sdk;
2+
3+
import okhttp3.ResponseBody;
4+
import retrofit2.Call;
5+
import retrofit2.http.GET;
6+
import retrofit2.http.HeaderMap;
7+
import retrofit2.http.Query;
8+
import retrofit2.http.Url;
9+
10+
import java.util.LinkedHashMap;
11+
import java.util.Map;
12+
13+
14+
public interface APIService {
15+
@GET
16+
Call<ResponseBody> getRequest(
17+
@Url String url, @HeaderMap LinkedHashMap<String, Object> headers);
18+
19+
@GET("v3/taxonomies/entries")
20+
Call<ResponseBody> getTaxonomy(
21+
@HeaderMap Map<String, Object> headers,
22+
@Query("query") String query);
23+
}

contentstack/src/main/java/com/contentstack/sdk/Asset.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -385,8 +385,8 @@ public void fetch(FetchResultCallback callback) {
385385
urlQueries.put("environment", headers.get("environment"));
386386
}
387387
String mainStringForMD5 = urlEndpoint + new JSONObject().toString() + headers.toString();
388-
String md5Value = new SDKUtil().getMD5FromString(mainStringForMD5.trim());
389-
File cacheFile = new File(SDKConstant.cacheFolderName + File.separator + md5Value);
388+
String shaValue = new SDKUtil().getSHAFromString(mainStringForMD5.trim());
389+
File cacheFile = new File(SDKConstant.cacheFolderName + File.separator + shaValue);
390390

391391
switch (cachePolicyForCall) {
392392
case IGNORE_CACHE:

contentstack/src/main/java/com/contentstack/sdk/AssetLibrary.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,8 @@ public void fetchAll(FetchAssetsCallback assetsCallback) {
215215
urlQueries.put("environment", headers.get("environment"));
216216
}
217217
String mainStringForMD5 = URL + new JSONObject().toString() + headers.toString();
218-
String md5Value = new SDKUtil().getMD5FromString(mainStringForMD5.trim());
219-
File cacheFile = new File(SDKConstant.cacheFolderName + File.separator + md5Value);
218+
String shaValue = new SDKUtil().getSHAFromString(mainStringForMD5.trim());
219+
File cacheFile = new File(SDKConstant.cacheFolderName + File.separator + shaValue);
220220
switch (cachePolicyForCall) {
221221
case IGNORE_CACHE:
222222
fetchFromNetwork(URL, urlQueries, headers, cacheFile.getPath(), assetsCallback);

contentstack/src/main/java/com/contentstack/sdk/Config.java

+58
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22

33
import android.text.TextUtils;
44

5+
import java.net.Proxy;
56
import java.util.Objects;
7+
import java.util.concurrent.TimeUnit;
8+
9+
import okhttp3.ConnectionPool;
610

711

812
/**
@@ -17,6 +21,10 @@ public class Config {
1721
protected String environment = null;
1822
protected String branch = null;
1923
protected String[] earlyAccess = null;
24+
protected Proxy proxy = null;
25+
protected ConnectionPool connectionPool = new ConnectionPool();
26+
protected String endpoint;
27+
2028

2129

2230
/**
@@ -179,5 +187,55 @@ public String getEnvironment() {
179187
return environment;
180188
}
181189

190+
/**
191+
* Proxy can be set like below.
192+
*
193+
* @param proxy Proxy setting, typically a type (http, socks) and a socket address. A Proxy is an immutable object
194+
* <br>
195+
* <br>
196+
* <b>Example:</b><br>
197+
* <br>
198+
* <code>
199+
* java.net.Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("proxyHost", "proxyPort"));
200+
* java.net.Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("sl.theproxyvpn.io", 80)); Config
201+
* config = new Config(); config.setProxy(proxy);
202+
* </code>
203+
*/
204+
public void setProxy(Proxy proxy) {
205+
this.proxy = proxy;
206+
}
207+
208+
/**
209+
* Returns the Proxy instance
210+
*
211+
* @return Proxy
212+
*/
213+
public Proxy getProxy() {
214+
return this.proxy;
215+
}
216+
217+
/**
218+
* Manages reuse of HTTP and HTTP/2 connections for reduced network latency. HTTP requests that * share the same
219+
* {@link okhttp3.Address} may share a {@link okhttp3.Connection}. This class implements the policy * of which
220+
* connections to keep open for future use.
221+
*
222+
* @param maxIdleConnections the maxIdleConnections default value is 5
223+
* @param keepAliveDuration the keepAliveDuration default value is 5
224+
* @param timeUnit the timeUnit default value is TimeUnit. MINUTES
225+
* @return ConnectionPool
226+
*/
227+
public ConnectionPool connectionPool(int maxIdleConnections, long keepAliveDuration, TimeUnit timeUnit) {
228+
this.connectionPool = new ConnectionPool(maxIdleConnections, keepAliveDuration, timeUnit);
229+
return this.connectionPool;
230+
}
231+
232+
protected String getEndpoint() {
233+
return endpoint + "/" + getVersion() + "/";
234+
}
235+
236+
protected void setEndpoint(String endpoint) {
237+
this.endpoint = endpoint;
238+
}
239+
182240

183241
}

contentstack/src/main/java/com/contentstack/sdk/Entry.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1087,9 +1087,9 @@ public void fetch(EntryResultCallBack callBack) {
10871087
}
10881088

10891089
String mainStringForMD5 = URL + new JSONObject().toString() + headerAll.toString();
1090-
String md5Value = new SDKUtil().getMD5FromString(mainStringForMD5.trim());
1090+
String shaValue = new SDKUtil().getSHAFromString(mainStringForMD5.trim());
10911091

1092-
File cacheFile = new File(SDKConstant.cacheFolderName + File.separator + md5Value);
1092+
File cacheFile = new File(SDKConstant.cacheFolderName + File.separator + shaValue);
10931093

10941094

10951095
switch (cachePolicyForCall) {

contentstack/src/main/java/com/contentstack/sdk/Query.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1595,8 +1595,8 @@ protected void execQuery(SingleQueryResultCallback callBack, QueryResultsCallBac
15951595
mainJSON.put("query", urlQueries);
15961596
mainJSON.put("_method", SDKConstant.RequestMethod.GET.toString());
15971597
String mainStringForMD5 = URL + mainJSON.toString() + headers.toString();
1598-
String md5Value = new SDKUtil().getMD5FromString(mainStringForMD5.trim());
1599-
File cacheFile = new File(SDKConstant.cacheFolderName + File.separator + md5Value);
1598+
String shaValue = new SDKUtil().getSHAFromString(mainStringForMD5.trim());
1599+
File cacheFile = new File(SDKConstant.cacheFolderName + File.separator + shaValue);
16001600
CachePolicy cachePolicy = CachePolicy.NETWORK_ONLY;//contentTypeInstance.stackInstance.globalCachePolicyForCall;
16011601
if (cachePolicyForCall != null) {
16021602
cachePolicy = cachePolicyForCall;

0 commit comments

Comments
 (0)