Skip to content

Commit

Permalink
Add tests to verify if the SDK can be successfully integrated into an…
Browse files Browse the repository at this point in the history
… Android project. (#514)
  • Loading branch information
overcat authored Aug 23, 2023
1 parent bb68109 commit d6379e9
Show file tree
Hide file tree
Showing 40 changed files with 1,074 additions and 1 deletion.
33 changes: 32 additions & 1 deletion .github/workflows/test-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,39 @@ jobs:
name: javadoc
path: javadoc

android-test:
needs: shadow_jar
runs-on: macos-latest
name: android-test (api ${{ matrix.api-level }})
strategy:
fail-fast: false
matrix:
# minSdk and targetSdk, see ${project_root}/android_test/app/build.gradle.kts
api-level: [ 26, 33 ]
steps:
- name: checkout
uses: actions/checkout@v3
- name: Download JAR Artifact
uses: actions/download-artifact@v2
with:
name: jar
path: android_test/app/libs/
- uses: actions/setup-java@v3
with:
java-version: 17 # TODO: Android Gradle plugin requires Java 11, consider replacing other parts with Java 17.
distribution: ${{ env.JAVA_DISTRIBUTION }}
- name: run tests
uses: reactivecircus/android-emulator-runner@v2
with:
working-directory: ./android_test
api-level: ${{ matrix.api-level }}
script: ./gradlew connectedCheck
target: google_apis
arch: x86_64
profile: 'pixel_2'

deploy:
needs: [ shadow_jar, javadoc ]
needs: [ javadoc, android-test ]
permissions:
contents: write
if: github.event_name == 'release' && github.event.action == 'created'
Expand Down
15 changes: 15 additions & 0 deletions android_test/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties
4 changes: 4 additions & 0 deletions android_test/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Android Test
This folder contains a simple project for testing whether stellar-sdk can be successfully integrated into an Android project.

This project is based on a template project created using Android Studio, and I have tried my best not to make any excessive modifications.
1 change: 1 addition & 0 deletions android_test/app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
71 changes: 71 additions & 0 deletions android_test/app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
}

android {
namespace = "org.stellar.javastellarsdkdemoapp"
compileSdk = 33

defaultConfig {
applicationId = "org.stellar.javastellarsdkdemoapp"
minSdk = 26
targetSdk = 33
versionCode = 1
versionName = "1.0"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
}
}

buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.4.3"
}
packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}
}

dependencies {

implementation("androidx.core:core-ktx:1.9.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.1")
implementation("androidx.activity:activity-compose:1.7.2")
implementation(platform("androidx.compose:compose-bom:2023.03.00"))
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-graphics")
implementation("androidx.compose.ui:ui-tooling-preview")
implementation("androidx.compose.material3:material3")
implementation(files("libs/stellar-sdk.jar"))
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.uiautomator:uiautomator:2.3.0-alpha03")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
androidTestImplementation(platform("androidx.compose:compose-bom:2023.03.00"))
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
debugImplementation("androidx.compose.ui:ui-tooling")
debugImplementation("androidx.compose.ui:ui-test-manifest")
}
1 change: 1 addition & 0 deletions android_test/app/libs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
You need to place stellar-sdk.jar into this folder.
21 changes: 21 additions & 0 deletions android_test/app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package org.stellar.javastellarsdkdemoapp

import android.content.Intent
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.Until
import org.junit.Assert.*
import org.junit.Test
import org.junit.runner.RunWith

private const val ONE_MINUTE = 1000L * 60
private const val PACKAGE = "org.stellar.javastellarsdkdemoapp"

/**
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class MainInstrumentedTest {
@Test
fun testGetNetwork() {
val device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
// open app
device.pressHome()
val launcherPackage: String = device.launcherPackageName
assertNotNull(launcherPackage)
device.wait(
Until.hasObject(By.pkg(launcherPackage).depth(0)),
ONE_MINUTE
)
val context = InstrumentationRegistry.getInstrumentation().context
val intent =
context.packageManager.getLaunchIntentForPackage(PACKAGE)
intent?.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
context.startActivity(intent)
// wait for app to appear
device.wait(
Until.hasObject(By.pkg(PACKAGE).depth(0)),
ONE_MINUTE
)

// get text
val textNoNetworkInfo = device.wait(
Until.findObject(By.text("No network info")),
ONE_MINUTE
)
assertNotNull(textNoNetworkInfo)

// get button
val button = device.wait(
Until.findObject(By.text("Get Network")),
ONE_MINUTE
)
assertNotNull(button)

// click button and wait text to appear
button.click()

assertTrue(device.wait(Until.hasObject(By.text("public")), ONE_MINUTE * 5))
}
}
28 changes: 28 additions & 0 deletions android_test/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />

<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.JavaStellarSDKDemoApp"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.JavaStellarSDKDemoApp">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package org.stellar.javastellarsdkdemoapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.stellar.javastellarsdkdemoapp.ui.theme.JavaStellarSDKDemoAppTheme
import org.stellar.sdk.Server

private const val HORIZON_SERVER = "https://horizon.stellar.org/"
private const val PUBLIC = "Public Global Stellar Network ; September 2015"
private const val TESTNET = "Test SDF Network ; September 2015"

class MainActivity : ComponentActivity() {
private lateinit var networkViewModel: NetworkViewModel

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

networkViewModel = ViewModelProvider(this).get(NetworkViewModel::class.java)

setContent {
JavaStellarSDKDemoAppTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
Main(networkViewModel)
}
}
}
}
}

class NetworkViewModel : ViewModel() {
private val _network = mutableStateOf<String?>(null)
val network: String? get() = _network.value

fun fetchNetworkPassphrase() {
viewModelScope.launch {
_network.value = withContext(Dispatchers.IO) {
getNetwork()
}
}
}
}

@Composable
fun Main(networkViewModel: NetworkViewModel, modifier: Modifier = Modifier) {
Column(
modifier = modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Button(
onClick = { networkViewModel.fetchNetworkPassphrase() }
) {
Text(text = "Get Network")
}

Spacer(modifier = Modifier.height(16.dp))

Text(
text = networkViewModel.network ?: "No network info",
modifier = Modifier.padding(horizontal = 16.dp)
)
}
}

@Preview(showBackground = true)
@Composable
fun MainPreview() {
JavaStellarSDKDemoAppTheme {
val networkViewModel = NetworkViewModel()
Main(networkViewModel)
}
}

private fun getNetwork(): String? {
val server = Server(HORIZON_SERVER)
return try {
when (server.root().networkPassphrase) {
PUBLIC -> {
"public"
}

TESTNET -> {
"testnet"
}

else -> {
"others"
}
}
} catch (e: Exception) {
null
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.stellar.javastellarsdkdemoapp.ui.theme

import androidx.compose.ui.graphics.Color

val Purple80 = Color(0xFFD0BCFF)
val PurpleGrey80 = Color(0xFFCCC2DC)
val Pink80 = Color(0xFFEFB8C8)

val Purple40 = Color(0xFF6650a4)
val PurpleGrey40 = Color(0xFF625b71)
val Pink40 = Color(0xFF7D5260)
Loading

0 comments on commit d6379e9

Please sign in to comment.