Skip to content

Commit

Permalink
feat: Bootstrap data (#18)
Browse files Browse the repository at this point in the history
Initial setup the app needs.
  • Loading branch information
sdsantos authored Mar 29, 2021
1 parent 0f7a378 commit fb65b57
Show file tree
Hide file tree
Showing 9 changed files with 139 additions and 1 deletion.
4 changes: 4 additions & 0 deletions app/src/main/java/tech/relaycorp/ping/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import kotlinx.coroutines.launch
import tech.relaycorp.awaladroid.Awala
import tech.relaycorp.ping.common.di.AppComponent
import tech.relaycorp.ping.common.di.DaggerAppComponent
import tech.relaycorp.ping.domain.BootstrapData
import javax.inject.Inject

class App : Application() {

Expand All @@ -18,13 +20,15 @@ class App : Application() {
.appModule(AppModule(this))
.build()

@Inject lateinit var bootstrapData: BootstrapData

override fun onCreate() {
super.onCreate()
component.inject(this)

CoroutineScope(coroutineContext).launch {
Awala.setup(this@App)
bootstrapData.bootstrapIfNeeded()
}
}
}
16 changes: 16 additions & 0 deletions app/src/main/java/tech/relaycorp/ping/awala/AwalaModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package tech.relaycorp.ping.awala

import dagger.Module
import dagger.Provides
import tech.relaycorp.awaladroid.endpoint.FirstPartyEndpoint

@Module
class AwalaModule {

@Provides
fun firstPartyEndpointRegistration(): FirstPartyEndpointRegistration =
object : FirstPartyEndpointRegistration {
override suspend fun register(): FirstPartyEndpoint =
FirstPartyEndpoint.register()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package tech.relaycorp.ping.awala

import tech.relaycorp.awaladroid.endpoint.FirstPartyEndpoint

interface FirstPartyEndpointRegistration {
suspend fun register(): FirstPartyEndpoint
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package tech.relaycorp.ping.common.di
import dagger.Component
import tech.relaycorp.ping.App
import tech.relaycorp.ping.AppModule
import tech.relaycorp.ping.awala.AwalaModule
import tech.relaycorp.ping.data.DataModule
import tech.relaycorp.ping.ui.main.MainActivity
import javax.inject.Singleton
Expand All @@ -11,7 +12,8 @@ import javax.inject.Singleton
@Component(
modules = [
AppModule::class,
DataModule::class
DataModule::class,
AwalaModule::class
]
)
interface AppComponent {
Expand Down
6 changes: 6 additions & 0 deletions app/src/main/java/tech/relaycorp/ping/data/DataModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,19 @@ package tech.relaycorp.ping.data
import android.content.Context
import androidx.room.Room
import dagger.Module
import dagger.Provides
import tech.relaycorp.ping.data.database.AppDatabase

@Module
class DataModule {

@Provides
fun appDatabase(context: Context) =
Room.databaseBuilder(context, AppDatabase::class.java, "ping").build()

@Provides
fun pingDao(db: AppDatabase) = db.pingDao()

@Provides
fun publicPeerDao(db: AppDatabase) = db.publicPeerDao()
}
23 changes: 23 additions & 0 deletions app/src/main/java/tech/relaycorp/ping/domain/AddPublicPeer.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package tech.relaycorp.ping.domain

import tech.relaycorp.awaladroid.endpoint.PublicThirdPartyEndpoint
import tech.relaycorp.ping.data.database.dao.PublicPeerDao
import tech.relaycorp.ping.data.database.entity.PublicPeerEntity
import javax.inject.Inject

class AddPublicPeer
@Inject constructor(
private val publicPeerDao: PublicPeerDao
) {

suspend fun add(address: String, identity: ByteArray): PublicThirdPartyEndpoint {
val endpoint = PublicThirdPartyEndpoint.import(address, identity)
publicPeerDao.save(
PublicPeerEntity(
privateAddress = endpoint.privateAddress,
publicAddress = endpoint.publicAddress
)
)
return endpoint
}
}
32 changes: 32 additions & 0 deletions app/src/main/java/tech/relaycorp/ping/domain/BootstrapData.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package tech.relaycorp.ping.domain

import android.content.res.Resources
import kotlinx.coroutines.flow.first
import tech.relaycorp.ping.R
import tech.relaycorp.ping.awala.FirstPartyEndpointRegistration
import tech.relaycorp.ping.data.preference.AppPreferences
import javax.inject.Inject

class BootstrapData
@Inject constructor(
private val resources: Resources,
private val appPreferences: AppPreferences,
private val addPublicPeer: AddPublicPeer,
private val firstPartyEndpointRegistration: FirstPartyEndpointRegistration
) {

suspend fun bootstrapIfNeeded() {
if (appPreferences.firstPartyEndpointAddress().first() != null) return

importDefaultPublicPeer()
val endpoint = firstPartyEndpointRegistration.register()
appPreferences.setFirstPartyEndpointAddress(endpoint.privateAddress)
}

private suspend fun importDefaultPublicPeer() {
addPublicPeer.add(
"ping.awala.services",
resources.openRawResource(R.raw.ping_awala_identity).use { it.readBytes() }
)
}
}
File renamed without changes.
48 changes: 48 additions & 0 deletions app/src/test/java/tech/relaycorp/ping/domain/BootstrapDataTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package tech.relaycorp.ping.domain

import android.content.res.Resources
import com.nhaarman.mockitokotlin2.*
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.test.runBlockingTest
import org.junit.Test
import tech.relaycorp.awaladroid.endpoint.FirstPartyEndpoint
import tech.relaycorp.ping.awala.FirstPartyEndpointRegistration
import tech.relaycorp.ping.data.preference.AppPreferences

class BootstrapDataTest {

private val resources = mock<Resources>()
private val appPreferences = mock<AppPreferences>()
private val addPublicPeer = mock<AddPublicPeer>()
private val registerFirstPartyEndpoint = mock<FirstPartyEndpointRegistration>()

private val subject =
BootstrapData(resources, appPreferences, addPublicPeer, registerFirstPartyEndpoint)

@Test
fun bootstrap_ifNotNeeded() = runBlockingTest {
whenever(appPreferences.firstPartyEndpointAddress()).thenReturn(flowOf("123456"))

subject.bootstrapIfNeeded()

verifyZeroInteractions(registerFirstPartyEndpoint)
verifyZeroInteractions(addPublicPeer)
verify(appPreferences, never()).setFirstPartyEndpointAddress(any())
}

@Test
fun bootstrap_ifNeeded() = runBlockingTest {
whenever(appPreferences.firstPartyEndpointAddress()).thenReturn(flowOf(null))
val firstPartyEndpoint = mock<FirstPartyEndpoint>()
val firstPartyAddress = "123456"
whenever(firstPartyEndpoint.privateAddress).thenReturn(firstPartyAddress)
whenever(registerFirstPartyEndpoint.register()).thenReturn(firstPartyEndpoint)
whenever(resources.openRawResource(any())).thenReturn(ByteArray(0).inputStream())

subject.bootstrapIfNeeded()

verify(addPublicPeer).add(eq("ping.awala.services"), any())
verify(registerFirstPartyEndpoint).register()
verify(appPreferences).setFirstPartyEndpointAddress(eq(firstPartyAddress))
}
}

0 comments on commit fb65b57

Please sign in to comment.