Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
705d3f8
feat: Separate unit/API tests and enhance integration test coverage
harshithad0703 Nov 3, 2025
0ce9568
refactor: Update pom.xml
harshithad0703 Nov 4, 2025
73b35da
update pom.xml
harshithad0703 Nov 4, 2025
b8796d7
Add comprehensive unit tests for Asset class
harshithad0703 Nov 6, 2025
d2fc99b
Add comprehensive unit tests for AssetLibrary
harshithad0703 Nov 6, 2025
eb6484b
Add comprehensive unit tests for AssetModel and AssetsModel classes
harshithad0703 Nov 6, 2025
bd79c49
Add comprehensive unit tests for Config and Contentstack classes
harshithad0703 Nov 6, 2025
0f43c93
Add comprehensive unit tests for ContentType class
harshithad0703 Nov 6, 2025
b82f8ff
Add unit tests for AssetModel constructor with isArray=false and tags…
harshithad0703 Nov 6, 2025
aa4b7c2
Add comprehensive unit tests for ContentTypesCallback class
harshithad0703 Nov 6, 2025
9d43c94
Add comprehensive unit tests for ContentTypesModel class
harshithad0703 Nov 6, 2025
d693805
Add comprehensive unit tests for CSBackgroundTask constructors with v…
harshithad0703 Nov 6, 2025
9e7dda5
Add comprehensive unit tests for CSConnectionPool and CSConnectionReq…
harshithad0703 Nov 6, 2025
c129863
Add comprehensive unit tests for CSHttpConnection class
harshithad0703 Nov 6, 2025
c06d44a
Add comprehensive unit tests for EntriesModel class
harshithad0703 Nov 6, 2025
e4b9466
Add comprehensive unit tests for Entry class
harshithad0703 Nov 6, 2025
64db395
Add comprehensive unit tests for EntryModel class
harshithad0703 Nov 6, 2025
910fde8
Add comprehensive unit tests for ErrorMessages and GlobalField classes
harshithad0703 Nov 6, 2025
9a2ff2b
Add comprehensive unit tests for GlobalFieldsModel class
harshithad0703 Nov 6, 2025
62e1db4
Add comprehensive unit tests for Group class
harshithad0703 Nov 6, 2025
d51c425
Add comprehensive unit tests for Query class
harshithad0703 Nov 6, 2025
2bc632e
Add comprehensive unit tests for Query class, enhancing coverage with…
harshithad0703 Nov 6, 2025
bae11ed
Add comprehensive unit tests for Stack class, covering initialization…
harshithad0703 Nov 6, 2025
f9549b9
Add comprehensive unit tests for live preview query functionality in …
harshithad0703 Nov 6, 2025
c4a13a4
Add comprehensive unit tests for SyncStack class, covering all getter…
harshithad0703 Nov 6, 2025
24692a1
Add comprehensive unit tests for Taxonomy class, covering all query b…
harshithad0703 Nov 6, 2025
1736c3b
Add comprehensive integration tests for ContentstackPlugin, validatin…
harshithad0703 Nov 6, 2025
1895139
Remove obsolete unit tests for live preview query and find method in …
harshithad0703 Nov 6, 2025
336b07f
Add integration tests for ContentstackPlugin, implementing two sample…
harshithad0703 Nov 7, 2025
10f9fef
Add additional unit tests for CSHttpConnection, covering form paramet…
harshithad0703 Nov 7, 2025
240c71f
Add comprehensive unit tests for ContentType, GlobalFieldsModel, Quer…
harshithad0703 Nov 7, 2025
12bfaa6
Refactor SanityReport class: move to test directory and update report…
harshithad0703 Nov 7, 2025
c816697
Add comprehensive unit tests for Query class, specifically for the gr…
harshithad0703 Nov 7, 2025
d128d84
Add scripts for checking JaCoCo coverage thresholds and configure Git…
harshithad0703 Nov 7, 2025
306f031
Enhance GitHub Actions workflow for unit testing: add JaCoCo report g…
harshithad0703 Nov 7, 2025
5eb9ca0
Refactor test cases in TestCSBackgroundTask and TestQuery: replace st…
harshithad0703 Nov 7, 2025
be5827b
Update GitHub Actions workflow for unit testing
harshithad0703 Nov 7, 2025
38b24d9
Update GitHub Actions workflow for unit testing: modify JaCoCo report…
harshithad0703 Nov 7, 2025
fb503b7
Remove check-coverage.sh script and update unit testing workflow to s…
harshithad0703 Nov 7, 2025
74b997d
Update unit testing workflow: change JDK version to 9, enhance covera…
harshithad0703 Nov 7, 2025
b5b9c18
Update unit testing workflow to use Zulu distribution for JDK 9 setup
harshithad0703 Nov 7, 2025
e6877af
modify unit testing workflow to set up JDK 8 with Temurin distribution
harshithad0703 Nov 7, 2025
3714a2b
update workflow
harshithad0703 Nov 7, 2025
c6cc34b
Enhance unit testing workflow: enable tests in pom.xml temporarily, i…
harshithad0703 Nov 7, 2025
2e75436
Refactor unit testing workflow: rename job to 'coverage', update JDK …
harshithad0703 Nov 7, 2025
5717c7d
Update unit testing workflow: change JDK setup to version 8 with Temu…
harshithad0703 Nov 7, 2025
4167518
Refactor unit testing workflow
harshithad0703 Nov 7, 2025
ff2a73d
update workflow
harshithad0703 Nov 7, 2025
9bd99fe
update workflow
harshithad0703 Nov 7, 2025
7d9dfca
update workflow
harshithad0703 Nov 7, 2025
cf739f6
update workflow
harshithad0703 Nov 7, 2025
8c767ed
update workflow
harshithad0703 Nov 7, 2025
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
102 changes: 102 additions & 0 deletions .github/workflows/unit-testing.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
name: Java SDK - Coverage Check

on:
pull_request:
branches:
- development
- staging
- master

jobs:
coverage:
runs-on: ubuntu-latest

steps:
- name: 🧾 Checkout repository
uses: actions/checkout@v4

- name: ☕ Set up JDK 8 (Temurin)
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 8
cache: maven

- name: 🧩 Ensure tests are enabled in pom.xml
run: |
echo "🔧 Ensuring tests are enabled in pom.xml..."
sed -i 's/<skipTests>true<\/skipTests>/<skipTests>false<\/skipTests>/g' pom.xml || true

- name: 🧪 Run tests and generate JaCoCo report
run: mvn clean test -Dtest='Test*' jacoco:report -Dgpg.skip=true

- name: 📊 Extract coverage from JaCoCo HTML report
id: extract_coverage
run: |
echo "📊 Extracting coverage summary from JaCoCo HTML report..."

REPORT="target/site/jacoco/index.html"

if [ ! -f "$REPORT" ]; then
echo "❌ JaCoCo HTML report not found!"
exit 1
fi

# Extract the <tfoot> Total row and clean it up
TOTAL_ROW=$(grep -A2 "<td>Total</td>" "$REPORT" | tr -d '\n')

# Extract numeric percentages in order (Instruction first, Branch second)
PERCENTAGES=($(echo "$TOTAL_ROW" | grep -oE '[0-9]+%' | sed 's/%//g'))

INSTRUCTION=${PERCENTAGES[0]:-0}
BRANCH=${PERCENTAGES[1]:-0}

echo "📘 Instruction Coverage: ${INSTRUCTION}%"
echo "🌿 Branch Coverage: ${BRANCH}%"

echo "instruction=${INSTRUCTION}" >> $GITHUB_OUTPUT
echo "branch=${BRANCH}" >> $GITHUB_OUTPUT

- name: 🚦 Enforce coverage threshold
run: |
MIN_INSTRUCTION=90
MIN_BRANCH=80

INSTRUCTION=${{ steps.extract_coverage.outputs.instruction }}
BRANCH=${{ steps.extract_coverage.outputs.branch }}

echo "🧾 Required minimums:"
echo " • Instruction: ${MIN_INSTRUCTION}%"
echo " • Branch: ${MIN_BRANCH}%"
echo ""
echo "📈 Actual coverage:"
echo " • Instruction: ${INSTRUCTION}%"
echo " • Branch: ${BRANCH}%"

if [ "$INSTRUCTION" -lt "$MIN_INSTRUCTION" ]; then
echo "❌ Instruction coverage (${INSTRUCTION}%) is below the threshold (${MIN_INSTRUCTION}%)"
exit 1
fi

if [ "$BRANCH" -lt "$MIN_BRANCH" ]; then
echo "❌ Branch coverage (${BRANCH}%) is below the threshold (${MIN_BRANCH}%)"
exit 1
fi

echo "✅ Coverage thresholds met!"

- name: 💬 Post coverage summary as PR comment
uses: marocchino/sticky-pull-request-comment@v2
with:
header: 🧪 JaCoCo Coverage Report
message: |
**Coverage Summary**
- 📘 Instruction Coverage: `${{ steps.extract_coverage.outputs.instruction }}%`
- 🌿 Branch Coverage: `${{ steps.extract_coverage.outputs.branch }}%`

