- Added new methods that allow a query of a single term over name, address, phone, telegram an website fields
- Linking this result to the code that handles the UI update (working for merchants only)
This commit is contained in:
parent
07e39e9001
commit
aebff15033
8 changed files with 144 additions and 21 deletions
|
@ -47,6 +47,11 @@ android {
|
||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
targetCompatibility JavaVersion.VERSION_1_8
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
}
|
}
|
||||||
|
// Gradle automatically adds 'android.test.runner' as a dependency.
|
||||||
|
useLibrary 'android.test.runner'
|
||||||
|
useLibrary 'android.test.base'
|
||||||
|
useLibrary 'android.test.mock'
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -100,9 +105,12 @@ dependencies {
|
||||||
debugImplementation 'com.amitshekhar.android:debug-db:1.0.4'
|
debugImplementation 'com.amitshekhar.android:debug-db:1.0.4'
|
||||||
|
|
||||||
// TODO enable and make proper testing
|
// TODO enable and make proper testing
|
||||||
// testImplementation 'junit:junit:4.12'
|
testImplementation 'junit:junit:4.12'
|
||||||
|
// Core library
|
||||||
|
androidTestImplementation 'androidx.test:core:1.1.0'
|
||||||
|
|
||||||
// testImplementation "androidx.arch.core:core-testing:$lifecycle_version"
|
// testImplementation "androidx.arch.core:core-testing:$lifecycle_version"
|
||||||
// testImplementation "androidx.room:room-testing:$room_version"
|
// testImplementation "androidx.room:room-testing:$room_version"
|
||||||
// androidTestImplementation 'androidx.test:runner:1.1.0'
|
// androidTestImplementation 'androidx.test:runner:1.1.0'
|
||||||
// androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
package cy.agorise.bitsybitshareswallet;
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.room.Room
|
||||||
|
import androidx.test.core.app.ApplicationProvider
|
||||||
|
import androidx.test.runner.AndroidJUnit4
|
||||||
|
import cy.agorise.bitsybitshareswallet.database.BitsyDatabase
|
||||||
|
import cy.agorise.bitsybitshareswallet.database.entities.Merchant
|
||||||
|
import org.junit.After
|
||||||
|
import org.junit.Assert
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.runner.RunWith
|
||||||
|
import java.io.IOException
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4::class)
|
||||||
|
public class MerchantQueryTest {
|
||||||
|
private lateinit var db: BitsyDatabase
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun createDb(){
|
||||||
|
val context = ApplicationProvider.getApplicationContext<Context>()
|
||||||
|
db = Room.inMemoryDatabaseBuilder(context, BitsyDatabase::class.java).build()
|
||||||
|
|
||||||
|
// Creating a few sample merchants
|
||||||
|
val merchant1 = Merchant("5c23c8c234c83f0013e67786",
|
||||||
|
"Café del Mar",
|
||||||
|
"Address1",
|
||||||
|
17.82834,
|
||||||
|
-9.38483,
|
||||||
|
"+1 999.999.9999",
|
||||||
|
"@user",
|
||||||
|
"https://100Natural.com")
|
||||||
|
val merchant2 = Merchant("5c23c91a34c83f0013e67787",
|
||||||
|
"Condesa Acapulco",
|
||||||
|
"Address2",
|
||||||
|
13.82834,
|
||||||
|
-67.38483,
|
||||||
|
"+1 999.999.9999",
|
||||||
|
"@user",
|
||||||
|
"https://100Natural.com")
|
||||||
|
db.merchantDao().insert(merchant1)
|
||||||
|
db.merchantDao().insert(merchant2)
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
@Throws(IOException::class)
|
||||||
|
fun closeDb(){
|
||||||
|
db.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testSimpleQuery(){
|
||||||
|
val allMerchants = db.merchantDao().getAllSync()
|
||||||
|
Assert.assertEquals(2, allMerchants.size)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testSearchQuery(){
|
||||||
|
val query = "%con%"
|
||||||
|
val merchants = db.merchantDao().findMerchantsByWordSync(query)
|
||||||
|
Assert.assertEquals(1, merchants.size)
|
||||||
|
Assert.assertEquals(merchants[0].name, "Condesa Acapulco")
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,7 @@ import androidx.room.Insert
|
||||||
import androidx.room.OnConflictStrategy
|
import androidx.room.OnConflictStrategy
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import cy.agorise.bitsybitshareswallet.database.entities.Merchant
|
import cy.agorise.bitsybitshareswallet.database.entities.Merchant
|
||||||
|
import io.reactivex.Single
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
interface MerchantDao {
|
interface MerchantDao {
|
||||||
|
@ -18,6 +19,15 @@ interface MerchantDao {
|
||||||
@Query("SELECT * FROM merchants")
|
@Query("SELECT * FROM merchants")
|
||||||
fun getAll(): LiveData<List<Merchant>>
|
fun getAll(): LiveData<List<Merchant>>
|
||||||
|
|
||||||
|
@Query("SELECT * FROM merchants")
|
||||||
|
fun getAllSync(): List<Merchant>
|
||||||
|
|
||||||
|
@Query("SELECT * FROM merchants WHERE (name LIKE :query) OR (address LIKE :query) OR (phone LIKE :query) OR (telegram LIKE :query) OR (website LIKE :query)")
|
||||||
|
fun findMerchantsByWord(query: String): Single<List<Merchant>>
|
||||||
|
|
||||||
|
@Query("SELECT * FROM merchants WHERE (name LIKE :query) OR (address LIKE :query) OR (phone LIKE :query) OR (telegram LIKE :query) OR (website LIKE :query)")
|
||||||
|
fun findMerchantsByWordSync(query: String): List<Merchant>
|
||||||
|
|
||||||
@Query("DELETE FROM merchants")
|
@Query("DELETE FROM merchants")
|
||||||
fun deleteAll()
|
fun deleteAll()
|
||||||
}
|
}
|
|
@ -6,6 +6,7 @@ import androidx.room.Insert
|
||||||
import androidx.room.OnConflictStrategy
|
import androidx.room.OnConflictStrategy
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import cy.agorise.bitsybitshareswallet.database.entities.Teller
|
import cy.agorise.bitsybitshareswallet.database.entities.Teller
|
||||||
|
import io.reactivex.Single
|
||||||
|
|
||||||
@Dao
|
@Dao
|
||||||
interface TellerDao {
|
interface TellerDao {
|
||||||
|
@ -18,6 +19,9 @@ interface TellerDao {
|
||||||
@Query("SELECT * FROM tellers")
|
@Query("SELECT * FROM tellers")
|
||||||
fun getAll(): LiveData<List<Teller>>
|
fun getAll(): LiveData<List<Teller>>
|
||||||
|
|
||||||
|
@Query("SELECT * FROM tellers WHERE (name LIKE :query) OR (address LIKE :query) OR (phone LIKE :query) OR (telegram LIKE :query) OR (website LIKE :query)")
|
||||||
|
fun findTellersByWord(query: String): Single<List<Teller>>
|
||||||
|
|
||||||
@Query("DELETE FROM tellers")
|
@Query("DELETE FROM tellers")
|
||||||
fun deleteAll()
|
fun deleteAll()
|
||||||
}
|
}
|
|
@ -6,13 +6,8 @@ import android.content.pm.PackageManager
|
||||||
import android.database.Cursor
|
import android.database.Cursor
|
||||||
import android.database.MatrixCursor
|
import android.database.MatrixCursor
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
|
||||||
import com.google.android.gms.maps.GoogleMap
|
|
||||||
import com.google.android.gms.maps.OnMapReadyCallback
|
|
||||||
import com.google.android.gms.maps.SupportMapFragment
|
|
||||||
|
|
||||||
import cy.agorise.bitsybitshareswallet.R
|
|
||||||
import android.preference.PreferenceManager
|
import android.preference.PreferenceManager
|
||||||
|
import android.util.Log
|
||||||
import android.view.*
|
import android.view.*
|
||||||
import android.widget.PopupWindow
|
import android.widget.PopupWindow
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
@ -27,12 +22,18 @@ import androidx.lifecycle.ViewModelProviders
|
||||||
import com.afollestad.materialdialogs.MaterialDialog
|
import com.afollestad.materialdialogs.MaterialDialog
|
||||||
import com.afollestad.materialdialogs.customview.customView
|
import com.afollestad.materialdialogs.customview.customView
|
||||||
import com.google.android.gms.maps.CameraUpdateFactory
|
import com.google.android.gms.maps.CameraUpdateFactory
|
||||||
import com.google.android.gms.maps.model.*
|
import com.google.android.gms.maps.GoogleMap
|
||||||
|
import com.google.android.gms.maps.OnMapReadyCallback
|
||||||
|
import com.google.android.gms.maps.SupportMapFragment
|
||||||
|
import com.google.android.gms.maps.model.LatLngBounds
|
||||||
|
import com.google.android.gms.maps.model.MapStyleOptions
|
||||||
|
import com.google.android.gms.maps.model.Marker
|
||||||
import com.google.maps.android.MarkerManager
|
import com.google.maps.android.MarkerManager
|
||||||
import com.google.maps.android.clustering.Cluster
|
import com.google.maps.android.clustering.Cluster
|
||||||
import com.google.maps.android.clustering.ClusterItem
|
import com.google.maps.android.clustering.ClusterItem
|
||||||
import com.google.maps.android.clustering.ClusterManager
|
import com.google.maps.android.clustering.ClusterManager
|
||||||
import com.jakewharton.rxbinding3.appcompat.queryTextChangeEvents
|
import com.jakewharton.rxbinding3.appcompat.queryTextChangeEvents
|
||||||
|
import cy.agorise.bitsybitshareswallet.R
|
||||||
import cy.agorise.bitsybitshareswallet.database.entities.Merchant
|
import cy.agorise.bitsybitshareswallet.database.entities.Merchant
|
||||||
import cy.agorise.bitsybitshareswallet.database.entities.Teller
|
import cy.agorise.bitsybitshareswallet.database.entities.Teller
|
||||||
import cy.agorise.bitsybitshareswallet.utils.Constants
|
import cy.agorise.bitsybitshareswallet.utils.Constants
|
||||||
|
@ -42,7 +43,9 @@ import cy.agorise.bitsybitshareswallet.utils.toast
|
||||||
import cy.agorise.bitsybitshareswallet.viewmodels.MerchantViewModel
|
import cy.agorise.bitsybitshareswallet.viewmodels.MerchantViewModel
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||||
import io.reactivex.disposables.CompositeDisposable
|
import io.reactivex.disposables.CompositeDisposable
|
||||||
import java.lang.Exception
|
import io.reactivex.schedulers.Schedulers
|
||||||
|
import java.math.BigInteger
|
||||||
|
import java.util.*
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
|
||||||
|
@ -173,21 +176,35 @@ class MerchantsFragment : Fragment(), OnMapReadyCallback, SearchView.OnSuggestio
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateSearchViewSuggestions(query: String) {
|
private fun updateSearchViewSuggestions(query: String) {
|
||||||
// TODO make call to the db to obtain the list of merchants/tellers
|
val merchObs = mMerchantViewModel.queryMerchants(query)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
|
||||||
// Create a cursor out of an Array
|
val tellerObs = mMerchantViewModel.queryTellers(query)
|
||||||
val cursor = MatrixCursor(arrayOf(SUGGEST_COLUMN_ID, SUGGEST_COLUMN_NAME,
|
.subscribeOn(Schedulers.io())
|
||||||
SUGGEST_COLUMN_ADDRESS, SUGGEST_COLUMN_IS_MERCHANT, SUGGEST_COLUMN_IMAGE_RESOURCE))
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
|
||||||
for (i in 1..3) {
|
//TODO: Combine the results of both the merchants and teller queries
|
||||||
if (i%2 == 1)
|
// val combined: Observable<List<Any>> = Observable.combineLatest<List<Merchant>, List<Teller>, List<Any>>(merchObs, tellerObs, BiFunction { t1: List<Merchant>, t2:List<Teller> -> Arrays.asList(t1, t2)})
|
||||||
cursor.addRow(arrayOf(i.toString(), "Merchant $i", "Address $i", 1, R.drawable.ic_merchant_pin))
|
|
||||||
else
|
merchObs.subscribe({list ->
|
||||||
cursor.addRow(arrayOf(i.toString(), "Teller $i", "Address $i", 0, R.drawable.ic_teller_pin))
|
run {
|
||||||
|
Log.d(TAG, "list with ${list.size} elements")
|
||||||
|
val cursor = MatrixCursor(
|
||||||
|
arrayOf(
|
||||||
|
SUGGEST_COLUMN_ID, SUGGEST_COLUMN_NAME,
|
||||||
|
SUGGEST_COLUMN_ADDRESS, SUGGEST_COLUMN_IS_MERCHANT, SUGGEST_COLUMN_IMAGE_RESOURCE
|
||||||
|
)
|
||||||
|
)
|
||||||
|
for (item in list) {
|
||||||
|
cursor.addRow(arrayOf(BigInteger(item._id, 16).toLong(), item.name, item.address, 1, R.drawable.ic_merchant_pin))
|
||||||
}
|
}
|
||||||
|
|
||||||
mSearchView?.suggestionsAdapter?.changeCursor(cursor)
|
mSearchView?.suggestionsAdapter?.changeCursor(cursor)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{error -> Log.e(TAG, "Error while retrieving autocomplete suggestions. Msg: ${error}")})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
override fun onSuggestionSelect(position: Int): Boolean {
|
override fun onSuggestionSelect(position: Int): Boolean {
|
||||||
return onSuggestionClick(position)
|
return onSuggestionClick(position)
|
||||||
|
|
|
@ -11,6 +11,7 @@ import cy.agorise.bitsybitshareswallet.database.entities.Merchant
|
||||||
import cy.agorise.bitsybitshareswallet.network.FeathersResponse
|
import cy.agorise.bitsybitshareswallet.network.FeathersResponse
|
||||||
import cy.agorise.bitsybitshareswallet.network.MerchantsWebservice
|
import cy.agorise.bitsybitshareswallet.network.MerchantsWebservice
|
||||||
import cy.agorise.bitsybitshareswallet.utils.Constants
|
import cy.agorise.bitsybitshareswallet.utils.Constants
|
||||||
|
import io.reactivex.Single
|
||||||
import retrofit2.Call
|
import retrofit2.Call
|
||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
import retrofit2.Retrofit
|
import retrofit2.Retrofit
|
||||||
|
@ -79,4 +80,8 @@ class MerchantRepository internal constructor(val context: Context) : retrofit2.
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun findMerchantsByWord(query: String): Single<List<Merchant>> {
|
||||||
|
return mMerchantDao.findMerchantsByWord("%$query%")
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -11,6 +11,7 @@ import cy.agorise.bitsybitshareswallet.database.entities.Teller
|
||||||
import cy.agorise.bitsybitshareswallet.network.FeathersResponse
|
import cy.agorise.bitsybitshareswallet.network.FeathersResponse
|
||||||
import cy.agorise.bitsybitshareswallet.network.MerchantsWebservice
|
import cy.agorise.bitsybitshareswallet.network.MerchantsWebservice
|
||||||
import cy.agorise.bitsybitshareswallet.utils.Constants
|
import cy.agorise.bitsybitshareswallet.utils.Constants
|
||||||
|
import io.reactivex.Single
|
||||||
import retrofit2.Call
|
import retrofit2.Call
|
||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
import retrofit2.Retrofit
|
import retrofit2.Retrofit
|
||||||
|
@ -79,4 +80,8 @@ class TellerRepository internal constructor(val context: Context) : retrofit2.Ca
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun findTellerByWord(word: String): Single<List<Teller>> {
|
||||||
|
return mTellerDao.findTellersByWord("%$word%")
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -7,6 +7,7 @@ import cy.agorise.bitsybitshareswallet.database.entities.Merchant
|
||||||
import cy.agorise.bitsybitshareswallet.database.entities.Teller
|
import cy.agorise.bitsybitshareswallet.database.entities.Teller
|
||||||
import cy.agorise.bitsybitshareswallet.repositories.MerchantRepository
|
import cy.agorise.bitsybitshareswallet.repositories.MerchantRepository
|
||||||
import cy.agorise.bitsybitshareswallet.repositories.TellerRepository
|
import cy.agorise.bitsybitshareswallet.repositories.TellerRepository
|
||||||
|
import io.reactivex.Single
|
||||||
|
|
||||||
class MerchantViewModel(application: Application) : AndroidViewModel(application) {
|
class MerchantViewModel(application: Application) : AndroidViewModel(application) {
|
||||||
private var mMerchantRepository = MerchantRepository(application)
|
private var mMerchantRepository = MerchantRepository(application)
|
||||||
|
@ -19,4 +20,12 @@ class MerchantViewModel(application: Application) : AndroidViewModel(application
|
||||||
internal fun getAllTellers(): LiveData<List<Teller>> {
|
internal fun getAllTellers(): LiveData<List<Teller>> {
|
||||||
return mTellerRepository.getAll()
|
return mTellerRepository.getAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun queryMerchants(query: String): Single<List<Merchant>> {
|
||||||
|
return mMerchantRepository.findMerchantsByWord(query)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun queryTellers(query: String): Single<List<Teller>> {
|
||||||
|
return mTellerRepository.findTellerByWord(query)
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue