From bc0d43843f65f309dd58693d2633952d348709e3 Mon Sep 17 00:00:00 2001 From: Tuan Nguyen Date: Fri, 28 Mar 2025 16:32:15 +0700 Subject: [PATCH 1/2] Add some basic unit tests for ResponseExt --- data-core/src/test/java/android/util/Log.kt | 9 +++ .../java/com/tymex/github/LinkHeaderTest.kt | 39 +++++++++++++ .../com/tymex/github/NetworkResponseTest.kt | 56 +++++++++++++++++++ 3 files changed, 104 insertions(+) create mode 100644 data-core/src/test/java/android/util/Log.kt create mode 100644 data-core/src/test/java/com/tymex/github/LinkHeaderTest.kt create mode 100644 data-core/src/test/java/com/tymex/github/NetworkResponseTest.kt diff --git a/data-core/src/test/java/android/util/Log.kt b/data-core/src/test/java/android/util/Log.kt new file mode 100644 index 0000000..5ccb662 --- /dev/null +++ b/data-core/src/test/java/android/util/Log.kt @@ -0,0 +1,9 @@ +package android.util + +object Log { + @JvmStatic fun d(tag: String, msg: String) = 0 + @JvmStatic fun e(tag: String, msg: String) = 0 + @JvmStatic fun i(tag: String, msg: String) = 0 + @JvmStatic fun v(tag: String, msg: String) = 0 + @JvmStatic fun w(tag: String, msg: String) = 0 +} \ No newline at end of file diff --git a/data-core/src/test/java/com/tymex/github/LinkHeaderTest.kt b/data-core/src/test/java/com/tymex/github/LinkHeaderTest.kt new file mode 100644 index 0000000..90dd451 --- /dev/null +++ b/data-core/src/test/java/com/tymex/github/LinkHeaderTest.kt @@ -0,0 +1,39 @@ +package com.tymex.github.data.core + +import com.tymex.github.data.core.data.ext.isLastPage +import org.hamcrest.CoreMatchers.`is` +import org.hamcrest.MatcherAssert.assertThat +import org.junit.Test + +class LinkHeaderTest { + + @Test + fun `when link header contains rel next, should return false`() { + val linkHeader = "; rel=\"next\"" + assertThat(linkHeader.isLastPage(), `is`(false)) + } + + @Test + fun `when link header does not contain rel next, should return true`() { + val linkHeader = "; rel=\"prev\"" + assertThat(linkHeader.isLastPage(), `is`(true)) + } + + @Test + fun `when link header is empty, should return true`() { + val linkHeader = "" + assertThat(linkHeader.isLastPage(), `is`(true)) + } + + @Test + fun `when link header has unrelated text, should return true`() { + val linkHeader = "Some random header text" + assertThat(linkHeader.isLastPage(), `is`(true)) + } + + @Test + fun `when link header contains both rel next and rel prev, should return false`() { + val linkHeader = "; rel=\"next\", ; rel=\"prev\"" + assertThat(linkHeader.isLastPage(), `is`(false)) + } +} diff --git a/data-core/src/test/java/com/tymex/github/NetworkResponseTest.kt b/data-core/src/test/java/com/tymex/github/NetworkResponseTest.kt new file mode 100644 index 0000000..22a9a13 --- /dev/null +++ b/data-core/src/test/java/com/tymex/github/NetworkResponseTest.kt @@ -0,0 +1,56 @@ +package com.tymex.github.data.core + +import com.tymex.github.data.core.data.ext.toNetworkResponse +import com.tymex.github.data.core.data.model.NetworkResponse +import junit.framework.TestCase.assertTrue +import okhttp3.MediaType.Companion.toMediaType +import okhttp3.ResponseBody +import org.hamcrest.CoreMatchers.`is` +import org.hamcrest.MatcherAssert.assertThat +import org.junit.Test +import org.mockito.Mockito +import retrofit2.Response + +class NetworkResponseTest { + + @Test + fun `when response is successful and body is present, should return NetworkResponse Success`() { + val mockResponse = Response.success("Hello World") + + val result = mockResponse.toNetworkResponse() + + assertTrue(result is NetworkResponse.Success) + assertThat((result as NetworkResponse.Success).data, `is`("Hello World")) + } + + @Test + fun `when response is successful but body is null, should return NetworkResponse Error`() { + val mockResponse: Response = Response.success(null) + + val result = mockResponse.toNetworkResponse() + + assertTrue(result is NetworkResponse.Error) + assertThat((result as NetworkResponse.Error).message, `is`("Response body is empty")) + } + + @Test + fun `when response is unsuccessful with error body, should return NetworkResponse Error`() { + val errorBody = ResponseBody.create("application/json".toMediaType(), "Not Found") + val mockResponse: Response = Response.error(404, errorBody) + + val result = mockResponse.toNetworkResponse() + + assertTrue(result is NetworkResponse.Error) + assertThat((result as NetworkResponse.Error).message, `is`("Not Found")) + } + + @Test + fun `when response is unsuccessful with null error body, should return NetworkResponse Error with Unknown`() { + val mockResponse: Response = Response.error(500, Mockito.mock(ResponseBody::class.java)) + + val result = mockResponse.toNetworkResponse() + + assertTrue(result is NetworkResponse.Error) + assertThat((result as NetworkResponse.Error).message, `is`("Unknown")) + } +} From feb41da5b385f273d3706d5b6081ae6b4fc94044 Mon Sep 17 00:00:00 2001 From: Tuan Nguyen Date: Fri, 28 Mar 2025 16:45:17 +0700 Subject: [PATCH 2/2] Add github action script to trigger build/unit test upon PR/push onto main branch --- .github/workflows/gradle-build.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/gradle-build.yml diff --git a/.github/workflows/gradle-build.yml b/.github/workflows/gradle-build.yml new file mode 100644 index 0000000..cfebfce --- /dev/null +++ b/.github/workflows/gradle-build.yml @@ -0,0 +1,30 @@ +name: Gradle Build + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + build: + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + java: [17, 21] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: ${{ matrix.java }} + - uses: gradle/gradle-build-action@v3 + + - name: Grant execute permission to Gradle wrapper + run: chmod +x ./gradlew + + - run: ./gradlew clean build + + - name: Run unit tests + run: ./gradlew test