Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
5ea5b09
Merge pull request #96 from contentstack/master
reeshika-h Nov 4, 2025
841f0ef
add comprehensive tests for Asset, AssetLibrary, AssetModel, and Asse…
harshithad0703 Nov 12, 2025
7a84e21
Add comprehensive unit tests for CachePolicy, Config, and Contentstac…
harshithad0703 Nov 12, 2025
ded7ed0
Add unit tests for ContentType and ContentTypesModel classes to ensur…
harshithad0703 Nov 12, 2025
92f307c
Add comprehensive unit tests for CSBackgroundTask, CSConnectionReques…
harshithad0703 Nov 12, 2025
d306b60
Add comprehensive unit tests for Entry, EntryModel, and related class…
harshithad0703 Nov 12, 2025
c6bb623
Add comprehensive unit tests for AssetModel and related Asset functio…
harshithad0703 Nov 12, 2025
a7e3724
Add comprehensive unit tests for AssetLibrary and AssetModel, focusin…
harshithad0703 Nov 12, 2025
7ccf697
Add comprehensive unit tests for Error, ErrorMessages, and exception …
harshithad0703 Nov 12, 2025
7ab90b7
Add comprehensive unit tests for DefaultOption class, covering render…
harshithad0703 Nov 12, 2025
cd0b986
Add comprehensive unit tests for Entry class, covering configuration,…
harshithad0703 Nov 12, 2025
9bc2028
Add comprehensive unit tests for AssetLibrary private methods, utiliz…
harshithad0703 Nov 14, 2025
6cf84a1
Add comprehensive unit tests for CachePolicy, Config, ContentType, Gl…
harshithad0703 Nov 14, 2025
b3ec3c1
Add comprehensive unit tests for Group, InvalidInputException, Langua…
harshithad0703 Nov 14, 2025
790e46f
Add comprehensive unit tests for Metadata, NodeToHTML, Query, QueryAd…
harshithad0703 Nov 14, 2025
48d72be
Add comprehensive unit tests for Query, QueryResult, and Query privat…
harshithad0703 Nov 14, 2025
d35aec6
Add comprehensive unit tests for SDKUtil, SDKController, ResponseType…
harshithad0703 Nov 14, 2025
95ee546
Add comprehensive unit tests for Stack, Taxonomy, and Sync operations…
harshithad0703 Nov 14, 2025
cd32c53
Add unit tests for SDKController, verifying constructor initializatio…
harshithad0703 Nov 18, 2025
451d495
Remove unit tests for SDKController, streamlining the test suite by e…
harshithad0703 Nov 18, 2025
252d926
Add unit tests for ContentstackResultCallback, verifying onCompletion…
harshithad0703 Nov 18, 2025
fd7e749
Add unit tests for ContentstackResultCallback and SDKController, veri…
harshithad0703 Nov 18, 2025
105cd5c
Refactor test classes for consistency and add unit tests for JSONUTF8…
harshithad0703 Nov 18, 2025
1a93f96
Add unit tests for SingleQueryResultCallback, verifying onCompletion …
harshithad0703 Nov 18, 2025
b5af4f2
Add unit tests for TestQueryResultsCallBack, verifying onCompletion a…
harshithad0703 Nov 18, 2025
9cbdcf8
Add unit tests for ClearCache, verifying deletion of old cache files …
harshithad0703 Nov 18, 2025
e5276cb
Add unit tests for GlobalFieldsResultCallback, verifying onCompletion…
harshithad0703 Nov 18, 2025
9f36977
Add unit tests for CSConnectionRequest, enhancing coverage for onRequ…
harshithad0703 Nov 18, 2025
8ef3f73
Add unit tests for ConnectionStatus, covering various scenarios inclu…
harshithad0703 Nov 18, 2025
73fd4aa
Update JaCoCo version to 0.8.12 and configure Java 17 compatibility; …
harshithad0703 Nov 19, 2025
df2c981
Add unit tests for TestCallbackScenarios, covering various callback s…
harshithad0703 Nov 19, 2025
e0f9123
Enable core library desugaring in build.gradle and remove redundant e…
harshithad0703 Nov 19, 2025
93dfea2
Add unit tests for SyncStack, verifying JSON handling with various sc…
harshithad0703 Nov 19, 2025
1b50617
Add unit tests for TestContentType, enhancing coverage with various s…
harshithad0703 Nov 19, 2025
49cb17b
Add unit tests for TestSDKUtil, enhancing coverage with new scenarios…
harshithad0703 Nov 19, 2025
43d90be
Add unit tests for EntryResultCallBack, verifying onRequestFinish and…
harshithad0703 Nov 19, 2025
adf4df4
Add unit tests for CSHttpConnection error handling, verifying the gen…
harshithad0703 Nov 20, 2025
d445ff3
Add assertions in TestCSHttpConnectionErrorHandling to verify non-nul…
harshithad0703 Nov 20, 2025
d98ba5d
Remove redundant Jacoco coverage verification rules from build.gradle…
harshithad0703 Nov 20, 2025
d469052
Add CSConnectionRequest.class to JaCoCo coverage exclusions in build.…
harshithad0703 Nov 20, 2025
bcce349
Add unit tests for ContentTypesCallback and FetchResultCallback, veri…
harshithad0703 Nov 20, 2025
6413c67
Add unit tests for TestStackSyncCallbacks, verifying the behavior of …
harshithad0703 Nov 20, 2025
01be290
Update TestStackSyncCallbacks.java to include an additional blank lin…
harshithad0703 Nov 20, 2025
495fe9b
Refactor TestTaxonomy to implement a FakeAPIService and enhance query…
harshithad0703 Nov 20, 2025
fc9d65e
Refactor TestEntry to simplify unit tests by removing dependencies on…
harshithad0703 Nov 20, 2025
abdf0ce
Remove multiple test classes to streamline the test suite, including …
harshithad0703 Nov 20, 2025
7861c1e
Update JaCoCo coverage exclusions in build.gradle to include SyncResu…
harshithad0703 Nov 21, 2025
608073d
Merge pull request #97 from contentstack/fix/dx-3678-improve-tests
harshithad0703 Nov 21, 2025
d79ec8f
Add setLocale method to Asset class and corresponding test case
harshithad0703 Feb 24, 2026
1fa200a
Refactor TestContentType to simplify test methods
harshithad0703 Feb 24, 2026
215833f
Update CHANGELOG for version 4.2.0, adding asset localisation support…
harshithad0703 Feb 24, 2026
4e63754
update license
harshithad0703 Feb 24, 2026
2018270
Merge pull request #98 from contentstack/feat/dx-4450-add-asset-local…
harshithad0703 Feb 25, 2026
0888d28
Merge pull request #99 from contentstack/development
harshithad0703 Feb 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# CHANGELOG

