Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 8 additions & 4 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ android {
resourceConfigurations += listOf("ar", "be", "bg", "bn", "bn-rIN", "bs", "cs", "da", "de", "el-rGR", "en", "eo", "es", "es-rAR", "et", "fi", "fr", "gl", "he-rIL", "hi", "hr", "hu", "in-rID", "is", "it", "ja", "ko", "lt", "lv", "nb-rNO", "nl", "oc", "pl", "pt", "pt-rBR", "pt-rPT", "ro-rRO", "ru", "sk", "sl", "sr", "sv", "ta", "tr", "uk", "vi", "zh-rCN", "zh-rTW")

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"

buildConfigField("boolean", "showDonate", "true")
buildConfigField("boolean", "showRateOnGooglePlay", "false")
Comment on lines -30 to -32
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As explained, this change is wrong.

}

buildTypes {
Expand Down Expand Up @@ -130,6 +127,7 @@ dependencies {
implementation("androidx.compose.foundation:foundation")
implementation("androidx.compose.material3:material3")
implementation("androidx.compose.ui:ui-tooling-preview-android")
debugImplementation("androidx.compose.ui:ui-tooling:1.9.2")

// Third-party
implementation("com.journeyapps:zxing-android-embedded:4.3.0@aar")
Expand All @@ -148,10 +146,16 @@ dependencies {

androidTestImplementation("androidx.test:core:$androidXTestVersion")
androidTestImplementation("junit:junit:$junitVersion")
androidTestImplementation("androidx.test.ext:junit:1.2.1")
// androidTestImplementation("androidx.test.ext:junit:1.3.0")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why commented out code?

androidTestImplementation("androidx.test:runner:$androidXTestVersion")
androidTestImplementation("androidx.test.uiautomator:uiautomator:2.3.0")
implementation("androidx.test.espresso:espresso-intents:3.7.0")
androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")

// Test rules and transitive dependencies:
implementation("androidx.compose.ui:ui-test-junit4:1.9.2")
// Needed for createComposeRule(), but not for createAndroidComposeRule<YourActivity>():
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Needed for createComposeRule(), but not for createAndroidComposeRule<YourActivity>():
// Needed for createComposeRule(), but not for createAndroidComposeRule<YourActivity>():

debugImplementation("androidx.compose.ui:ui-test-manifest:1.9.2")
}

tasks.register("copyRawResFiles", Copy::class) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
package protect.card_locker

import android.content.Context
import android.content.Intent
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.assertIsNotDisplayed
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.test.performClick
import androidx.test.core.app.ApplicationProvider
import androidx.test.espresso.intent.Intents
import androidx.test.espresso.intent.Intents.intended
import androidx.test.espresso.intent.matcher.IntentMatchers.hasAction
import androidx.test.espresso.intent.matcher.IntentMatchers.hasData
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.hamcrest.Matchers.allOf
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class AboutActivityIntegrationTest {
private lateinit var context: Context
@get:Rule
val composableTestRule = createAndroidComposeRule<AboutActivity>()

@Before
fun setup() {
context = ApplicationProvider.getApplicationContext()
}

@Test
fun testActivityCreation() {
val title = context.getString(R.string.about_title_fmt, context.getString(R.string.app_name))

// Ensure the UI is ready before checking the nodes
composableTestRule.waitForIdle()

with(composableTestRule) {
// Check title exists
onNodeWithText(title).assertExists()

// Check key elements are initialized
onNodeWithText(context.getString(R.string.credits)).assertExists()
onNodeWithText(context.getString(R.string.version_history)).assertExists()
onNodeWithText(context.getString(R.string.help_translate_this_app)).assertExists()
onNodeWithText(context.getString(R.string.license)).assertExists()
onNodeWithText(context.getString(R.string.source_repository)).assertExists()
onNodeWithText(context.getString(R.string.privacy_policy)).assertExists()
onNodeWithText(context.getString(R.string.report_error)).assertExists()
}
}


@Test
fun testDialogContentMethods() {
// Use reflection to test private methods
with(composableTestRule) {
onNodeWithTag(context.getString(R.string.license))
.performClick()

onNodeWithText(context.getString(R.string.ok))
.assertIsDisplayed()
.performClick()

onNodeWithText(context.getString(R.string.ok))
.assertIsNotDisplayed()
}
Comment on lines +59 to +70
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this reflection? Are these private methods?

}

@Test
fun testClickListeners() {
// need to catch the Intent. This requires Espresso-Intents
Intents.init()

with(composableTestRule) {
onNodeWithTag(context.getString(R.string.source_repository))
.performClick()

waitForIdle()
}

intended(
allOf(
hasAction(Intent.ACTION_VIEW),
hasData(AppURLs.REPOSITORY_SOURCE)
)
)

Intents.release()
}

@Test
fun testOpenBrowserOnVersionHistoryUrl() {
Intents.init()

with(composableTestRule) {
onNodeWithTag(context.getString(R.string.version_history))
.performClick()

onNodeWithText(context.getString(R.string.view_online))
.assertIsDisplayed()
.performClick()

waitForIdle()
}

intended(
allOf(
hasAction(Intent.ACTION_VIEW),
hasData(AppURLs.VERSION_HISTORY)
)
)

Intents.release()
}

@Test
fun testOpenBrowserWhenClickOnHelpTranslateThisApp() {
Intents.init()

with(composableTestRule) {
onNodeWithTag(context.getString(R.string.help_translate_this_app))
.performClick()

waitForIdle()
}

intended(
allOf(
hasAction(Intent.ACTION_VIEW),
hasData(AppURLs.HELP_TRANSLATE_APP)
)
)

Intents.release()
}

@Test
fun testOpenBrowserWhenClickOnLicense() {
Intents.init()

with(composableTestRule) {
onNodeWithTag(context.getString(R.string.license))
.performClick()

onNodeWithText(context.getString(R.string.view_online))
.assertIsDisplayed()
.performClick()
}

intended(
allOf(
hasAction(Intent.ACTION_VIEW),
hasData(AppURLs.LICENSE)
)
)

Intents.release()
}

@Test
fun testOpenBrowserWhenClickOnSourceRepository() {
Intents.init()

composableTestRule
.onNodeWithTag(context.getString(R.string.source_repository))
.performClick()

intended(
allOf(
hasAction(Intent.ACTION_VIEW),
hasData(AppURLs.REPOSITORY_SOURCE)
)
)

Intents.release()
}

@Test
fun testOpenBrowserWhenClickOnPrivacyPolicy() {
Intents.init()

with(composableTestRule) {
onNodeWithTag(context.getString(R.string.privacy_policy))
.performClick()

onNodeWithText(context.getString(R.string.view_online))
.assertIsDisplayed()
.performClick()
}

intended(
allOf(
hasAction(Intent.ACTION_VIEW),
hasData(AppURLs.PRIVACY_POLICY)
)
)

Intents.release()
}

@Test
fun testOpenBrowserWhenClickOnDonate() {
Intents.init()

composableTestRule
.onNodeWithTag(context.getString(R.string.donate))
.performClick()

intended(
allOf(
hasAction(Intent.ACTION_VIEW),
hasData(AppURLs.DONATE)
)
)

Intents.release()
}

@Test
fun testOpenBrowserWhenClickOnReportError() {
Intents.init()

composableTestRule
.onNodeWithTag(context.getString(R.string.report_error))
.performClick()

intended(
allOf(
hasAction(Intent.ACTION_VIEW),
hasData(AppURLs.REPORT_ERROR)
)
)

Intents.release()
}
}
14 changes: 14 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -204,4 +204,18 @@
</intent-filter>
</service>
</application>

<!--
In Android 11 (API level 30) and higher, package visibility restrictions apply.
Without declaring this <queries> element, calls like
intent.resolveActivity(activity.packageManager) will return null,
because the system hides apps that can handle the intent.
-->
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
</intent>
</queries>
Comment on lines +207 to +220
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this for? Catima has been running on Android 11 and up for ages and has never needed this before.

</manifest>
Loading