Skip to content

Commit

Permalink
ALS-1885 Update place popup to show new information (#96)
Browse files Browse the repository at this point in the history
* fix: reverse geocode and direction button should not work if only data is pulled bug fixes
fix: Two bottom sheet opening fixes with code optimization
refactor: Auth SDK version update with related code changes

ALS-1882

* fix: App should work without no data inside custom.properties file

ALS-1884

* feat: Places popup updated with new information

ALS-1885

* feat: code optimize

ALS-1885

---------

Co-authored-by: shah <[email protected]>
  • Loading branch information
wadhawh and shah272728 authored Dec 4, 2024
1 parent d7b035c commit a0abe8b
Show file tree
Hide file tree
Showing 54 changed files with 1,863 additions and 416 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ dependencies {

implementation "org.maplibre.gl:android-sdk:11.0.0"
implementation "org.maplibre.gl:android-plugin-annotation-v9:3.0.0"
implementation("software.amazon.location:auth:0.2.5")
implementation("software.amazon.location:auth:1.1.0")
implementation("com.google.android.gms:play-services-location:21.3.0")

implementation "androidx.navigation:navigation-fragment-ktx:2.7.7"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ const val TEST_WORD_RIO_TINTO = "Rio Tinto"
const val TEST_WORD_SHYAMAL = "Shyamal Cross"
const val TEST_WORD_SCHOOL = "School"
const val TEST_WORD_SHYAMAL_CROSS_ROAD = "Shyamal Cross Road"
const val TEST_WORD_DOMINO_PIZZA_VEJALPUR = "dominos Jivraj Park Cross Road, Vejalpur Police Chowky, Vejalpur"
const val TEST_WORD_DOMINO_PIZZA = "Domino's"
const val TEST_WORD_AUBURN_SYDNEY = "auburn sydney"
const val TEST_WORD_MANLY_BEACH_SYDNEY = "manly beach sydney"
const val TEST_WORD_CLOVERDALE_PERTH = "cloverdale perth"
Expand Down Expand Up @@ -86,6 +88,7 @@ const val TEST_FAILED_COUNT_NOT_GREATER_THEN_TWO = "Test failed due to count not
const val TEST_FAILED_DRIVE_OR_WALK_OR_TRUCK_OPTION_NOT_VISIBLE = "Test failed due to drive or walk or truck option not visible"
const val TEST_FAILED_INVALID_ORIGIN_OR_DESTINATION_TEXT = "Test failed due to invalid origin or destination text"
const val TEST_FAILED_DIRECTION_TIME_NOT_VISIBLE = "Test failed due to direction time not visible"
const val TEST_FAILED_PLACE_LINK_NOT_VISIBLE = "Test failed due to place link not visible"
const val TEST_FAILED_IMAGE_NULL = "Test failed due to image null"
const val TEST_FAILED_NOT_EQUAL = "Test failed due to not equal"
const val TEST_FAILED_POOL_ID_NOT_BLANK = "Test failed due to pool id not blank"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import com.aws.amazonlocation.ui.main.ExploreFragmentSearchByCategoriesTest
import com.aws.amazonlocation.ui.main.ExploreFragmentSearchCollapseTest
import com.aws.amazonlocation.ui.main.ExploreFragmentSearchExistsTest
import com.aws.amazonlocation.ui.main.ExploreFragmentSearchGeocodeReversedTest
import com.aws.amazonlocation.ui.main.SearchContactInfoPOICardTest
import org.junit.runner.RunWith
import org.junit.runners.Suite

Expand All @@ -31,5 +32,6 @@ import org.junit.runners.Suite
ExploreFragmentSearchCollapseTest::class,
ExploreFragmentSearchExistsTest::class,
ExploreFragmentSearchGeocodeReversedTest::class,
SearchContactInfoPOICardTest::class
)
class MapLoadAndPlaceSearchFlowSuite
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package com.aws.amazonlocation.ui.main

import android.view.View
import androidx.appcompat.widget.AppCompatTextView
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import androidx.test.core.app.ApplicationProvider
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.action.ViewActions.replaceText
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.contrib.RecyclerViewActions
import androidx.test.espresso.matcher.ViewMatchers.hasDescendant
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import androidx.test.uiautomator.By
import androidx.test.uiautomator.UiDevice
import androidx.test.uiautomator.UiSelector
import androidx.test.uiautomator.Until
import com.aws.amazonlocation.ALLOW
import com.aws.amazonlocation.AMAZON_MAP_READY
import com.aws.amazonlocation.BaseTestMainActivity
import com.aws.amazonlocation.BuildConfig
import com.aws.amazonlocation.DELAY_15000
import com.aws.amazonlocation.DELAY_2000
import com.aws.amazonlocation.DELAY_20000
import com.aws.amazonlocation.R
import com.aws.amazonlocation.TEST_FAILED
import com.aws.amazonlocation.TEST_FAILED_NO_SEARCH_RESULT
import com.aws.amazonlocation.TEST_FAILED_PLACE_LINK_NOT_VISIBLE
import com.aws.amazonlocation.TEST_WORD_DOMINO_PIZZA
import com.aws.amazonlocation.TEST_WORD_DOMINO_PIZZA_VEJALPUR
import com.aws.amazonlocation.WHILE_USING_THE_APP
import com.aws.amazonlocation.WHILE_USING_THE_APP_ALLOW
import com.aws.amazonlocation.WHILE_USING_THE_APP_CAPS
import com.aws.amazonlocation.di.AppModule
import com.aws.amazonlocation.enableGPS
import com.aws.amazonlocation.failTest
import com.google.android.material.card.MaterialCardView
import dagger.hilt.android.testing.HiltAndroidTest
import dagger.hilt.android.testing.UninstallModules
import org.junit.Assert
import org.junit.Test

@UninstallModules(AppModule::class)
@HiltAndroidTest
class SearchContactInfoPOICardTest : BaseTestMainActivity() {

private val uiDevice = UiDevice.getInstance(getInstrumentation())

@Test
fun searchContactInfoPOICardTest() {
try {
val btnContinueToApp = uiDevice.findObject(UiSelector().resourceId("${BuildConfig.APPLICATION_ID}:id/btn_continue_to_app"))
if (btnContinueToApp.exists()) {
btnContinueToApp.click()
Thread.sleep(DELAY_2000)
}
uiDevice.findObject(By.text(WHILE_USING_THE_APP))?.click()
uiDevice.findObject(By.text(WHILE_USING_THE_APP_CAPS))?.click()
uiDevice.findObject(By.text(WHILE_USING_THE_APP_ALLOW))?.click()
uiDevice.findObject(By.text(ALLOW))?.click()
Thread.sleep(DELAY_2000)
enableGPS(ApplicationProvider.getApplicationContext())
uiDevice.wait(Until.hasObject(By.desc(AMAZON_MAP_READY)), DELAY_15000)
Thread.sleep(DELAY_2000)

val edtSearch =
onView(withId(R.id.edt_search_places)).check(matches(isDisplayed()))
edtSearch.perform(click())
onView(withId(R.id.edt_search_places)).perform(replaceText(TEST_WORD_DOMINO_PIZZA_VEJALPUR))
uiDevice.wait(
Until.hasObject(By.res("${BuildConfig.APPLICATION_ID}:id/rv_search_places_suggestion")),
DELAY_20000
)
getInstrumentation().waitForIdleSync()
val rvSearchPlaceSuggestion =
mActivityRule.activity.findViewById<RecyclerView>(R.id.rv_search_places_suggestion)
if (rvSearchPlaceSuggestion.adapter?.itemCount != null) {
rvSearchPlaceSuggestion.adapter?.itemCount?.let {
if (it >= 0) {
Thread.sleep(DELAY_2000)
onView(withId(R.id.rv_search_places_suggestion))
.check(matches(hasDescendant(withText(TEST_WORD_DOMINO_PIZZA))))
Thread.sleep(DELAY_2000)
onView(withId(R.id.rv_search_places_suggestion))
.perform(RecyclerViewActions.actionOnItem<ViewHolder>(hasDescendant(withText(TEST_WORD_DOMINO_PIZZA)), click()))
Thread.sleep(DELAY_2000)
val btnDirection =
mActivityRule.activity.findViewById<MaterialCardView>(R.id.btn_direction)
if (btnDirection.visibility == View.VISIBLE) {
uiDevice.wait(
Until.hasObject(By.res("${BuildConfig.APPLICATION_ID}:id/tv_direction_distance")),
DELAY_20000,
)
val tvPlaceLink =
mActivityRule.activity.findViewById<AppCompatTextView>(R.id.tv_place_link)
Thread.sleep(DELAY_2000)
Assert.assertTrue(TEST_FAILED_PLACE_LINK_NOT_VISIBLE, tvPlaceLink.visibility == View.VISIBLE)
} else {
Assert.fail()
}
} else {
Assert.fail(TEST_FAILED_NO_SEARCH_RESULT)
}
}
} else {
Assert.fail(TEST_FAILED_NO_SEARCH_RESULT)
}
} catch (e: Exception) {
failTest(107, e)
Assert.fail(TEST_FAILED)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
package com.aws.amazonlocation.data.datasource

import aws.sdk.kotlin.services.georoutes.model.CalculateRoutesResponse
import aws.sdk.kotlin.services.location.model.ListGeofenceResponseEntry
import aws.sdk.kotlin.services.location.model.Step
import com.aws.amazonlocation.domain.`interface`.BatchLocationUpdateInterface
import com.aws.amazonlocation.domain.`interface`.DistanceInterface
import com.aws.amazonlocation.domain.`interface`.GeofenceAPIInterface
import com.aws.amazonlocation.domain.`interface`.LocationDeleteHistoryInterface
import com.aws.amazonlocation.domain.`interface`.LocationHistoryInterface
import com.aws.amazonlocation.domain.`interface`.NavigationDataInterface
import com.aws.amazonlocation.domain.`interface`.PlaceInterface
import com.aws.amazonlocation.domain.`interface`.SearchDataInterface
import com.aws.amazonlocation.domain.`interface`.SearchPlaceInterface
import com.aws.amazonlocation.domain.`interface`.SignInInterface
Expand Down Expand Up @@ -102,4 +100,9 @@ interface RemoteDataSource {
suspend fun refreshTokensWithOkHttp(
signInInterface: SignInInterface
)

suspend fun getPlace(
placeId: String,
placeInterface: PlaceInterface
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import com.aws.amazonlocation.domain.`interface`.DistanceInterface
import com.aws.amazonlocation.domain.`interface`.GeofenceAPIInterface
import com.aws.amazonlocation.domain.`interface`.LocationDeleteHistoryInterface
import com.aws.amazonlocation.domain.`interface`.LocationHistoryInterface
import com.aws.amazonlocation.domain.`interface`.PlaceInterface
import com.aws.amazonlocation.domain.`interface`.SearchDataInterface
import com.aws.amazonlocation.domain.`interface`.SearchPlaceInterface
import com.aws.amazonlocation.domain.`interface`.SignInInterface
Expand Down Expand Up @@ -48,8 +49,8 @@ class RemoteDataSourceImpl(
if (mContext.isInternetAvailable()) {
val mSearchSuggestionResponse =
mPlacesProvider.searchPlaceSuggestion(lat, lng, searchText, mLocationProvider.getBaseActivity(), mLocationProvider.getGeoPlacesClient())
if (validateLatLng(searchText) != null) {
val mLatLng = validateLatLng(searchText)
if (validateLatLng(searchText.trim()) != null) {
val mLatLng = validateLatLng(searchText.trim())
if (mSearchSuggestionResponse.text == (mLatLng?.latitude.toString() + "," + mLatLng?.longitude.toString())) {
searchPlace.getSearchPlaceSuggestionResponse(mSearchSuggestionResponse)
} else {
Expand Down Expand Up @@ -267,4 +268,25 @@ class RemoteDataSourceImpl(
signInInterface.refreshTokensWithOkHttpFailed("failed")
}
}

override suspend fun getPlace(placeId: String, placeInterface: PlaceInterface) {
if (mContext.isInternetAvailable()) {
val placeResponse = mPlacesProvider.getPlace(placeId, mLocationProvider.getBaseActivity(), mLocationProvider.getGeoPlacesClient())
if (placeResponse != null) {
placeInterface.placeSuccess(placeResponse)
} else {
placeInterface.placeFailed(DataSourceException.Error(""))
}
} else {
placeInterface.internetConnectionError(
if (isRunningRemoteDataSourceImplTest) {
""
} else {
mContext.resources.getString(
R.string.check_your_internet_connection_and_try_again,
)
},
)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package com.aws.amazonlocation.data.repository

import aws.sdk.kotlin.services.geoplaces.GeoPlacesClient
import com.aws.amazonlocation.data.datasource.RemoteDataSourceImpl
import com.aws.amazonlocation.domain.`interface`.DistanceInterface
import com.aws.amazonlocation.domain.`interface`.PlaceInterface
import com.aws.amazonlocation.domain.`interface`.SearchDataInterface
import com.aws.amazonlocation.domain.`interface`.SearchPlaceInterface
import com.aws.amazonlocation.domain.repository.LocationSearchRepository
import com.aws.amazonlocation.ui.base.BaseActivity

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.

Expand Down Expand Up @@ -64,4 +67,8 @@ class LocationSearchImp(private val mRemoteDataSource: RemoteDataSourceImpl) :
searchPlace
)
}

override suspend fun getPlace(placeId: String, placeInterface: PlaceInterface) {
mRemoteDataSource.getPlace(placeId, placeInterface)
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.aws.amazonlocation.data.response

import aws.sdk.kotlin.services.geoplaces.model.Address
import aws.sdk.kotlin.services.geoplaces.model.Contacts
import aws.sdk.kotlin.services.geoplaces.model.OpeningHours


// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
Expand All @@ -23,5 +25,7 @@ data class SearchSuggestionData(
var isPlaceIndexForPosition: Boolean = false,
var amazonLocationAddress: Address? = null,
var position: List<Double> ? = null,
var queryId: String ? = null
var queryId: String ? = null,
var contacts: Contacts? = null,
var openingHours: List<OpeningHours>? = null
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.aws.amazonlocation.domain.`interface`

import aws.sdk.kotlin.services.geoplaces.model.GetPlaceResponse
import com.aws.amazonlocation.data.common.DataSourceException

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.

// SPDX-License-Identifier: MIT-0
interface PlaceInterface {

fun placeSuccess(success: GetPlaceResponse) {}

fun placeFailed(exception: DataSourceException) {}

fun internetConnectionError(exception: String) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import aws.sdk.kotlin.services.georoutes.model.CalculateRoutesResponse
import aws.sdk.kotlin.services.location.model.Step
import com.aws.amazonlocation.domain.`interface`.DistanceInterface
import com.aws.amazonlocation.domain.`interface`.NavigationDataInterface
import com.aws.amazonlocation.domain.`interface`.PlaceInterface
import com.aws.amazonlocation.domain.`interface`.SearchDataInterface
import com.aws.amazonlocation.domain.`interface`.SearchPlaceInterface

Expand Down Expand Up @@ -43,4 +44,6 @@ interface LocationSearchRepository {
lng: Double?,
searchPlace: SearchDataInterface
)

suspend fun getPlace(placeId: String, placeInterface: PlaceInterface)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import aws.sdk.kotlin.services.georoutes.model.CalculateRoutesResponse
import aws.sdk.kotlin.services.location.model.Step
import com.aws.amazonlocation.domain.`interface`.DistanceInterface
import com.aws.amazonlocation.domain.`interface`.NavigationDataInterface
import com.aws.amazonlocation.domain.`interface`.PlaceInterface
import com.aws.amazonlocation.domain.`interface`.SearchDataInterface
import com.aws.amazonlocation.domain.`interface`.SearchPlaceInterface
import com.aws.amazonlocation.domain.repository.LocationSearchRepository
Expand Down Expand Up @@ -55,4 +56,6 @@ class LocationSearchUseCase @Inject constructor(private val mLocationSearchRepos
lng: Double?,
searchPlace: SearchDataInterface
) = mLocationSearchRepository.searPlaceIndexForPosition(lat, lng, searchPlace)

suspend fun getPlace(placeId: String, placeInterface: PlaceInterface) = mLocationSearchRepository.getPlace(placeId, placeInterface)
}
11 changes: 4 additions & 7 deletions app/src/main/java/com/aws/amazonlocation/ui/base/BaseActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import software.amazon.location.auth.AuthHelper
import javax.inject.Inject

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
Expand Down Expand Up @@ -73,7 +72,6 @@ open class BaseActivity : AppCompatActivity() {
lateinit var mLocationProvider: LocationProvider

private var subTitle = ""
lateinit var authHelper: AuthHelper
val mSignInViewModel: SignInViewModel by viewModels()

override fun onCreate(savedInstanceState: Bundle?) {
Expand Down Expand Up @@ -105,7 +103,6 @@ open class BaseActivity : AppCompatActivity() {
mGeofenceBottomSheetHelper = GeofenceBottomSheetHelper(this@BaseActivity)
mGeofenceUtils = GeofenceUtils()

authHelper = AuthHelper(applicationContext)
val preference = PreferenceManager(applicationContext)
mTrackingUtils = TrackingUtils(preference, this@BaseActivity, mLocationProvider)
mSimulationUtils = SimulationUtils(preference, this@BaseActivity, mLocationProvider)
Expand All @@ -127,8 +124,8 @@ open class BaseActivity : AppCompatActivity() {
}

suspend fun initMobileClient() {
mLocationProvider.initializeLocationCredentialsProvider(authHelper, this)
mLocationProvider.initPlaceRoutesClients()
mLocationProvider.initializeLocationCredentialsProvider(this)
mLocationProvider.initPlaceRoutesClients(this)
}

private fun locationPermissionDialog() {
Expand Down Expand Up @@ -253,10 +250,10 @@ open class BaseActivity : AppCompatActivity() {

fun restartAppWithClearData() {
lifecycleScope.launch {
mLocationProvider.locationCredentialsProvider?.clear()
mLocationProvider.clearCredentials()
mPreferenceManager.setDefaultConfig()
delay(RESTART_DELAY)
restartApplication()
}
}
}
}
Loading

0 comments on commit a0abe8b

Please sign in to comment.