## Version 4.2.0

### Date: 02-Mar-2026

- Added asset localisation support

## Version 4.1.0

### Date: 15-Sept-2025
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2012 - 2025 Contentstack
Copyright (c) 2012 - 2026 Contentstack

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
buildscript {
ext {
jacoco_version = '0.8.8'
jacoco_version = '0.8.12'
agp_version = '8.2.1'
}
repositories {
Expand Down
220 changes: 201 additions & 19 deletions contentstack/build.gradle
Original file line number Diff line number Diff line change
@@ -1,17 +1,27 @@
plugins {
id "com.android.library"
id "com.vanniktech.maven.publish" version "0.33.0"
id 'jacoco'
}

ext {
PUBLISH_GROUP_ID = 'com.contentstack.sdk'
PUBLISH_ARTIFACT_ID = 'android'
PUBLISH_VERSION = '4.1.0'
PUBLISH_VERSION = '4.2.0'
}

android {
namespace "com.contentstack.sdk"
compileSdk 34 // Using latest stable Android SDK version

// SDK compiles to Java 17 for JaCoCo compatibility
// But can be built with Java 21 - tests use Java 17 toolchain
compileOptions {
coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}

buildFeatures {
buildConfig true
}
Expand All @@ -30,10 +40,15 @@ android {
}

testOptions {
unitTests.all {
// jacoco {
// includeNoLocationClasses = true
// }
unitTests {
includeAndroidResources = true
returnDefaultValues = true
all {
jacoco {
includeNoLocationClasses = true
excludes = ['jdk.internal.*']
}
}
}
}
// signing {
Expand Down Expand Up @@ -109,18 +124,37 @@ dependencies {
def multidex = "2.0.1"
def volley = "1.2.1"
def junit = "4.13.2"
def mockito = "5.2.0"
def mockitoKotlin = "2.2.0"
configurations.configureEach { resolutionStrategy.force 'com.android.support:support-annotations:23.1.0' }
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "com.android.volley:volley:$volley"
implementation "junit:junit:$junit"

// For AGP 7.4+
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.4'

// Unit Testing Dependencies
testImplementation 'junit:junit:4.13.2'
testImplementation "org.mockito:mockito-core:$mockito"
testImplementation "org.mockito:mockito-inline:$mockito"
testImplementation 'org.mockito:mockito-android:5.2.0'
testImplementation 'org.robolectric:robolectric:4.15' // Updated to fix security vulnerabilities
testImplementation 'androidx.test:core:1.5.0'
testImplementation 'androidx.test:runner:1.5.2'
testImplementation 'androidx.test.ext:junit:1.1.5'
testImplementation 'com.squareup.okhttp3:mockwebserver:4.12.0'
testImplementation 'org.json:json:20231013'
// PowerMock for advanced mocking
testImplementation 'org.powermock:powermock-module-junit4:2.0.9'
testImplementation 'org.powermock:powermock-api-mockito2:2.0.9'
testImplementation 'org.powermock:powermock-core:2.0.9'

// Android Test Dependencies
androidTestImplementation 'androidx.test:core:1.5.0'
testImplementation 'org.robolectric:robolectric:4.6.1'

androidTestImplementation('androidx.test.espresso:espresso-core:3.1.0', {
androidTestImplementation 'androidx.test:runner:1.5.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation('androidx.test.espresso:espresso-core:3.5.1', {
exclude group: 'com.android.support', module: 'support-annotations'
})

Expand Down Expand Up @@ -200,22 +234,170 @@ mavenPublishing {
}
}

jacoco {
toolVersion = "0.8.12"
}

tasks.register('jacocoTestReport', JacocoReport) {
dependsOn('testDebugUnitTest', 'createDebugCoverageReport')
dependsOn('testDebugUnitTest')

reports {
xml.required = true
html.required = true
csv.required = false

xml.outputLocation = file("${buildDir}/reports/jacoco/jacocoTestReport/jacocoTestReport.xml")
html.outputLocation = file("${buildDir}/reports/jacoco/jacocoTestReport/html")
}

def excludePatterns = [
'**/R.class',
'**/R$*.class',
'**/BuildConfig.*',
'**/Manifest*.*',
'**/*Test*.*',
'android/**/*.*',
'**/*$ViewInjector*.*',
'**/*$ViewBinder*.*',
'**/Lambda$*.class',
'**/Lambda.class',
'**/*Lambda.class',
'**/*Lambda*.class',
'**/*_MembersInjector.class',
'**/Dagger*Component*.*',
'**/*Module_*Factory.class',
'**/AutoValue_*.*',
'**/*JavascriptBridge.class',
'**/package-info.class',
'**/TestActivity.class',
// External library exclusions
'**/okhttp/**',
'**/okio/**',
'**/txtmark/**',
'**/retrofit2/**',
'**/volley/**',
'**/CSConnectionRequest.class',
// Exclude callback interfaces and their anonymous implementations
'**/SyncResultCallBack.class',
'**/Stack$*.class'
]

sourceDirectories.setFrom(files([
"${project.projectDir}/src/main/java"
]))

classDirectories.setFrom(files([
fileTree(dir: "${buildDir}/intermediates/javac/debug", excludes: excludePatterns),
fileTree(dir: "${buildDir}/tmp/kotlin-classes/debug", excludes: excludePatterns)
]))

executionData.setFrom(fileTree(buildDir).include([
"outputs/unit_test_code_coverage/debugUnitTest/testDebugUnitTest.exec",
"jacoco/testDebugUnitTest.exec"
]))
}

// Configure jacocoTestReport after evaluation when classDirectories is available
project.afterEvaluate {
tasks.named('jacocoTestReport', JacocoReport) {
classDirectories.setFrom(files(classDirectories.files.collect {
fileTree(dir: it, exclude: [
'**com/contentstack/okhttp**',
'**com/contentstack/okio**',
'**com/contentstack/txtmark**'
])
}))
// Combined coverage report for both unit and instrumentation tests
tasks.register('jacocoCombinedReport', JacocoReport) {
// This task can run after both test types complete
// Make it depend on both if they're being run
group = "Reporting"
description = "Generate Jacoco coverage reports for both unit and instrumentation tests"

reports {
xml.required = true
html.required = true
csv.required = false

xml.outputLocation = file("${buildDir}/reports/jacoco/jacocoCombinedReport/jacocoCombinedReport.xml")
html.outputLocation = file("${buildDir}/reports/jacoco/jacocoCombinedReport/html")
}

def excludePatterns = [
'**/R.class',
'**/R$*.class',
'**/BuildConfig.*',
'**/Manifest*.*',
'**/*Test*.*',
'android/**/*.*',
'**/*$ViewInjector*.*',
'**/*$ViewBinder*.*',
'**/Lambda$*.class',
'**/Lambda.class',
'**/*Lambda.class',
'**/*Lambda*.class',
'**/*_MembersInjector.class',
'**/Dagger*Component*.*',
'**/*Module_*Factory.class',
'**/AutoValue_*.*',
'**/*JavascriptBridge.class',
'**/package-info.class',
'**/TestActivity.class',
// External library exclusions
'**/okhttp/**',
'**/okio/**',
'**/txtmark/**',
'**/retrofit2/**',
'**/volley/**',
'**/CSConnectionRequest.class',
// Exclude callback interfaces and their anonymous implementations
'**/SyncResultCallBack.class',
'**/Stack$*.class'
]

sourceDirectories.setFrom(files([
"${project.projectDir}/src/main/java"
]))

classDirectories.setFrom(files([
fileTree(dir: "${buildDir}/intermediates/javac/debug", excludes: excludePatterns),
fileTree(dir: "${buildDir}/tmp/kotlin-classes/debug", excludes: excludePatterns)
]))

// Collect execution data from both unit tests and instrumentation tests
executionData.setFrom(fileTree(buildDir).include([
// Unit test coverage
"outputs/unit_test_code_coverage/debugUnitTest/testDebugUnitTest.exec",
"jacoco/testDebugUnitTest.exec",
// Instrumentation test coverage
"outputs/code_coverage/debugAndroidTest/connected/**/*.ec"
]))
}

tasks.register('jacocoTestCoverageVerification', JacocoCoverageVerification) {
dependsOn('testDebugUnitTest')

def excludePatterns = [
'**/R.class',
'**/R$*.class',
'**/BuildConfig.*',
'**/Manifest*.*',
'**/*Test*.*',
'android/**/*.*',
'**/package-info.class',
'**/TestActivity.class',
'**/CSConnectionRequest.class',
// Exclude callback interfaces and their anonymous implementations
'**/SyncResultCallBack.class',
'**/Stack$*.class'
]

sourceDirectories.setFrom(files([
"${project.projectDir}/src/main/java"
]))

classDirectories.setFrom(files([
fileTree(dir: "${buildDir}/intermediates/javac/debug", excludes: excludePatterns),
fileTree(dir: "${buildDir}/tmp/kotlin-classes/debug", excludes: excludePatterns)
]))

executionData.setFrom(fileTree(buildDir).include([
"outputs/unit_test_code_coverage/debugUnitTest/testDebugUnitTest.exec",
"jacoco/testDebugUnitTest.exec"
]))
}

// Make check task depend on coverage verification
tasks.named('check') {
dependsOn('jacocoTestReport', 'jacocoTestCoverageVerification')
}
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,22 @@ public void onCompletion(ResponseType responseType, Error error) {
latch.await(5, TimeUnit.SECONDS);
}

@Test
public void test_setLocale_fetch() throws InterruptedException {
final CountDownLatch latch = new CountDownLatch(1);
final Asset asset = stack.asset(assetUid);
asset.setLocale("en-us");
asset.fetch(new FetchResultCallback() {
@Override
public void onCompletion(ResponseType responseType, Error error) {
assertNotNull(asset.getAssetUid());
latch.countDown();
}
});
latch.await(5, TimeUnit.SECONDS);
assertEquals("Query was not completed in time", 0, latch.getCount());
}

@Test
public void test_include_branch() {
final Asset asset = stack.asset(assetUid);
Expand Down
18 changes: 18 additions & 0 deletions contentstack/src/main/java/com/contentstack/sdk/Asset.java
Original file line number Diff line number Diff line change
Expand Up @@ -616,4 +616,22 @@ public Asset includeBranch() {
return this;
}

/**
* <p>
* <br><br><b>Example :</b><br>
* <pre class="prettyprint">
* Asset asset = asset.setLocale("en-hi");
* </pre>
* </p>
*/
public Asset setLocale(String locale) {
if (locale != null) {
try {
urlQueries.put("locale", locale);
} catch (JSONException e) {
Log.e(TAG, e.getLocalizedMessage());
}
}
return this;
}
}

This file was deleted.

This file was deleted.

Loading
Loading