Skip to content

Commit 893649d

Browse files
kcw-gruntjosikieandhikayuana
authored
πŸš€[Release v2.12.4 20241130] Merge into Main (#285)
* πŸš€[Release v2.11.1 071024] Merge into Develop (#245) * replaced the control in PeerManager.c Signed-off-by: kcw-grunt <[email protected]> * reverted BRBitcoinAmount Signed-off-by: kcw-grunt <[email protected]> * Cleaning up the files Signed-off-by: kcw-grunt <[email protected]> * Removed Pusher remnants Signed-off-by: kcw-grunt <[email protected]> --------- Signed-off-by: kcw-grunt <[email protected]> * Added Fiat feature, and FCM for push notifications (#247) * Added fiat feature based on language user chose * added fcm for push notifications * Update PushNotificationService.kt * Added new Icon, removed duplicate fcm library, added in app messaging * Added new Icon, removed duplicate fcm library, added in app messaging * Tech debt/add af sdk (#248) * Recent newline Signed-off-by: kcw-grunt <[email protected]> * AF added Refactored cruft - AF working Signed-off-by: kcw-grunt <[email protected]> --------- Signed-off-by: kcw-grunt <[email protected]> * Techdebt/refactor brevents syncmarkers (#254) * Tech debt/add af sdk (#248) - AF working - Changed requiredActivity - Added analytics error report - test this.Activity is null or not - Bugfix - Phrase Reminder crash - added an exception handler for UserNotAuthenticatedException. - note: this should allow for the system to display the native authorization UI when needed - fixes issue - https://console.firebase.google.com/u/0/project/litewallet-beta/crashlytics/app/android:com.loafwallet/issues/09dac17241309f0e823ef597a9a82cd4 - Added dev note - remove calls to BREventManager - removed BREventManager - renamed error message - fixed Firebase Analytics event error Signed-off-by: kcw-grunt <[email protected]> * version bump update gitignore Signed-off-by: kcw-grunt <[email protected]> --------- Signed-off-by: kcw-grunt <[email protected]> * Techdebt/ fixed send issue add syncing measurements (#255) * removed unused BRSharedPreferences Signed-off-by: kcw-grunt <[email protected]> * started commenting out more Timber Signed-off-by: kcw-grunt <[email protected]> * Added more shared preferences for syncing Signed-off-by: kcw-grunt <[email protected]> * Commented out many verbose Timber logs Signed-off-by: kcw-grunt <[email protected]> * WIP Still trying to figure out the eplased time and last and start timestamps…??? I dunno Signed-off-by: kcw-grunt <[email protected]> * Moved sync measurment into the method calls Signed-off-by: kcw-grunt <[email protected]> * Debugged the install issue with send - Moved all the measurements in new methods - recalculated measure points - Added analytics - event did_complete_sync was shown! - adding a dummy file to make sure file system is set ||||WIP still verifying the JSON is present - added a blockheight label - changed the sleep time (a hack to allow the device time to refresh the view) to 100 ms from 500ms!! -WIP Why is the bundle not showing on time Signed-off-by: kcw-grunt <[email protected]> * replaces afID to first location Signed-off-by: kcw-grunt <[email protected]> * Removed redundant sync measurements Signed-off-by: kcw-grunt <[email protected]> * code bump Signed-off-by: kcw-grunt <[email protected]> --------- Signed-off-by: kcw-grunt <[email protected]> * Techdebt/test refactor cruft removal (#250) * Removed non english seed words -Refactor tests - Reset AnalyticsTests Signed-off-by: kcw-grunt <[email protected]> * Rename Bitcoinletter to Litecoinletters -added tests testLitecoinSymbolConstants testAppExternalURLConstants testFirebaseAnalyticsConstants Signed-off-by: kcw-grunt <[email protected]> --------- Signed-off-by: kcw-grunt <[email protected]> * fix: [#152] make sure using Fragment, FragmentManager and FragmentTransaction from androidx (#260) * fix: [#126] the issue came from FragmentBalanceSeedReminder.fetchSeedPhrase, so we just wrap with runCatching for now to avoid crash (#263) * fix: [#264] add null checking for BRKeyStore.removeAliasAndFiles (#270) * fix: [#265] add null checking, migrate viewpage… (#271) * fix: [WIP][#265] work in progress add null checking, migrate viewpager to viewpager2 and more * fix: [#265] finalize migration some deprecated class and implement null checking at FragmentTransactionItem * fix: dix dismiss outside FragmentTransactionDetails * πŸš€[Release v2.12.2 20241118] Merge into Develop (#272) * πŸš€[Release v2.11.1 071024] Merge into Main (#246) * replaced the control in PeerManager.c Signed-off-by: kcw-grunt <[email protected]> * reverted BRBitcoinAmount Signed-off-by: kcw-grunt <[email protected]> * Cleaning up the files Signed-off-by: kcw-grunt <[email protected]> * Removed Pusher remnants Signed-off-by: kcw-grunt <[email protected]> --------- Signed-off-by: kcw-grunt <[email protected]> * version bump Signed-off-by: kcw-grunt <[email protected]> * Removed donation button removed xml removed fragments removed references of the donation removed analytical events Signed-off-by: kcw-grunt <[email protected]> * fix: prevent activity close * code bump Signed-off-by: kcw-grunt <[email protected]> * enabled for Debug Signed-off-by: kcw-grunt <[email protected]> * fix: [#264] add null checking for BRKeyStore.removeAliasAndFiles (#270) * fix: [#265] add null checking, migrate viewpage… (#271) * fix: [WIP][#265] work in progress add null checking, migrate viewpager to viewpager2 and more * fix: [#265] finalize migration some deprecated class and implement null checking at FragmentTransactionItem * fix: dix dismiss outside FragmentTransactionDetails * code bump Signed-off-by: kcw-grunt <[email protected]> * version bump Signed-off-by: kcw-grunt <[email protected]> --------- Signed-off-by: kcw-grunt <[email protected]> Co-authored-by: andhikayuana <[email protected]> * revert minSDkVersion to 29 (#276) Signed-off-by: kcw-grunt <[email protected]> * fix: [#258] avoid OOM with cache the result of opsAll, previously called multiple times at onBindViewHolder (#277) * fix: [#258] avoid OOM with cache the result of opsAll, previously called multiple times at onBindViewHolder * chore: [#258] cleanup comment * fix: [#266] add null checking and default value based on iOS since getCurrency can produce null (#278) * fix: [#266] add null checking and default value based on iOS since getCurrency can produce null * chore: [#266] cleanup comment * fix: [#274] fixing locale on android 14 and setup test using junit & mockk (#282) * chore: [#274] initial setup test using JUnit & MockK * chore: [#274] add more test case at LocaleHelperTest * fix: [#274] fix default language from shared preferences * fix: [#274] disable language split on AAB * chore: [#274] rename method * bumped version and code * compiled the env (#284) please check @andhikayuana @josikie that you are able to compile * Users complained that recyclerView was setting to the wrong language - Polished to index to a language - bump code * chore: [#126] simplify exception handling at BRKeyStore._getData and record exception to Firebase Crashlytics (#283) --------- Signed-off-by: kcw-grunt <[email protected]> Co-authored-by: Josi Kie <[email protected]> Co-authored-by: Andhika Yuana <[email protected]>
1 parent dcb363e commit 893649d

File tree

15 files changed

+379
-213
lines changed

15 files changed

+379
-213
lines changed

β€Ž.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -102,3 +102,4 @@ app/src/litewalletDebug/google-services.json
102102
/app/debug/google-services.json
103103
/.idea/dictionaries/grunt.xml
104104
androidTestResultsUserPreferences.xml
105+
.idea/deploymentTargetSelector.xml

β€Žapp/build.gradle

+14-3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ android {
2525
buildConfig true
2626
viewBinding true
2727
}
28+
bundle {
29+
language {
30+
enableSplit = false
31+
}
32+
}
2833
assetPacks = [":install_time_asset_pack",":fast_follow_asset_pack_01"]
2934
signingConfigs {
3035
release {
@@ -61,10 +66,10 @@ android {
6166
defaultConfig {
6267
testInstrumentationRunner = 'androidx.test.runner.AndroidJUnitRunner'
6368
applicationId = 'com.loafwallet'
64-
minSdkVersion 31
69+
minSdkVersion 29
6570
targetSdkVersion 34
66-
versionCode 20241118
67-
versionName "v2.12.2"
71+
versionCode 20241130
72+
versionName "v2.12.4"
6873
multiDexEnabled true
6974
archivesBaseName = "${versionName}(${versionCode})"
7075

@@ -78,8 +83,10 @@ android {
7883
// libraries Gradle should build and package with your APK.
7984
abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
8085
}
86+
ndkVersion "25.1.8937393"
8187
externalNativeBuild {
8288
cmake {
89+
version "3.22.1"
8390
arguments "-DANDROID_TOOLCHAIN=clang"
8491
}
8592
}
@@ -365,6 +372,10 @@ dependencies {
365372

366373
// Get the latest version from https://mvnrepository.com/artifact/com.appsflyer/af-android-sdk
367374
implementation 'com.appsflyer:af-android-sdk:6.15.1'
375+
376+
//test
377+
testImplementation "io.mockk:mockk:1.13.13"
378+
testImplementation 'junit:junit:4.13.2'
368379
}
369380

370381

β€Žapp/src/main/java/com/breadwallet/entities/IntroLanguageResource.kt

+6-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ class IntroLanguageResource {
77
private val EUR: String = "EUR"
88
private val RMB: String = "RMB"
99
private val JPY: String = "JPY"
10-
fun loadResources() : Array<IntroLanguage>{
11-
return arrayOf<IntroLanguage> (
10+
fun loadResources(): Array<IntroLanguage> {
11+
return arrayOf<IntroLanguage>(
1212
IntroLanguage(
1313
Language.ENGLISH.code,
1414
Language.ENGLISH.title,
@@ -115,4 +115,8 @@ class IntroLanguageResource {
115115
)
116116
)
117117
}
118+
119+
fun findLanguageIndex(language: Language): Int {
120+
return loadResources().map { intro -> intro.lang }.indexOf(language)
121+
}
118122
}

β€Žapp/src/main/java/com/breadwallet/presenter/activities/intro/IntroActivity.java

+7-3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import android.content.Intent;
77
import android.graphics.Point;
88
import android.os.Bundle;
9+
import android.os.Handler;
910
import android.util.Log;
1011
import android.view.View;
1112
import android.widget.Button;
@@ -14,13 +15,12 @@
1415
import androidx.recyclerview.widget.LinearLayoutManager;
1516
import androidx.recyclerview.widget.RecyclerView;
1617

17-
import com.appsflyer.AppsFlyerLib;
1818
import com.breadwallet.entities.IntroLanguageResource;
19+
import com.breadwallet.entities.Language;
1920
import com.breadwallet.presenter.activities.SetPinActivity;
2021
import com.breadwallet.presenter.entities.PartnerNames;
2122
import com.breadwallet.tools.adapter.CountryLanguageAdapter;
2223
import com.breadwallet.tools.util.LocaleHelper;
23-
import com.google.android.material.snackbar.Snackbar;
2424
//import com.breadwallet.BuildConfig;
2525
import com.breadwallet.R;
2626
import com.breadwallet.presenter.activities.BreadActivity;
@@ -78,6 +78,10 @@ protected void onCreate(Bundle savedInstanceState) {
7878
countryLanguageAdapter = new CountryLanguageAdapter(this, introLanguageResource.loadResources());
7979
listLangRecyclerView.setAdapter(countryLanguageAdapter);
8080

81+
Language currentLanguage = LocaleHelper.Companion.getInstance().getCurrentLocale();
82+
int currentIndex = introLanguageResource.findLanguageIndex(currentLanguage);
83+
countryLanguageAdapter.updateCenterPosition(currentIndex);
84+
new Handler().post(() -> listLangRecyclerView.scrollToPosition(currentIndex));
8185
listLangRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
8286
@Override
8387
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
@@ -90,12 +94,12 @@ public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newStat
9094
countryLanguageAdapter.updateCenterPosition(centerPosition);
9195
description.setText(countryLanguageAdapter.selectedDesc());
9296
showDialogForItem(countryLanguageAdapter.selectedMessage());
97+
listLangRecyclerView.smoothScrollToPosition(centerPosition);
9398
}
9499
}
95100
}
96101

97102
});
98-
99103
listLangRecyclerView.setLayoutManager(layoutManager);
100104

101105
setListeners();

β€Žapp/src/main/java/com/breadwallet/tools/adapter/TransactionListAdapter.java

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
package com.breadwallet.tools.adapter;
2+
23
import android.app.Activity;
34
import android.content.Context;
45
import android.util.TypedValue;
@@ -45,6 +46,7 @@ public class TransactionListAdapter extends RecyclerView.Adapter<RecyclerView.Vi
4546
private final int txResId;
4647
private final int syncingResId;
4748
private final int promptResId;
49+
private final String cachedOpsAll;
4850
private List<TxItem> backUpFeed;
4951
private List<TxItem> itemFeed;
5052
private final int txType = 0;
@@ -58,6 +60,9 @@ public TransactionListAdapter(Context mContext, List<TxItem> items) {
5860
this.syncingResId = R.layout.syncing_item;
5961
this.promptResId = R.layout.prompt_item;
6062
this.mContext = mContext;
63+
64+
cachedOpsAll = Utils.fetchPartnerKey(mContext, PartnerNames.OPSALL);
65+
6166
items = new ArrayList<>();
6267
init(items);
6368
}
@@ -179,8 +184,7 @@ private void setTexts(final TxHolder convertView, int position) {
179184

180185
Set<String> outputAddressSet = new HashSet<String>(Arrays.asList(item.getTo()));
181186

182-
final String opsString = Utils.fetchPartnerKey(mContext, PartnerNames.OPSALL);
183-
List<String> opsList = new ArrayList<String>(Arrays.asList(opsString.split(",")));
187+
List<String> opsList = new ArrayList<String>(Arrays.asList(cachedOpsAll.split(",")));
184188
Set<String> opsSet = new HashSet<>();
185189
opsSet.addAll(opsList);
186190
List<String> outputAddresses = outputAddressSet.stream().filter(element -> !opsSet.contains(element)).collect(Collectors.toList());

β€Žapp/src/main/java/com/breadwallet/tools/security/BRKeyStore.java

+28-39
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import com.breadwallet.tools.util.TypesConverter;
2828
import com.breadwallet.tools.util.Utils;
2929
import com.breadwallet.wallet.BRWalletManager;
30+
import com.google.firebase.crashlytics.FirebaseCrashlytics;
3031
import com.platform.entities.WalletInfo;
3132
import com.platform.tools.KVStoreManager;
3233

@@ -36,6 +37,7 @@
3637
import java.io.FileOutputStream;
3738
import java.io.IOException;
3839
import java.io.UnsupportedEncodingException;
40+
import java.security.GeneralSecurityException;
3941
import java.security.InvalidAlgorithmParameterException;
4042
import java.security.InvalidKeyException;
4143
import java.security.KeyStore;
@@ -239,8 +241,11 @@ private synchronized static byte[] _getData(final Context context, String alias,
239241
if (encryptedData != null) {
240242
//new format data is present, good
241243
byte[] iv = retrieveEncryptedData(context, alias_iv);
242-
if (iv == null)
243-
throw new NullPointerException("iv is missing when data isn't: " + alias);
244+
if (iv == null) {
245+
NullPointerException exception = new NullPointerException("iv is missing when data isn't: " + alias);
246+
FirebaseCrashlytics.getInstance().recordException(exception);
247+
return null;
248+
}
244249
Cipher outCipher;
245250

246251
outCipher = Cipher.getInstance(NEW_CIPHER_ALGORITHM);
@@ -251,8 +256,9 @@ private synchronized static byte[] _getData(final Context context, String alias,
251256
return decryptedData;
252257
}
253258
} catch (IllegalBlockSizeException | BadPaddingException e) {
254-
Timber.e(e);
255-
throw new RuntimeException("failed to decrypt data: " + e.getMessage());
259+
Timber.e(e, "failed to decrypt data: " + alias);
260+
FirebaseCrashlytics.getInstance().recordException(e);
261+
return null;
256262
}
257263
}
258264
//no new format data, get the old one and migrate it to the new format
@@ -264,7 +270,9 @@ private synchronized static byte[] _getData(final Context context, String alias,
264270
if (!fileExists) {
265271
return null;/* file also not there, fine then */
266272
}
267-
Timber.e(new BRKeystoreErrorException("file is present but the key is gone: " + alias));
273+
BRKeystoreErrorException exception = new BRKeystoreErrorException("file is present but the key is gone: " + alias);
274+
Timber.e(exception);
275+
FirebaseCrashlytics.getInstance().recordException(exception);
268276
return null;
269277
}
270278

@@ -275,12 +283,15 @@ private synchronized static byte[] _getData(final Context context, String alias,
275283
removeAliasAndFiles(keyStore, alias, context);
276284
//report it if one exists and not the other.
277285
if (ivExists != aliasExists) {
278-
Timber.e(new BRKeystoreErrorException("alias or iv isn't on the disk: " + alias + ", aliasExists:" + aliasExists));
279-
return null;
286+
BRKeystoreErrorException exception = new BRKeystoreErrorException("alias or iv isn't on the disk: " + alias + ", aliasExists:" + aliasExists);
287+
Timber.e(exception);
288+
FirebaseCrashlytics.getInstance().recordException(exception);
280289
} else {
281-
Timber.e(new BRKeystoreErrorException("!ivExists && !aliasExists: " + alias));
282-
return null;
290+
BRKeystoreErrorException exception = new BRKeystoreErrorException("!ivExists && !aliasExists: " + alias);
291+
Timber.e(exception);
292+
FirebaseCrashlytics.getInstance().recordException(exception);
283293
}
294+
return null;
284295
}
285296

286297
byte[] iv = readBytesFromFile(getFilePath(alias_iv, context));
@@ -309,36 +320,14 @@ private synchronized static byte[] _getData(final Context context, String alias,
309320
storeEncryptedData(context, encryptedData, alias);
310321
return result;
311322

312-
} catch (InvalidKeyException e) {
313-
if (e instanceof UserNotAuthenticatedException) {
314-
/** user not authenticated, ask the system for authentication */
315-
Timber.e(e, "timber:_getData: showAuthenticationScreen: %s", alias);
316-
showAuthenticationScreen(context, request_code, alias);
317-
throw (UserNotAuthenticatedException) e;
318-
} else {
319-
Timber.e(e, "timber:_getData: InvalidKeyException");
320-
if (e instanceof KeyPermanentlyInvalidatedException)
321-
showKeyInvalidated(context);
322-
throw new UserNotAuthenticatedException(); //just to not go any further
323-
}
324-
} catch (IOException | CertificateException | KeyStoreException e) {
325-
/** keyStore.load(null) threw the Exception, meaning the keystore is unavailable */
326-
Timber.d(e, "_getData: keyStore.load(null) threw the Exception, meaning the keystore is unavailable");
327-
if (e instanceof FileNotFoundException) {
328-
Timber.e(new RuntimeException("the key is present but the phrase on the disk no", e), "_getData: File not found exception");
329-
throw new RuntimeException(e.getMessage());
330-
} else {
331-
Timber.e(e);
332-
throw new RuntimeException(e.getMessage());
333-
}
334-
} catch (UnrecoverableKeyException | NoSuchAlgorithmException | NoSuchPaddingException |
335-
InvalidAlgorithmParameterException e) {
336-
/** if for any other reason the keystore fails, crash! */
337-
Timber.e(e, "timber:getData: error");
338-
throw new RuntimeException(e.getMessage());
339-
} catch (BadPaddingException | IllegalBlockSizeException | NoSuchProviderException e) {
340-
Timber.e(e);
341-
throw new RuntimeException(e.getMessage());
323+
} catch (UserNotAuthenticatedException e) {
324+
Timber.e(e, "timber:_getData: showAuthenticationScreen: %s", alias);
325+
showAuthenticationScreen(context, request_code, alias);
326+
throw e;
327+
} catch (GeneralSecurityException | IOException e) {
328+
Timber.e(e, "timber:getData: error retrieving");
329+
FirebaseCrashlytics.getInstance().recordException(e);
330+
throw new IllegalStateException(e);
342331
} finally {
343332
lock.unlock();
344333
}

β€Žapp/src/main/java/com/breadwallet/tools/util/LocaleHelper.kt

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package com.breadwallet.tools.util
33
import android.content.Context
44
import android.content.SharedPreferences
55
import android.os.Build
6+
import androidx.appcompat.app.AppCompatDelegate
7+
import androidx.core.os.LocaleListCompat
68
import androidx.preference.PreferenceManager
79
import com.breadwallet.entities.Language
810
import java.util.*
@@ -34,6 +36,8 @@ class LocaleHelper private constructor() {
3436
Locale.setDefault(locale)
3537
val config = context.resources.configuration
3638
config.setLocale(locale)
39+
val localeList = LocaleListCompat.forLanguageTags(language.code)
40+
AppCompatDelegate.setApplicationLocales(localeList)
3741
return context.createConfigurationContext(config)
3842
}
3943

β€Žapp/src/main/java/com/breadwallet/tools/util/Utils.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -303,10 +303,13 @@ else if (name == PartnerNames.PUSHERSTAGING) {
303303
/// Description: 1715876807
304304
public static long tieredOpsFee(Context app, long sendAmount) {
305305

306+
double doubleRate = 83.000;
306307
double sendAmountDouble = new Double(String.valueOf(sendAmount));
307308
String usIso = Currency.getInstance(new Locale("en", "US")).getCurrencyCode();
308309
CurrencyEntity currency = CurrencyDataSource.getInstance(app).getCurrencyByIso(usIso);
309-
double doubleRate = currency.rate;
310+
if (currency != null) {
311+
doubleRate = currency.rate;
312+
}
310313
double usdInLTC = sendAmountDouble * doubleRate / 100_000_000.0;
311314
usdInLTC = Math.floor(usdInLTC * 100) / 100;
312315

β€Žapp/src/main/res/layout/activity_intro.xml

+4-4
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,13 @@
4343
<androidx.recyclerview.widget.RecyclerView
4444
android:id="@+id/language_list"
4545
android:layout_width="200dp"
46-
android:layout_height="55dp"
46+
android:layout_height="70dp"
4747
android:layout_marginTop="96dp"
48-
android:paddingBottom="14dp"
48+
android:background="@drawable/lang_rounded_background"
4949
android:paddingStart="10dp"
50+
android:paddingTop="18dp"
5051
android:paddingEnd="10dp"
51-
android:paddingTop="14dp"
52-
android:background="@drawable/lang_rounded_background"
52+
android:paddingBottom="17dp"
5353
app:layout_constraintEnd_toEndOf="parent"
5454
app:layout_constraintHorizontal_bias="0.497"
5555
app:layout_constraintStart_toStartOf="parent"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.breadwallet.tools.util
2+
3+
import android.content.Context
4+
import com.breadwallet.entities.Language
5+
import io.mockk.mockk
6+
import org.junit.Assert.assertEquals
7+
import org.junit.Assert.assertFalse
8+
import org.junit.Assert.assertTrue
9+
import org.junit.Test
10+
11+
class LocaleHelperTest {
12+
13+
@Test
14+
fun `given LocaleHelper instance, then should validate default value`() {
15+
val context: Context = mockk(relaxed = true)
16+
17+
LocaleHelper.init(context)
18+
19+
val currentLocale = LocaleHelper.instance.currentLocale
20+
21+
assertTrue(currentLocale == Language.ENGLISH)
22+
assertEquals("en", currentLocale.code)
23+
assertEquals("English", currentLocale.title)
24+
assertEquals("Select language", currentLocale.desc)
25+
}
26+
27+
@Test
28+
fun `getLocale invoked, should return Locale object`() {
29+
val localeIndonesian = LocaleHelper.getLocale(Language.INDONESIAN)
30+
31+
assertEquals("id", localeIndonesian.language)
32+
33+
val localeChineseSimplified = LocaleHelper.getLocale(Language.CHINESE_SIMPLIFIED)
34+
35+
assertEquals("zh", localeChineseSimplified.language)
36+
assertEquals("CN", localeChineseSimplified.country)
37+
}
38+
39+
@Test
40+
fun `setLocaleIfNeeded invoked, should update current locale`() {
41+
val context: Context = mockk(relaxed = true)
42+
LocaleHelper.init(context)
43+
44+
val currentLocale = LocaleHelper.instance.currentLocale
45+
assertTrue(currentLocale == Language.ENGLISH)
46+
47+
var changed = LocaleHelper.instance.setLocaleIfNeeded(Language.INDONESIAN)
48+
assertTrue(changed)
49+
50+
changed = LocaleHelper.instance.setLocaleIfNeeded(Language.INDONESIAN)
51+
assertFalse(changed)
52+
}
53+
}

β€Žbuild.gradle

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ buildscript {
1010
// in below line we are adding configurations to our project.
1111
configurations.all {
1212
// in below line we are adding strategy for each dependency and requesting the details
13-
resolutionStrategy.eachDependency {DependencyResolveDetails details ->
13+
resolutionStrategy.eachDependency {details ->
1414
// on below line we are getting to see the details using requested.
1515
def requested = details.requested
1616
// in below line we are requesting a group.
@@ -29,7 +29,7 @@ buildscript {
2929

3030
// NOTE: Do not place your application dependencies here; they belong
3131
// in the individual module build.gradle files
32-
classpath 'com.google.gms:google-services:4.4.0'
32+
classpath 'com.google.gms:google-services:4.4.2'
3333

3434
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.9'
3535

β€Žgradle/wrapper/gradle-wrapper.jar

-6.24 KB
Binary file not shown.

0 commit comments

Comments
Β (0)