Skip to content

Commit 07fe0e4

Browse files
authored
Merge pull request #2752 from wmathurin/clearcache
Add Clear Caches menu item to login view
2 parents 8b13b3a + cf95ed2 commit 07fe0e4

5 files changed

Lines changed: 77 additions & 1 deletion

File tree

libs/SalesforceSDK/res/values/sf__strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
<string name="sf__more_options">More Options</string>
2525
<string name="sf__pick_server">Change Server</string>
2626
<string name="sf__clear_cookies">Clear Cookies</string>
27+
<string name="sf__clear_cache">Clear cache</string>
2728
<string name="sf__reload">Reload</string>
2829
<string name="sf__launch_idp">Log In with IDP App</string>
2930
<string name="sf__login_with_biometric">Log In with Biometric</string>

libs/SalesforceSDK/src/com/salesforce/androidsdk/ui/LoginViewModel.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ package com.salesforce.androidsdk.ui
2828

2929
import android.webkit.CookieManager
3030
import android.webkit.URLUtil
31+
import android.webkit.WebView
3132
import androidx.annotation.VisibleForTesting
3233
import androidx.compose.runtime.Composable
3334
import androidx.compose.runtime.derivedStateOf
@@ -241,6 +242,11 @@ open class LoginViewModel(val bootConfig: BootConfig) : ViewModel() {
241242
open fun clearCookies() =
242243
CookieManager.getInstance().removeAllCookies(null)
243244

245+
/** Clear WebView Cache. */
246+
open fun clearWebViewCache(webView: WebView) {
247+
webView.clearCache(true)
248+
}
249+
244250
/**
245251
* Automatically log in using the provided UI Bridge API parameters.
246252
* @param frontdoorBridgeUrl The UI Bridge API front door bridge API

libs/SalesforceSDK/src/com/salesforce/androidsdk/ui/components/LoginView.kt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ import androidx.lifecycle.LiveData
107107
import androidx.lifecycle.viewmodel.compose.viewModel
108108
import com.salesforce.androidsdk.R.string.sf__back_button_content_description
109109
import com.salesforce.androidsdk.R.string.sf__clear_cookies
110+
import com.salesforce.androidsdk.R.string.sf__clear_cache
110111
import com.salesforce.androidsdk.R.string.sf__launch_idp
111112
import com.salesforce.androidsdk.R.string.sf__loading_indicator
112113
import com.salesforce.androidsdk.R.string.sf__more_options
@@ -149,6 +150,7 @@ fun LoginView() {
149150
titleTextColor = viewModel.titleTextColor ?: viewModel.dynamicHeaderTextColor.value,
150151
showServerPicker = viewModel.showServerPicker,
151152
clearCookies = { viewModel.clearCookies() },
153+
clearWebViewCache = { viewModel.clearWebViewCache(activity.webView) },
152154
reloadWebView = { viewModel.reloadWebView() },
153155
shouldShowBackButton = viewModel.shouldShowBackButton,
154156
finish = { activity.handleBackBehavior() },
@@ -246,6 +248,7 @@ internal fun DefaultTopAppBar(
246248
titleTextColor: Color,
247249
showServerPicker: MutableState<Boolean>,
248250
clearCookies: () -> Unit,
251+
clearWebViewCache: () -> Unit,
249252
reloadWebView: () -> Unit,
250253
shouldShowBackButton: Boolean,
251254
finish: () -> Unit,
@@ -295,6 +298,11 @@ internal fun DefaultTopAppBar(
295298
reloadWebView()
296299
showMenu = false
297300
}
301+
MenuItem(stringResource(sf__clear_cache)) {
302+
clearWebViewCache()
303+
reloadWebView()
304+
showMenu = false
305+
}
298306
MenuItem(stringResource(sf__reload)) {
299307
reloadWebView()
300308
showMenu = false
@@ -474,6 +482,7 @@ private fun AppBarPreview() {
474482
titleTextColor = Color.Black,
475483
showServerPicker = remember { mutableStateOf(false) },
476484
clearCookies = { },
485+
clearWebViewCache = { },
477486
reloadWebView = { },
478487
shouldShowBackButton = false,
479488
finish = { },
@@ -493,6 +502,7 @@ private fun AppBarLoadingPreview() {
493502
titleTextColor = Color.Black,
494503
showServerPicker = remember { mutableStateOf(false) },
495504
clearCookies = { },
505+
clearWebViewCache = { },
496506
reloadWebView = { },
497507
shouldShowBackButton = false,
498508
finish = { },
@@ -512,6 +522,7 @@ private fun AppBarBackButtonPreview() {
512522
titleTextColor = Color.Black,
513523
showServerPicker = remember { mutableStateOf(false) },
514524
clearCookies = { },
525+
clearWebViewCache = { },
515526
reloadWebView = { },
516527
shouldShowBackButton = true,
517528
finish = { },
@@ -531,6 +542,7 @@ private fun AppBarDarkPreview() {
531542
titleTextColor = Color.White,
532543
showServerPicker = remember { mutableStateOf(false) },
533544
clearCookies = { },
545+
clearWebViewCache = { },
534546
reloadWebView = { },
535547
shouldShowBackButton = true,
536548
finish = { },
@@ -550,6 +562,7 @@ private fun BlueAppBarPreview() {
550562
titleTextColor = Color.White,
551563
showServerPicker = remember { mutableStateOf(false) },
552564
clearCookies = { },
565+
clearWebViewCache = { },
553566
reloadWebView = { },
554567
shouldShowBackButton = true,
555568
finish = { },
@@ -569,6 +582,7 @@ private fun BlueAppBarLoadingPreview() {
569582
titleTextColor = Color.White,
570583
showServerPicker = remember { mutableStateOf(false) },
571584
clearCookies = { },
585+
clearWebViewCache = { },
572586
reloadWebView = { },
573587
shouldShowBackButton = true,
574588
finish = { },
@@ -587,6 +601,7 @@ private fun CustomTextAppBarPreview() {
587601
titleTextColor = Color.White,
588602
showServerPicker = remember { mutableStateOf(false) },
589603
clearCookies = { },
604+
clearWebViewCache = { },
590605
reloadWebView = { },
591606
shouldShowBackButton = false,
592607
finish = { },
@@ -605,6 +620,7 @@ private fun CustomTextAppBarLoadingPreview() {
605620
titleTextColor = Color.White,
606621
showServerPicker = remember { mutableStateOf(false) },
607622
clearCookies = { },
623+
clearWebViewCache = { },
608624
reloadWebView = { },
609625
shouldShowBackButton = false,
610626
finish = { },
@@ -623,6 +639,7 @@ private fun LongCustomTextAppBarPreview() {
623639
titleTextColor = Color.Black,
624640
showServerPicker = remember { mutableStateOf(false) },
625641
clearCookies = { },
642+
clearWebViewCache = { },
626643
reloadWebView = { },
627644
shouldShowBackButton = true,
628645
finish = { },

libs/test/SalesforceSDKTest/src/com/salesforce/androidsdk/auth/LoginViewModelTest.kt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,12 @@
2626
*/
2727
package com.salesforce.androidsdk.auth
2828

29+
import android.webkit.WebView
2930
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
3031
import androidx.test.ext.junit.runners.AndroidJUnit4
3132
import androidx.test.platform.app.InstrumentationRegistry
33+
import io.mockk.mockk
34+
import io.mockk.verify
3235
import com.salesforce.androidsdk.R.string.oauth_display_type
3336
import com.salesforce.androidsdk.app.SalesforceSDKManager
3437
import com.salesforce.androidsdk.auth.OAuth2.getFrontdoorUrl
@@ -197,6 +200,18 @@ class LoginViewModelTest {
197200
assertEquals(unchangedUrl, viewModel.getValidServerUrl(endingSlash))
198201
}
199202

203+
@Test
204+
fun clearWebViewCache_CallsWebViewClearCache_WithTrueParameter() {
205+
// Arrange
206+
val mockWebView = mockk<WebView>(relaxed = true)
207+
208+
// Act
209+
viewModel.clearWebViewCache(mockWebView)
210+
211+
// Assert
212+
verify { mockWebView.clearCache(true) }
213+
}
214+
200215
private fun generateExpectedAuthorizationUrl(
201216
server: String,
202217
codeChallenge: String,

libs/test/SalesforceSDKTest/src/com/salesforce/androidsdk/ui/LoginViewActivityTest.kt

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,42 @@ class LoginViewActivityTest {
185185
Assert.assertTrue("Reload should be called.", reloadCalled)
186186
}
187187

188+
@Test
189+
fun topAppBar_ClearCacheButton_ClearsCacheAndReloads() {
190+
var clearCacheCalled = false
191+
var reloadCalled = false
192+
androidComposeTestRule.setContent {
193+
DefaultTopAppBarTestWrapper(
194+
clearWebViewCache = { clearCacheCalled = true },
195+
reloadWebView = { reloadCalled = true },
196+
)
197+
}
198+
199+
val backButton = androidComposeTestRule.onNodeWithContentDescription(
200+
androidComposeTestRule.activity.getString(R.string.sf__back_button_content_description)
201+
)
202+
val titleText = androidComposeTestRule.onNodeWithText(DEFAULT_URL)
203+
val menu = androidComposeTestRule.onNodeWithContentDescription(
204+
androidComposeTestRule.activity.getString(R.string.sf__more_options)
205+
)
206+
val clearCacheButton = androidComposeTestRule.onNodeWithText(
207+
androidComposeTestRule.activity.getString(R.string.sf__clear_cache)
208+
)
209+
210+
backButton.assertDoesNotExist()
211+
titleText.assertIsDisplayed()
212+
menu.assertIsDisplayed()
213+
214+
menu.performClick()
215+
clearCacheButton.assertIsDisplayed()
216+
Assert.assertFalse("Clear cache should not be called yet.", clearCacheCalled)
217+
Assert.assertFalse("Reload should not be called yet.", reloadCalled)
218+
219+
clearCacheButton.performClick()
220+
Assert.assertTrue("Clear cache should be called.", clearCacheCalled)
221+
Assert.assertTrue("Reload should be called.", reloadCalled)
222+
}
223+
188224
@Test
189225
fun topAppBar_ReloadButton_CallsReload() {
190226
var reloadCalled = false
@@ -363,13 +399,14 @@ class LoginViewActivityTest {
363399
titleTextColor: Color = Color.Black,
364400
showServerPicker: MutableState<Boolean> = remember { mutableStateOf(false) },
365401
clearCookies: () -> Unit = { },
402+
clearWebViewCache: () -> Unit = { },
366403
reloadWebView: () -> Unit = { },
367404
shouldShowBackButton: Boolean = false,
368405
finish: () -> Unit = { },
369406
) {
370407
DefaultTopAppBar(
371408
backgroundColor, titleText, titleTextColor, showServerPicker, clearCookies,
372-
reloadWebView, shouldShowBackButton, finish
409+
clearWebViewCache, reloadWebView, shouldShowBackButton, finish
373410
)
374411
}
375412

0 commit comments

Comments
 (0)