dev
dart 213 lines 6.45 KB
Raw
1 import "package:cake_wallet/entities/balance_display_mode.dart";
2 import "package:cake_wallet/entities/bitcoin_amount_display_mode.dart";
3 import "package:cake_wallet/new-ui/widgets/money/currency_symbol_text.dart";
4 import "package:cake_wallet/new-ui/widgets/money/money_settings_cubit.dart";
5 import "package:cw_core/crypto_currency.dart";
6 import "package:flutter/material.dart";
7 import "package:flutter_bloc/flutter_bloc.dart";
8 import "package:flutter_test/flutter_test.dart";
9
10 class FakeMoneySettingsCubit extends Cubit<MoneySettingsState> implements MoneySettingsCubit {
11 FakeMoneySettingsCubit(super.initialState);
12
13 void setState(MoneySettingsState state) => emit(state);
14 }
15
16 const _bitcoinMode = MoneySettingsState(
17 bitcoinAmountDisplayMode: BitcoinAmountDisplayMode.bitcoin,
18 displayMode: BalanceDisplayMode.fullBalance,
19 );
20
21 const _satoshiMode = MoneySettingsState(
22 bitcoinAmountDisplayMode: BitcoinAmountDisplayMode.satoshi,
23 displayMode: BalanceDisplayMode.fullBalance,
24 );
25
26 const _lnSatoshiMode = MoneySettingsState(
27 bitcoinAmountDisplayMode: BitcoinAmountDisplayMode.satoshiForLightning,
28 displayMode: BalanceDisplayMode.fullBalance,
29 );
30
31 /// A non-BTC currency whose symbol exceeds the 8-char cap. `raw: -1` keeps it
32 /// distinct from every real currency, so it never counts as BTC/BTCLN.
33 const _longSymbol = CryptoCurrency(title: "SUPERLONGTOKEN", name: "superlongtoken", decimals: 8);
34
35 Future<FakeMoneySettingsCubit> _pump(
36 WidgetTester tester,
37 Widget child,
38 MoneySettingsState state,
39 ) async {
40 final cubit = FakeMoneySettingsCubit(state);
41 addTearDown(cubit.close);
42 await tester.pumpWidget(
43 MaterialApp(
44 home: BlocProvider<MoneySettingsCubit>.value(
45 value: cubit,
46 child: Scaffold(body: Center(child: child)),
47 ),
48 ),
49 );
50 return cubit;
51 }
52
53 void main() {
54 group("useBaseUnit == null (follows settings)", () {
55 testWidgets("BTC in satoshi mode -> sats", (tester) async {
56 await _pump(tester, const CurrencySymbolText(CryptoCurrency.btc), _satoshiMode);
57
58 expect(find.text("sats"), findsOneWidget);
59 });
60
61 testWidgets("BTC in bitcoin mode -> BTC", (tester) async {
62 await _pump(tester, const CurrencySymbolText(CryptoCurrency.btc), _bitcoinMode);
63
64 expect(find.text("BTC"), findsOneWidget);
65 });
66
67 testWidgets("non-BTC currency ignores satoshi mode", (tester) async {
68 await _pump(tester, const CurrencySymbolText(CryptoCurrency.xmr), _satoshiMode);
69
70 expect(find.text("XMR"), findsOneWidget);
71 });
72
73 testWidgets("BTCLN in LN-satoshi mode -> sats", (tester) async {
74 await _pump(
75 tester,
76 const CurrencySymbolText(CryptoCurrency.btcln),
77 _lnSatoshiMode,
78 );
79
80 expect(find.text("sats"), findsOneWidget);
81 });
82
83 testWidgets("BTCLN in bitcoin mode -> BTC", (tester) async {
84 await _pump(tester, const CurrencySymbolText(CryptoCurrency.btcln), _bitcoinMode);
85
86 // BTCLN's title/symbol is "BTC".
87 expect(find.text("BTC"), findsOneWidget);
88 });
89 });
90
91 group("useBaseUnit == true (force base unit where supported)", () {
92 testWidgets("BTC -> sats regardless of settings", (tester) async {
93 await _pump(
94 tester,
95 const CurrencySymbolText(CryptoCurrency.btc, useBaseUnit: true),
96 _bitcoinMode, // settings say bitcoin, but override wins
97 );
98
99 expect(find.text("sats"), findsOneWidget);
100 });
101
102 testWidgets("BTCLN -> sats", (tester) async {
103 await _pump(
104 tester,
105 const CurrencySymbolText(CryptoCurrency.btcln, useBaseUnit: true),
106 _bitcoinMode,
107 );
108
109 expect(find.text("sats"), findsOneWidget);
110 });
111
112 testWidgets("non-BTC currency keeps its symbol even when forced", (tester) async {
113 await _pump(
114 tester,
115 const CurrencySymbolText(CryptoCurrency.xmr, useBaseUnit: true),
116 _satoshiMode,
117 );
118
119 expect(find.text("XMR"), findsOneWidget);
120 });
121 });
122
123 group("useBaseUnit == false (always the symbol)", () {
124 testWidgets("BTC -> BTC even in satoshi mode", (tester) async {
125 await _pump(
126 tester,
127 const CurrencySymbolText(CryptoCurrency.btc, useBaseUnit: false),
128 _satoshiMode,
129 );
130
131 expect(find.text("BTC"), findsOneWidget);
132 expect(find.text("sats"), findsNothing);
133 });
134
135 testWidgets("BTCLN -> BTC even in LN-satoshi mode", (tester) async {
136 await _pump(
137 tester,
138 const CurrencySymbolText(CryptoCurrency.btcln, useBaseUnit: false),
139 _lnSatoshiMode,
140 );
141
142 expect(find.text("BTC"), findsOneWidget);
143 expect(find.text("sats"), findsNothing);
144 });
145
146 testWidgets("non-BTC currency -> symbol", (tester) async {
147 await _pump(
148 tester,
149 const CurrencySymbolText(CryptoCurrency.xmr, useBaseUnit: false),
150 _bitcoinMode,
151 );
152
153 expect(find.text("XMR"), findsOneWidget);
154 });
155 });
156
157 group("symbol formatting", () {
158 testWidgets("caps symbols longer than 8 characters", (tester) async {
159 await _pump(
160 tester,
161 const CurrencySymbolText(_longSymbol, useBaseUnit: false),
162 _bitcoinMode,
163 );
164
165 // "SUPERLONGTOKEN" -> first 8 chars.
166 expect(find.text("SUPERLON"), findsOneWidget);
167 });
168 });
169
170 group("rebuild on cubit state change", () {
171 testWidgets("re-renders the symbol when settings change", (tester) async {
172 final cubit = await _pump(
173 tester,
174 const CurrencySymbolText(CryptoCurrency.btc),
175 _bitcoinMode,
176 );
177 expect(find.text("BTC"), findsOneWidget);
178
179 cubit.setState(_satoshiMode);
180 await tester.pump();
181
182 expect(find.text("BTC"), findsNothing);
183 expect(find.text("sats"), findsOneWidget);
184 });
185 });
186
187 group("forwarding to the inner Text", () {
188 testWidgets("passes through Text properties incl. semanticsIdentifier", (tester) async {
189 await _pump(
190 tester,
191 const CurrencySymbolText(
192 CryptoCurrency.btc,
193 maxLines: 2,
194 textAlign: TextAlign.center,
195 overflow: TextOverflow.fade,
196 style: TextStyle(fontSize: 18),
197 semanticsIdentifier: "currency-symbol",
198 ),
199 _bitcoinMode,
200 );
201
202 final text = tester.widget<Text>(
203 find.descendant(of: find.byType(CurrencySymbolText), matching: find.byType(Text)),
204 );
205
206 expect(text.maxLines, 2);
207 expect(text.textAlign, TextAlign.center);
208 expect(text.overflow, TextOverflow.fade);
209 expect(text.style?.fontSize, 18);
210 expect(text.semanticsIdentifier, "currency-symbol");
211 });
212 });
213 }