- name: 📦 Upload JaCoCo HTML report as artifact
uses: actions/upload-artifact@v4
with:
name: jacoco-report
path: target/site/jacoco/
if-no-files-found: warn
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -271,11 +271,16 @@
</executions>
</plugin>

<!-- Surefire Plugin for API Tests -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
<configuration>
<!-- Run only API tests (*IT.java) by default -->
<includes>
<include>**/*IT.java</include>
</includes>
<skipTests>true</skipTests>
</configuration>
</plugin>
Expand Down
2 changes: 1 addition & 1 deletion send-report.sh
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ echo "📄 Generating Surefire HTML report..."
mvn surefire-report:report-only

echo "📤 Sending test report to Slack..."
mvn compile exec:java -Dexec.mainClass="com.contentstack.sdk.SanityReport"
mvn test-compile exec:java -Dexec.mainClass="com.contentstack.sdk.SanityReport" -Dexec.classpathScope=test

# Restore pom.xml and clean up
restore_pom
Expand Down
230 changes: 230 additions & 0 deletions src/test/java/com/contentstack/sdk/AssetIT.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
package com.contentstack.sdk;

import java.util.List;
import java.util.logging.Logger;
import org.json.JSONObject;
import org.junit.jupiter.api.*;


@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
class AssetIT {

private final Logger logger = Logger.getLogger(AssetIT.class.getName());
private String assetUid;
private final Stack stack = Credentials.getStack();

private String envChecker() {
String githubActions = System.getenv("GITHUB_ACTIONS");
if (githubActions != null && githubActions.equals("true")) {
System.out.println("Tests are running in GitHub Actions environment.");
String mySecretKey = System.getenv("API_KEY");
System.out.println("My Secret Key: " + mySecretKey);
return "GitHub";
} else {
System.out.println("Tests are running in a local environment.");
return "local";
}
}

@Test
@Order(1)
void testNewAssetLibrary() {
envChecker();
AssetLibrary assets = stack.assetLibrary();
assets.fetchAll(new FetchAssetsCallback() {
@Override
public void onCompletion(ResponseType responseType, List<Asset> assets, Error error) {
Asset model = assets.get(0);
assetUid = model.getAssetUid();
Assertions.assertTrue(model.getAssetUid().startsWith("blt"));
Assertions.assertNotNull( model.getFileType());
Assertions.assertNotNull( model.getFileSize());
Assertions.assertNotNull( model.getFileName());
Assertions.assertTrue(model.toJSON().has("created_at"));
Assertions.assertTrue(model.getCreatedBy().startsWith("blt"));
Assertions.assertEquals("gregory", model.getUpdateAt().getCalendarType());
Assertions.assertTrue(model.getUpdatedBy().startsWith("blt"));
Assertions.assertEquals("", model.getDeletedBy());
}
});
}

@Test
@Order(2)
void testNewAssetZOnlyForOrderByUid() {
String[] tags = {"black", "white", "red"};
Asset asset = stack.asset(assetUid);
asset.includeFallback().addParam("fake@header", "fake@header").setTags(tags).fetch(new FetchResultCallback() {
@Override
public void onCompletion(ResponseType responseType, Error error) {
Assertions.assertTrue(asset.getAssetUid().startsWith("blt"));
Assertions.assertNotNull( asset.getFileType());
Assertions.assertNotNull( asset.getFileSize());
Assertions.assertNotNull( asset.getFileName());
Assertions.assertTrue(asset.toJSON().has("created_at"));
Assertions.assertTrue(asset.getCreatedBy().startsWith("blt"));
Assertions.assertEquals("gregory", asset.getUpdateAt().getCalendarType());
Assertions.assertTrue(asset.getUpdatedBy().startsWith("blt"));
Assertions.assertNull(asset.getDeleteAt());
Assertions.assertEquals("gregory", asset.getCreateAt().getCalendarType());
Assertions.assertEquals("", asset.getDeletedBy());
}
});
}

@Test
void testAssetDefaultConstructor() {
logger.fine("We are working with fake apis");
Asset asset = new Asset();
Assertions.assertNotNull(asset);
}

@Test
void testAddHeader() {
String headerKey = "fakeKey";
Asset assetInstance = stack.asset();
assetInstance.setHeader(headerKey, "fakeValue");
Assertions.assertTrue(assetInstance.headers.containsKey(headerKey));
}

@Test
void testRemoveHeader() {
String headerKey = "fakeKey";
Asset assetInstance = stack.asset();
assetInstance.removeHeader(headerKey);
Assertions.assertFalse(assetInstance.headers.containsKey(headerKey));
}

@Test
void testSetAssetUid() {
String headerKey = "asset@fakeuid";
Asset assetInstance = stack.asset();
assetInstance.setUid(headerKey);
Assertions.assertEquals(headerKey, assetInstance.assetUid);
}

@Test
void testSetAssetTagsLength() {
String[] tags = {"gif", "img", "landscape", "portrait"};
Asset assetInstance = stack.asset();
assetInstance.setTags(tags);
Assertions.assertEquals(tags.length, assetInstance.tagsArray.length);
}

@Test
void testGetAssetTags() {
String[] tags = {"gif", "img", "landscape", "portrait"};
Asset assetInstance = stack.asset();
assetInstance.setTags(tags);
Assertions.assertEquals(tags.length, assetInstance.getTags().length);
}

@Test
void testAssetIncludeDimension() {
Asset assetInstance = stack.asset();
assetInstance.includeDimension();
Assertions.assertTrue(assetInstance.urlQueries.has("include_dimension"));
}

@Test
void testAssetIncludeFallback() {
Asset assetInstance = stack.asset();
assetInstance.includeFallback();
Assertions.assertTrue(assetInstance.urlQueries.has("include_fallback"));
}

@Test
void testAssetAddParam() {
Asset assetInstance = stack.asset();
assetInstance.addParam("fake@Param", "fake@Param");
Assertions.assertTrue(assetInstance.urlQueries.has("fake@Param"));
}

@Test
void testNewAssetInstance() {
String fakeAssetUid = "fakeAssetUid";
Asset assetInstance = stack.asset(fakeAssetUid);
Assertions.assertEquals(fakeAssetUid, assetInstance.assetUid);
}

@Test
void assetConfigure() {
Asset assetInstance = stack.asset("assetuid@fake");
Assertions.assertEquals("assetuid@fake", assetInstance.assetUid);
}

JSONObject rawJson() {
JSONObject jsonObject = new JSONObject();
jsonObject.put("uid", "something@fake");
jsonObject.put("created_at", "2016-04-06T11:06:10.601Z");
jsonObject.put("updated_at", "2016-12-16T12:36:33.961Z");
jsonObject.put("created_by", "something@fake");
jsonObject.put("content_type", "image/jpeg");
jsonObject.put("file_size", "482141");
JSONObject jsonAsset = new JSONObject();
jsonAsset.put("asset", jsonObject);
return jsonAsset;
}

@Test
void testNewAssetConfigure() {
JSONObject assetObject = rawJson();
Asset asset = stack.asset("fake@uid");
asset.configure(assetObject);
Assertions.assertTrue(asset.json.has("asset"));
}

@Test
void testAssetIncludeBranch() {
Asset asset = stack.asset("fake@uid");
asset.includeBranch();
Assertions.assertTrue(asset.urlQueries.has("include_branch"));
}

@Test
void testAssetIncludeOwner() {
Asset asset = stack.asset("fake@uid");
asset.includeMetadata();
Assertions.assertTrue(asset.urlQueries.has("include_metadata"));
}

// @Test
// void testAssetAsPOJO() {
// Asset asset = stack.asset(assetUid);
// asset.fetch(new FetchResultCallback() {
// @Override
// public void onCompletion(ResponseType responseType, Error error) {
// if (error == null) {
// Assertions.assertNotNull(asset.getAssetUid());
// Assertions.assertNotNull(asset.getFileType());
// Assertions.assertNotNull(asset.getFileSize());
// Assertions.assertNotNull(asset.getFileName());
// Assertions.assertNotNull(asset.getUrl());
// Assertions.assertNotNull(asset.getTags());
// Assertions.assertNotNull(asset.toJSON());
// }
// }
// });
// }

// @Test
// void testAssetTypeSafety() {
// Asset asset = stack.asset(assetUid);
// asset.fetch(new FetchResultCallback() {
// @Override
// public void onCompletion(ResponseType responseType, Error error) {
// if (error == null) {
// Assertions.assertNotNull(asset.getAssetUid());
// Assertions.assertNotNull(asset.getFileType());
// Assertions.assertNotNull(asset.getFileSize());
// Assertions.assertNotNull(asset.getFileName());
// Assertions.assertNotNull(asset.getUrl());
// Assertions.assertNotNull(asset.getTags());

// }
// }
// });
// }

}
Loading
Loading