Merge pull request #197 from cypherstack/desktop

fix previous failing widget tests
This commit is contained in:
julian-CStack 2022-11-02 12:41:09 -06:00 committed by GitHub
commit 2954bc7846
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 1180 additions and 484 deletions

View file

@ -0,0 +1,3 @@
<svg width="12" height="7" viewBox="0 0 12 7" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11 6L6 1L1 6" stroke="#8E9192" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 208 B

View file

@ -1,17 +1,14 @@
import 'package:flutter/material.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/pages/stack_privacy_calls.dart';
import 'package:stackwallet/pages_desktop_specific/home/advanced_settings/stack_privacy_dialog.dart';
import 'package:stackwallet/providers/global/prefs_provider.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/widgets/custom_buttons/draggable_switch_button.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart';
import '../../../pages/settings_views/global_settings_view/advanced_views/debug_view.dart';
import '../../../providers/global/prefs_provider.dart';
import '../../../widgets/custom_buttons/draggable_switch_button.dart';
class AdvancedSettings extends ConsumerStatefulWidget {
const AdvancedSettings({Key? key}) : super(key: key);
@ -109,63 +106,69 @@ class _AdvancedSettings extends ConsumerState<AdvancedSettings> {
),
/// TODO: Make a dialog popup
Padding(
padding: const EdgeInsets.all(10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Stack Experience",
style:
STextStyles.desktopTextExtraSmall(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textDark),
textAlign: TextAlign.left,
),
Text(
"Easy Crypto",
style: STextStyles.desktopTextExtraExtraSmall(
context),
),
],
),
const StackPrivacyButton(),
],
),
),
const Padding(
padding: EdgeInsets.all(10.0),
child: Divider(
thickness: 0.5,
),
),
/// TODO: Make a dialog popup
Padding(
padding: const EdgeInsets.all(10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Debug info",
style: STextStyles.desktopTextExtraSmall(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textDark),
textAlign: TextAlign.left,
),
ShowLogsButton(),
],
),
),
Consumer(builder: (_, ref, __) {
final externalCalls = ref.watch(
prefsChangeNotifierProvider
.select((value) => value.externalCalls),
);
return Padding(
padding: const EdgeInsets.all(10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Stack Experience",
style:
STextStyles.desktopTextExtraSmall(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textDark),
textAlign: TextAlign.left,
),
Text(
externalCalls ? "Easy crypto" : "Incognito",
style: STextStyles.desktopTextExtraExtraSmall(
context),
),
],
),
const StackPrivacyButton(),
],
),
);
}),
],
),
const Padding(
padding: EdgeInsets.all(10.0),
child: Divider(
thickness: 0.5,
),
),
/// TODO: Make a dialog popup
Padding(
padding: const EdgeInsets.all(10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"Debug info",
style: STextStyles.desktopTextExtraSmall(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textDark),
textAlign: TextAlign.left,
),
const ShowLogsButton(),
],
),
),
],
),
),
@ -181,6 +184,17 @@ class StackPrivacyButton extends ConsumerWidget {
}) : super(key: key);
@override
Widget build(BuildContext context, WidgetRef ref) {
Future<void> changePrivacySettings() async {
await showDialog<dynamic>(
context: context,
useSafeArea: false,
barrierDismissible: true,
builder: (context) {
return const StackPrivacyDialog();
},
);
}
return SizedBox(
width: 84,
height: 37,
@ -189,10 +203,11 @@ class StackPrivacyButton extends ConsumerWidget {
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context),
onPressed: () {
Navigator.of(context).pushNamed(
StackPrivacyCalls.routeName,
arguments: false,
);
// Navigator.of(context).pushNamed(
// StackPrivacyCalls.routeName,
// arguments: false,
// );
changePrivacySettings();
},
child: Text(
"Change",
@ -208,6 +223,18 @@ class ShowLogsButton extends ConsumerWidget {
const ShowLogsButton({
Key? key,
}) : super(key: key);
Future<void> viewDebugLogs() async {
// await showDialog<dynamic>(
// context: context,
// useSafeArea: false,
// barrierDismissible: true,
// builder: (context) {
// return const DebugInfoDialog();
// },
// );
}
@override
Widget build(BuildContext context, WidgetRef ref) {
return SizedBox(
@ -218,7 +245,8 @@ class ShowLogsButton extends ConsumerWidget {
.extension<StackColors>()!
.getPrimaryEnabledButtonColor(context),
onPressed: () {
Navigator.of(context).pushNamed(DebugView.routeName);
//
viewDebugLogs();
},
child: Text(
"Show logs",

View file

@ -0,0 +1,437 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/svg.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog.dart';
import 'package:stackwallet/widgets/desktop/desktop_dialog_close_button.dart';
import 'package:stackwallet/widgets/desktop/primary_button.dart';
import 'package:stackwallet/widgets/desktop/secondary_button.dart';
import '../../../hive/db.dart';
import '../../../providers/global/prefs_provider.dart';
import '../../../providers/global/price_provider.dart';
import '../../../services/exchange/exchange_data_loading_service.dart';
import '../../../utilities/assets.dart';
import '../../../utilities/constants.dart';
import '../../../utilities/theme/stack_colors.dart';
import '../../../utilities/util.dart';
import '../../../widgets/rounded_white_container.dart';
class StackPrivacyDialog extends ConsumerStatefulWidget {
const StackPrivacyDialog({Key? key}) : super(key: key);
@override
ConsumerState<StackPrivacyDialog> createState() => _StackPrivacyDialog();
}
class _StackPrivacyDialog extends ConsumerState<StackPrivacyDialog> {
late final bool isDesktop;
late bool isEasy;
late bool infoToggle;
@override
void initState() {
isDesktop = Util.isDesktop;
isEasy = ref.read(prefsChangeNotifierProvider).externalCalls;
infoToggle = isEasy;
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return DesktopDialog(
maxHeight: 650,
maxWidth: 600,
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.all(32),
child: Text(
"Choose Your Stack Experience",
style: STextStyles.desktopH3(context),
textAlign: TextAlign.center,
),
),
const DesktopDialogCloseButton(),
],
),
const SizedBox(
height: 35,
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 32),
child: PrivacyToggle(
externalCallsEnabled: isEasy,
onChanged: (externalCalls) {
isEasy = externalCalls;
setState(() {
infoToggle = isEasy;
});
},
),
),
Padding(
padding: const EdgeInsets.all(32.0),
child: RoundedWhiteContainer(
borderColor: Theme.of(context)
.extension<StackColors>()!
.textFieldDefaultBG,
child: Center(
child: RichText(
textAlign: TextAlign.left,
text: TextSpan(
style: isDesktop
? STextStyles.desktopTextExtraExtraSmall(context)
: STextStyles.label(context).copyWith(
fontSize: 12.0,
),
children: infoToggle
? [
const TextSpan(
text:
"Exchange data preloaded for a seamless experience."),
const TextSpan(
text:
"\n\nCoinGecko enabled: (24 hour price change shown in-app, total wallet value shown in USD or other currency)."),
TextSpan(
text: "\n\nRecommended for most crypto users.",
style: isDesktop
? STextStyles.desktopTextExtraExtraSmall600(
context)
: TextStyle(
color: Theme.of(context)
.extension<StackColors>()!
.textDark,
fontWeight: FontWeight.w600,
),
),
]
: [
const TextSpan(
text:
"Exchange data not preloaded (slower experience)."),
const TextSpan(
text:
"\n\nCoinGecko disabled (price changes not shown, no wallet value shown in other currencies)."),
TextSpan(
text:
"\n\nRecommended for the privacy conscious.",
style: isDesktop
? STextStyles.desktopTextExtraExtraSmall600(
context)
: TextStyle(
color: Theme.of(context)
.extension<StackColors>()!
.textDark,
fontWeight: FontWeight.w600,
),
),
],
),
),
),
),
),
// const Spacer(),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 32),
child: Row(
children: [
Expanded(
child: SecondaryButton(
label: "Cancel",
onPressed: () {},
),
),
const SizedBox(
width: 16,
),
Expanded(
child: PrimaryButton(
label: "Save",
onPressed: () {
ref.read(prefsChangeNotifierProvider).externalCalls =
isEasy;
DB.instance
.put<dynamic>(
boxName: DB.boxNamePrefs,
key: "externalCalls",
value: isEasy)
.then((_) {
if (isEasy) {
unawaited(ExchangeDataLoadingService().loadAll(ref));
ref
.read(priceAnd24hChangeNotifierProvider)
.start(true);
}
});
if (isDesktop) {
Navigator.pop(context);
}
},
),
)
],
),
),
],
),
);
}
}
class PrivacyToggle extends StatefulWidget {
const PrivacyToggle({
Key? key,
required this.externalCallsEnabled,
this.onChanged,
}) : super(key: key);
final bool externalCallsEnabled;
final void Function(bool)? onChanged;
@override
State<PrivacyToggle> createState() => _PrivacyToggleState();
}
class _PrivacyToggleState extends State<PrivacyToggle> {
late bool externalCallsEnabled;
late final bool isDesktop;
@override
void initState() {
isDesktop = Util.isDesktop;
// initial toggle state
externalCallsEnabled = widget.externalCallsEnabled;
super.initState();
}
@override
Widget build(BuildContext context) {
return Row(
children: [
Expanded(
child: RawMaterialButton(
elevation: 0,
hoverElevation: 0,
fillColor: Theme.of(context).extension<StackColors>()!.popupBG,
shape: RoundedRectangleBorder(
side: !externalCallsEnabled
? BorderSide.none
: BorderSide(
color: Theme.of(context)
.extension<StackColors>()!
.infoItemIcons,
width: 2,
),
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius * 2,
),
),
onPressed: () {
setState(() {
// update toggle state
externalCallsEnabled = true;
});
// call callback with newly set value
widget.onChanged?.call(externalCallsEnabled);
},
child: Padding(
padding: const EdgeInsets.all(
12,
),
child: Stack(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
if (isDesktop)
const SizedBox(
height: 10,
),
SvgPicture.asset(
Assets.svg.personaEasy,
width: 120,
height: 120,
),
if (isDesktop)
const SizedBox(
height: 12,
),
Center(
child: Text(
"Easy Crypto",
style: isDesktop
? STextStyles.desktopTextSmall(context)
: STextStyles.label700(context),
),
),
Center(
child: Text(
"Recommended",
style: isDesktop
? STextStyles.desktopTextExtraExtraSmall(context)
: STextStyles.label(context),
),
),
if (isDesktop)
const SizedBox(
height: 12,
),
],
),
if (externalCallsEnabled)
Positioned(
top: 4,
right: 4,
child: SvgPicture.asset(
Assets.svg.checkCircle,
width: 20,
height: 20,
color: Theme.of(context)
.extension<StackColors>()!
.infoItemIcons,
),
),
if (!externalCallsEnabled)
Positioned(
top: 4,
right: 4,
child: Container(
width: 20,
height: 20,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(1000),
color: Theme.of(context)
.extension<StackColors>()!
.textFieldDefaultBG,
),
),
),
],
),
),
),
),
const SizedBox(
width: 16,
),
Expanded(
child: RawMaterialButton(
elevation: 0,
hoverElevation: 0,
fillColor: Theme.of(context).extension<StackColors>()!.popupBG,
shape: RoundedRectangleBorder(
side: externalCallsEnabled
? BorderSide.none
: BorderSide(
color: Theme.of(context)
.extension<StackColors>()!
.infoItemIcons,
width: 2,
),
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius * 2,
),
),
onPressed: () {
setState(() {
// update toggle state
externalCallsEnabled = false;
});
// call callback with newly set value
widget.onChanged?.call(externalCallsEnabled);
},
child: Padding(
padding: const EdgeInsets.all(
12,
),
child: Stack(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
if (isDesktop)
const SizedBox(
height: 10,
),
SvgPicture.asset(
Assets.svg.personaIncognito,
width: 120,
height: 120,
),
if (isDesktop)
const SizedBox(
height: 12,
),
Center(
child: Text(
"Incognito",
style: isDesktop
? STextStyles.desktopTextSmall(context)
: STextStyles.label700(context),
),
),
Center(
child: Text(
"Privacy conscious",
style: isDesktop
? STextStyles.desktopTextExtraExtraSmall(context)
: STextStyles.label(context),
),
),
if (isDesktop)
const SizedBox(
height: 12,
),
],
),
if (!externalCallsEnabled)
Positioned(
top: 4,
right: 4,
child: SvgPicture.asset(
Assets.svg.checkCircle,
width: 20,
height: 20,
color: Theme.of(context)
.extension<StackColors>()!
.infoItemIcons,
),
),
if (externalCallsEnabled)
Positioned(
top: 4,
right: 4,
child: Container(
width: 20,
height: 20,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(1000),
color: Theme.of(context)
.extension<StackColors>()!
.textFieldDefaultBG,
),
),
),
],
),
),
),
),
],
);
}
}

View file

@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:stackwallet/pages_desktop_specific/home/settings_menu/advanced_settings.dart';
import 'package:stackwallet/pages_desktop_specific/home/advanced_settings/advanced_settings.dart';
import 'package:stackwallet/pages_desktop_specific/home/settings_menu/appearance_settings.dart';
import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart';
import 'package:stackwallet/pages_desktop_specific/home/settings_menu/currency_settings.dart';

View file

@ -1,10 +1,18 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:stackwallet/models/contact.dart';
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/address_book_address_chooser/sub_widgets/contact_list_item.dart';
import 'package:stackwallet/providers/global/address_book_service_provider.dart';
import 'package:stackwallet/utilities/assets.dart';
import 'package:stackwallet/utilities/constants.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/text_styles.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
import 'package:stackwallet/widgets/stack_text_field.dart';
import 'package:stackwallet/widgets/textfield_icon_button.dart';
class AddressBookAddressChooser extends StatefulWidget {
const AddressBookAddressChooser({
@ -20,6 +28,12 @@ class AddressBookAddressChooser extends StatefulWidget {
}
class _AddressBookAddressChooserState extends State<AddressBookAddressChooser> {
late final bool isDesktop;
late final TextEditingController _searchController;
late final FocusNode searchFieldFocusNode;
String _searchTerm = "";
int _compareContactFavorite(Contact a, Contact b) {
if (a.isFavorite && b.isFavorite) {
return 0;
@ -43,29 +57,128 @@ class _AddressBookAddressChooserState extends State<AddressBookAddressChooser> {
return favorites;
}
List<Contact> filter(List<Contact> contacts) {
List<Contact> filter(List<Contact> contacts, String searchTerm) {
if (widget.coin != null) {
contacts.removeWhere(
(e) => e.addresses.where((a) => a.coin == widget.coin!).isEmpty);
}
contacts.retainWhere((e) => _matches(searchTerm, e));
if (contacts.length < 2) {
return contacts;
}
// redundant due to pullOutFavorites?
contacts.sort(_compareContactFavorite);
// TODO: other filtering?
return contacts;
}
bool _matches(String term, Contact contact) {
final text = term.toLowerCase();
if (contact.name.toLowerCase().contains(text)) {
return true;
}
for (int i = 0; i < contact.addresses.length; i++) {
if (contact.addresses[i].label.toLowerCase().contains(text) ||
contact.addresses[i].coin.name.toLowerCase().contains(text) ||
contact.addresses[i].coin.prettyName.toLowerCase().contains(text) ||
contact.addresses[i].coin.ticker.toLowerCase().contains(text) ||
contact.addresses[i].address.toLowerCase().contains(text)) {
return true;
}
}
return false;
}
@override
void initState() {
isDesktop = Util.isDesktop;
searchFieldFocusNode = FocusNode();
_searchController = TextEditingController();
super.initState();
}
@override
void dispose() {
_searchController.dispose();
searchFieldFocusNode.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Column(
children: [
// search field
const TextField(),
Padding(
padding: const EdgeInsets.symmetric(
horizontal: 32,
),
child: ClipRRect(
borderRadius: BorderRadius.circular(
Constants.size.circularBorderRadius,
),
child: TextField(
autocorrect: !isDesktop,
enableSuggestions: !isDesktop,
controller: _searchController,
focusNode: searchFieldFocusNode,
onChanged: (value) {
setState(() {
_searchTerm = value;
});
},
style: isDesktop
? STextStyles.desktopTextExtraSmall(context).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textFieldActiveText,
height: 1.8,
)
: STextStyles.field(context),
decoration: standardInputDecoration(
"Search",
searchFieldFocusNode,
context,
desktopMed: isDesktop,
).copyWith(
prefixIcon: Padding(
padding: EdgeInsets.symmetric(
horizontal: isDesktop ? 12 : 10,
vertical: isDesktop ? 18 : 16,
),
child: SvgPicture.asset(
Assets.svg.search,
width: isDesktop ? 20 : 16,
height: isDesktop ? 20 : 16,
),
),
suffixIcon: _searchController.text.isNotEmpty
? Padding(
padding: const EdgeInsets.only(right: 0),
child: UnconstrainedBox(
child: Row(
children: [
TextFieldIconButton(
child: const XIcon(),
onTap: () async {
setState(() {
_searchController.text = "";
_searchTerm = "";
});
},
),
],
),
),
)
: null,
),
),
),
),
const SizedBox(
height: 16,
),
@ -83,7 +196,7 @@ class _AddressBookAddressChooserState extends State<AddressBookAddressChooser> {
.select((value) => value.contacts))
.toList();
contacts = filter(contacts);
contacts = filter(contacts, _searchTerm);
final favorites = pullOutFavorites(contacts);
@ -96,6 +209,8 @@ class _AddressBookAddressChooserState extends State<AddressBookAddressChooser> {
itemBuilder: (context, index) {
if (index == 0) {
return Padding(
key: const Key(
"addressBookCAddressChooserFavoritesHeaderItemKey"),
padding: const EdgeInsets.only(
bottom: 10,
),
@ -108,12 +223,14 @@ class _AddressBookAddressChooserState extends State<AddressBookAddressChooser> {
} else if (index <= favorites.length) {
final id = favorites[index - 1].id;
return ContactListItem(
key: Key("contactCard_${id}_key"),
key: Key("contactContactListItem_${id}_key"),
contactId: id,
filterByCoin: widget.coin,
);
} else if (index == favorites.length + 1) {
return Padding(
key: const Key(
"addressBookCAddressChooserAllContactsHeaderItemKey"),
padding: const EdgeInsets.symmetric(
vertical: 10,
),
@ -126,7 +243,7 @@ class _AddressBookAddressChooserState extends State<AddressBookAddressChooser> {
} else {
final id = contacts[index - favorites.length - 1].id;
return ContactListItem(
key: Key("contactCard_${id}_key"),
key: Key("contactContactListItem_${id}_key"),
contactId: id,
filterByCoin: widget.coin,
);

View file

@ -10,7 +10,7 @@ import 'package:stackwallet/widgets/expandable.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart';
import 'package:stackwallet/widgets/wallet_info_row/sub_widgets/wallet_info_row_coin_icon.dart';
class ContactListItem extends ConsumerWidget {
class ContactListItem extends ConsumerStatefulWidget {
const ContactListItem({
Key? key,
required this.contactId,
@ -21,7 +21,24 @@ class ContactListItem extends ConsumerWidget {
final Coin? filterByCoin;
@override
Widget build(BuildContext context, WidgetRef ref) {
ConsumerState<ContactListItem> createState() => _ContactListItemState();
}
class _ContactListItemState extends ConsumerState<ContactListItem> {
late final String contactId;
late final Coin? filterByCoin;
ExpandableState _state = ExpandableState.collapsed;
@override
void initState() {
contactId = widget.contactId;
filterByCoin = widget.filterByCoin;
super.initState();
}
@override
Widget build(BuildContext context) {
final contact = ref.watch(addressBookServiceProvider
.select((value) => value.getContactById(contactId)));
@ -29,6 +46,11 @@ class ContactListItem extends ConsumerWidget {
padding: const EdgeInsets.all(0),
borderColor: Theme.of(context).extension<StackColors>()!.background,
child: Expandable(
onExpandChanged: (state) {
setState(() {
_state = state;
});
},
header: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 20,
@ -36,6 +58,7 @@ class ContactListItem extends ConsumerWidget {
),
child: AddressBookCard(
contactId: contactId,
indicatorDown: _state == ExpandableState.expanded,
),
),
body: Column(

View file

@ -1190,8 +1190,32 @@ class _DesktopSendState extends ConsumerState<DesktopSend> {
builder: (context) => DesktopDialog(
maxWidth: 696,
maxHeight: 600,
child: AddressBookAddressChooser(
coin: coin,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.only(
left: 32,
),
child: Text(
"Address book",
style:
STextStyles.desktopH3(context),
),
),
const DesktopDialogCloseButton(),
],
),
Expanded(
child: AddressBookAddressChooser(
coin: coin,
),
),
],
),
),
);

View file

@ -85,13 +85,13 @@ import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_sear
import 'package:stackwallet/pages/wallet_view/wallet_view.dart';
import 'package:stackwallet/pages/wallets_view/wallets_view.dart';
import 'package:stackwallet/pages_desktop_specific/create_password/create_password_view.dart';
import 'package:stackwallet/pages_desktop_specific/home/advanced_settings/advanced_settings.dart';
import 'package:stackwallet/pages_desktop_specific/home/desktop_home_view.dart';
import 'package:stackwallet/pages_desktop_specific/home/desktop_settings_view.dart';
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/my_stack_view.dart';
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/desktop_wallet_view.dart';
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/qr_code_desktop_popup_content.dart';
import 'package:stackwallet/pages_desktop_specific/home/my_stack_view/wallet_view/sub_widgets/wallet_keys_desktop_popup.dart';
import 'package:stackwallet/pages_desktop_specific/home/settings_menu/advanced_settings.dart';
import 'package:stackwallet/pages_desktop_specific/home/settings_menu/appearance_settings.dart';
import 'package:stackwallet/pages_desktop_specific/home/settings_menu/backup_and_restore/backup_and_restore_settings.dart';
import 'package:stackwallet/pages_desktop_specific/home/settings_menu/currency_settings.dart';

View file

@ -96,6 +96,7 @@ class _SVG {
String get qrcode => "assets/svg/qrcode1.svg";
String get ellipsis => "assets/svg/gear-3.svg";
String get chevronDown => "assets/svg/chevron-down.svg";
String get chevronUp => "assets/svg/chevron-up.svg";
String get swap => "assets/svg/swap.svg";
String get downloadFolder => "assets/svg/folder-down.svg";
String get lock => "assets/svg/lock-keyhole.svg";

View file

@ -13,9 +13,14 @@ import 'package:stackwallet/widgets/conditional_parent.dart';
import 'package:stackwallet/widgets/rounded_white_container.dart';
class AddressBookCard extends ConsumerStatefulWidget {
const AddressBookCard({Key? key, required this.contactId}) : super(key: key);
const AddressBookCard({
Key? key,
required this.contactId,
this.indicatorDown,
}) : super(key: key);
final String contactId;
final bool? indicatorDown;
@override
ConsumerState<AddressBookCard> createState() => _AddressBookCardState();
@ -122,7 +127,17 @@ class _AddressBookCardState extends ConsumerState<AddressBookCard> {
style: STextStyles.label(context),
),
],
)
),
if (isDesktop) const Spacer(),
if (isDesktop)
SvgPicture.asset(
widget.indicatorDown == true
? Assets.svg.chevronDown
: Assets.svg.chevronUp,
width: 10,
height: 5,
color: Theme.of(context).extension<StackColors>()!.textSubtitle2,
),
],
),
builder: (child) => RoundedWhiteContainer(

View file

@ -102,15 +102,13 @@ class _TransactionCardState extends ConsumerState<TransactionCard> {
.select((value) => value.getPrice(coin)))
.item1;
late final String prefix;
String prefix = "";
if (Util.isDesktop) {
if (_transaction.txType == "Sent") {
prefix = "-";
} else if (_transaction.txType == "Received") {
prefix = "+";
}
} else {
prefix = "";
}
return Material(

View file

@ -232,6 +232,7 @@ flutter:
- assets/svg/gear-3.svg
- assets/svg/swap.svg
- assets/svg/chevron-down.svg
- assets/svg/chevron-up.svg
- assets/svg/lock-keyhole.svg
- assets/svg/rotate-exclamation.svg
- assets/svg/folder-down.svg

View file

@ -1,6 +1,22 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:stackwallet/models/contact.dart';
import 'package:stackwallet/models/contact_address_entry.dart';
import 'package:stackwallet/pages/address_book_views/subviews/contact_popup.dart';
import 'package:stackwallet/providers/global/address_book_service_provider.dart';
import 'package:stackwallet/services/address_book_service.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/theme/light_colors.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/address_book_card.dart';
import 'address_book_card_test.mocks.dart';
class MockedFunctions extends Mock {
void showDialog();
@ -8,46 +24,53 @@ class MockedFunctions extends Mock {
@GenerateMocks([AddressBookService])
void main() {
// testWidgets('test returns Contact Address Entry', (widgetTester) async {
// final service = MockAddressBookService();
//
// when(service.getContactById("default"))
// .thenAnswer((realInvocation) => Contact(
// name: "John Doe",
// addresses: [
// const ContactAddressEntry(
// coin: Coin.bitcoincash,
// address: "some bch address",
// label: "Bills")
// ],
// isFavorite: true));
//
// await widgetTester.pumpWidget(
// ProviderScope(
// overrides: [
// addressBookServiceProvider.overrideWithValue(
// service,
// ),
// ],
// child: MaterialApp(
// theme: ThemeData(
// extensions: [
// StackColors.fromStackColorTheme(
// LightColors(),
// ),
// ],
// ),
// home: const AddressBookCard(
// contactId: "default",
// ),
// ),
// ),
// );
//
// expect(find.text("John Doe"), findsOneWidget);
// expect(find.text("BCH"), findsOneWidget);
// expect(find.text(Coin.bitcoincash.ticker), findsOneWidget);
//
// await widgetTester.tap(find.byType(RawMaterialButton));
// });
testWidgets('test returns Contact Address Entry', (widgetTester) async {
final service = MockAddressBookService();
when(service.getContactById("default")).thenAnswer(
(realInvocation) => Contact(
name: "John Doe",
addresses: [
const ContactAddressEntry(
coin: Coin.bitcoincash,
address: "some bch address",
label: "Bills")
],
isFavorite: true,
),
);
await widgetTester.pumpWidget(
ProviderScope(
overrides: [
addressBookServiceProvider.overrideWithValue(
service,
),
],
child: MaterialApp(
theme: ThemeData(
extensions: [
StackColors.fromStackColorTheme(
LightColors(),
),
],
),
home: const AddressBookCard(
contactId: "default",
),
),
),
);
expect(find.text("John Doe"), findsOneWidget);
expect(find.text("BCH"), findsOneWidget);
expect(find.text(Coin.bitcoincash.ticker), findsOneWidget);
if (Platform.isIOS || Platform.isAndroid) {
await widgetTester.tap(find.byType(RawMaterialButton));
expect(find.byType(ContactPopUp), findsOneWidget);
} else if (Util.isDesktop) {
expect(find.byType(RawMaterialButton), findsNothing);
}
});
}

View file

@ -1,4 +1,14 @@
import 'package:decimal/decimal.dart';
import 'package:flutter/material.dart';
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockingjay/mockingjay.dart' as mockingjay;
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:stackwallet/models/models.dart';
import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_details_view.dart';
import 'package:stackwallet/providers/providers.dart';
import 'package:stackwallet/services/coins/coin_service.dart';
import 'package:stackwallet/services/coins/firo/firo_wallet.dart';
import 'package:stackwallet/services/coins/manager.dart';
@ -6,7 +16,15 @@ import 'package:stackwallet/services/locale_service.dart';
import 'package:stackwallet/services/notes_service.dart';
import 'package:stackwallet/services/price_service.dart';
import 'package:stackwallet/services/wallets.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/prefs.dart';
import 'package:stackwallet/utilities/theme/light_colors.dart';
import 'package:stackwallet/utilities/theme/stack_colors.dart';
import 'package:stackwallet/utilities/util.dart';
import 'package:stackwallet/widgets/transaction_card.dart';
import 'package:tuple/tuple.dart';
import 'transaction_card_test.mocks.dart';
@GenerateMocks([
Wallets,
@ -19,362 +37,370 @@ import 'package:stackwallet/utilities/prefs.dart';
NotesService
], customMocks: [])
void main() {
// TestWidgetsFlutterBinding.ensureInitialized();
// testWidgets("Sent confirmed tx displays correctly", (tester) async {
// final mockManager = MockManager();
// final mockLocaleService = MockLocaleService();
// final wallets = MockWallets();
// final mockPrefs = MockPrefs();
// final mockPriceService = MockPriceService();
//
// final tx = Transaction(
// txid: "some txid",
// confirmedStatus: true,
// timestamp: 1648595998,
// txType: "Sent",
// amount: 100000000,
// aliens: [],
// worthNow: "0.01",
// worthAtBlockTimestamp: "0.01",
// fees: 3794,
// inputSize: 1,
// outputSize: 1,
// inputs: [],
// outputs: [],
// address: "",
// height: 450123,
// subType: "",
// confirmations: 10,
// isCancelled: false);
//
// final CoinServiceAPI wallet = MockFiroWallet();
//
// when(wallet.coin.ticker).thenAnswer((_) => "FIRO");
// when(mockLocaleService.locale).thenAnswer((_) => "en_US");
// when(mockPrefs.currency).thenAnswer((_) => "USD");
// when(mockPrefs.externalCalls).thenAnswer((_) => true);
// when(mockPriceService.getPrice(Coin.firo))
// .thenAnswer((realInvocation) => Tuple2(Decimal.ten, 0.00));
//
// when(wallet.coin).thenAnswer((_) => Coin.firo);
//
// when(wallets.getManager("wallet-id"))
// .thenAnswer((realInvocation) => Manager(wallet));
// //
// await tester.pumpWidget(
// ProviderScope(
// overrides: [
// walletsChangeNotifierProvider.overrideWithValue(wallets),
// localeServiceChangeNotifierProvider
// .overrideWithValue(mockLocaleService),
// prefsChangeNotifierProvider.overrideWithValue(mockPrefs),
// priceAnd24hChangeNotifierProvider.overrideWithValue(mockPriceService)
// ],
// child: MaterialApp(
// theme: ThemeData(
// extensions: [
// StackColors.fromStackColorTheme(
// LightColors(),
// ),
// ],
// ),
// home: TransactionCard(transaction: tx, walletId: "wallet-id"),
// ),
// ),
// );
//
// //
// final title = find.text("Sent");
// // final price1 = find.text("0.00 USD");
// final amount = find.text("1.00000000 FIRO");
//
// final icon = find.byIcon(FeatherIcons.arrowUp);
//
// expect(title, findsOneWidget);
// // expect(price1, findsOneWidget);
// expect(amount, findsOneWidget);
// // expect(icon, findsOneWidget);
// //
// await tester.pumpAndSettle(Duration(seconds: 2));
// //
// // final price2 = find.text("\$10.00");
// // expect(price2, findsOneWidget);
// //
// // verify(mockManager.addListener(any)).called(1);
// verify(mockLocaleService.addListener(any)).called(1);
//
// verify(mockPrefs.currency).called(1);
// verify(mockPriceService.getPrice(Coin.firo)).called(1);
// verify(wallet.coin.ticker).called(1);
//
// verify(mockLocaleService.locale).called(1);
//
// verifyNoMoreInteractions(mockManager);
// verifyNoMoreInteractions(mockLocaleService);
// });
//
// testWidgets("Anonymized confirmed tx displays correctly", (tester) async {
// final mockManager = MockManager();
// final mockLocaleService = MockLocaleService();
// final wallets = MockWallets();
// final mockPrefs = MockPrefs();
// final mockPriceService = MockPriceService();
//
// final tx = Transaction(
// txid: "some txid",
// confirmedStatus: true,
// timestamp: 1648595998,
// txType: "Anonymized",
// amount: 100000000,
// aliens: [],
// worthNow: "0.01",
// worthAtBlockTimestamp: "0.01",
// fees: 3794,
// inputSize: 1,
// outputSize: 1,
// inputs: [],
// outputs: [],
// address: "",
// height: 450123,
// subType: "mint",
// confirmations: 10,
// isCancelled: false);
//
// final CoinServiceAPI wallet = MockFiroWallet();
//
// when(wallet.coin.ticker).thenAnswer((_) => "FIRO");
// when(mockLocaleService.locale).thenAnswer((_) => "en_US");
// when(mockPrefs.currency).thenAnswer((_) => "USD");
// when(mockPrefs.externalCalls).thenAnswer((_) => true);
// when(mockPriceService.getPrice(Coin.firo))
// .thenAnswer((realInvocation) => Tuple2(Decimal.ten, 0.00));
//
// when(wallet.coin).thenAnswer((_) => Coin.firo);
//
// when(wallets.getManager("wallet-id"))
// .thenAnswer((realInvocation) => Manager(wallet));
// //
// await tester.pumpWidget(
// ProviderScope(
// overrides: [
// walletsChangeNotifierProvider.overrideWithValue(wallets),
// localeServiceChangeNotifierProvider
// .overrideWithValue(mockLocaleService),
// prefsChangeNotifierProvider.overrideWithValue(mockPrefs),
// priceAnd24hChangeNotifierProvider.overrideWithValue(mockPriceService)
// ],
// child: MaterialApp(
// theme: ThemeData(
// extensions: [
// StackColors.fromStackColorTheme(
// LightColors(),
// ),
// ],
// ),
// home: TransactionCard(transaction: tx, walletId: "wallet-id"),
// ),
// ),
// );
//
// //
// final title = find.text("Anonymized");
// // final price1 = find.text("0.00 USD");
// final amount = find.text("1.00000000 FIRO");
//
// final icon = find.byIcon(FeatherIcons.arrowUp);
//
// expect(title, findsOneWidget);
// // expect(price1, findsOneWidget);
// expect(amount, findsOneWidget);
// // expect(icon, findsOneWidget);
// //
// await tester.pumpAndSettle(Duration(seconds: 2));
// //
// // final price2 = find.text("\$10.00");
// // expect(price2, findsOneWidget);
// //
// // verify(mockManager.addListener(any)).called(1);
// verify(mockLocaleService.addListener(any)).called(1);
//
// verify(mockPrefs.currency).called(1);
// verify(mockPriceService.getPrice(Coin.firo)).called(1);
// verify(wallet.coin.ticker).called(1);
//
// verify(mockLocaleService.locale).called(1);
//
// verifyNoMoreInteractions(mockManager);
// verifyNoMoreInteractions(mockLocaleService);
// });
//
// testWidgets("Received unconfirmed tx displays correctly", (tester) async {
// final mockManager = MockManager();
// final mockLocaleService = MockLocaleService();
// final wallets = MockWallets();
// final mockPrefs = MockPrefs();
// final mockPriceService = MockPriceService();
//
// final tx = Transaction(
// txid: "some txid",
// confirmedStatus: false,
// timestamp: 1648595998,
// txType: "Received",
// amount: 100000000,
// aliens: [],
// worthNow: "0.01",
// worthAtBlockTimestamp: "0.01",
// fees: 3794,
// inputSize: 1,
// outputSize: 1,
// inputs: [],
// outputs: [],
// address: "",
// height: 0,
// subType: "",
// confirmations: 0,
// );
//
// final CoinServiceAPI wallet = MockFiroWallet();
//
// when(wallet.coin.ticker).thenAnswer((_) => "FIRO");
// when(mockLocaleService.locale).thenAnswer((_) => "en_US");
// when(mockPrefs.currency).thenAnswer((_) => "USD");
// when(mockPrefs.externalCalls).thenAnswer((_) => true);
// when(mockPriceService.getPrice(Coin.firo))
// .thenAnswer((realInvocation) => Tuple2(Decimal.ten, 0.00));
//
// when(wallet.coin).thenAnswer((_) => Coin.firo);
//
// when(wallets.getManager("wallet-id"))
// .thenAnswer((realInvocation) => Manager(wallet));
//
// await tester.pumpWidget(
// ProviderScope(
// overrides: [
// walletsChangeNotifierProvider.overrideWithValue(wallets),
// localeServiceChangeNotifierProvider
// .overrideWithValue(mockLocaleService),
// prefsChangeNotifierProvider.overrideWithValue(mockPrefs),
// priceAnd24hChangeNotifierProvider.overrideWithValue(mockPriceService)
// ],
// child: MaterialApp(
// theme: ThemeData(
// extensions: [
// StackColors.fromStackColorTheme(
// LightColors(),
// ),
// ],
// ),
// home: TransactionCard(transaction: tx, walletId: "wallet-id"),
// ),
// ),
// );
//
// final title = find.text("Receiving");
// final amount = find.text("1.00000000 FIRO");
//
// expect(title, findsOneWidget);
// expect(amount, findsOneWidget);
//
// await tester.pumpAndSettle(Duration(seconds: 2));
//
// verify(mockLocaleService.addListener(any)).called(1);
//
// verify(mockPrefs.currency).called(1);
// verify(mockPriceService.getPrice(Coin.firo)).called(1);
// verify(wallet.coin.ticker).called(1);
//
// verify(mockLocaleService.locale).called(1);
//
// verifyNoMoreInteractions(mockManager);
// verifyNoMoreInteractions(mockLocaleService);
// });
//
// testWidgets("Tap gesture", (tester) async {
// final mockManager = MockManager();
// final mockLocaleService = MockLocaleService();
// final wallets = MockWallets();
// final mockPrefs = MockPrefs();
// final mockPriceService = MockPriceService();
// final navigator = mockingjay.MockNavigator();
//
// final tx = Transaction(
// txid: "some txid",
// confirmedStatus: false,
// timestamp: 1648595998,
// txType: "Received",
// amount: 100000000,
// aliens: [],
// worthNow: "0.01",
// worthAtBlockTimestamp: "0.01",
// fees: 3794,
// inputSize: 1,
// outputSize: 1,
// inputs: [],
// outputs: [],
// address: "",
// height: 250,
// subType: "",
// confirmations: 10,
// );
//
// final CoinServiceAPI wallet = MockFiroWallet();
//
// when(wallet.coin.ticker).thenAnswer((_) => "FIRO");
// when(mockLocaleService.locale).thenAnswer((_) => "en_US");
// when(mockPrefs.currency).thenAnswer((_) => "USD");
// when(mockPrefs.externalCalls).thenAnswer((_) => true);
// when(mockPriceService.getPrice(Coin.firo))
// .thenAnswer((realInvocation) => Tuple2(Decimal.ten, 0.00));
//
// when(wallet.coin).thenAnswer((_) => Coin.firo);
//
// when(wallets.getManager("wallet id"))
// .thenAnswer((realInvocation) => Manager(wallet));
//
// mockingjay
// .when(() => navigator.pushNamed("/transactionDetails",
// arguments: Tuple3(tx, Coin.firo, "wallet id")))
// .thenAnswer((_) async => {});
//
// await tester.pumpWidget(
// ProviderScope(
// overrides: [
// walletsChangeNotifierProvider.overrideWithValue(wallets),
// localeServiceChangeNotifierProvider
// .overrideWithValue(mockLocaleService),
// prefsChangeNotifierProvider.overrideWithValue(mockPrefs),
// priceAnd24hChangeNotifierProvider.overrideWithValue(mockPriceService)
// ],
// child: MaterialApp(
// theme: ThemeData(
// extensions: [
// StackColors.fromStackColorTheme(LightColors()),
// ],
// ),
// home: mockingjay.MockNavigatorProvider(
// navigator: navigator,
// child: TransactionCard(transaction: tx, walletId: "wallet id")),
// ),
// ),
// );
//
// expect(find.byType(GestureDetector), findsOneWidget);
//
// await tester.tap(find.byType(GestureDetector));
// await tester.pump();
//
// verify(mockLocaleService.addListener(any)).called(1);
//
// verify(mockPrefs.currency).called(1);
// verify(mockLocaleService.locale).called(1);
// verify(wallet.coin.ticker).called(1);
//
// verifyNoMoreInteractions(wallet);
// verifyNoMoreInteractions(mockLocaleService);
//
// mockingjay
// .verify(() => navigator.pushNamed("/transactionDetails",
// arguments: Tuple3(tx, Coin.firo, "wallet id")))
// .called(1);
// });
TestWidgetsFlutterBinding.ensureInitialized();
testWidgets("Sent confirmed tx displays correctly", (tester) async {
final mockManager = MockManager();
final mockLocaleService = MockLocaleService();
final wallets = MockWallets();
final mockPrefs = MockPrefs();
final mockPriceService = MockPriceService();
final tx = Transaction(
txid: "some txid",
confirmedStatus: true,
timestamp: 1648595998,
txType: "Sent",
amount: 100000000,
aliens: [],
worthNow: "0.01",
worthAtBlockTimestamp: "0.01",
fees: 3794,
inputSize: 1,
outputSize: 1,
inputs: [],
outputs: [],
address: "",
height: 450123,
subType: "",
confirmations: 10,
isCancelled: false);
final CoinServiceAPI wallet = MockFiroWallet();
when(wallet.coin.ticker).thenAnswer((_) => "FIRO");
when(mockLocaleService.locale).thenAnswer((_) => "en_US");
when(mockPrefs.currency).thenAnswer((_) => "USD");
when(mockPrefs.externalCalls).thenAnswer((_) => true);
when(mockPriceService.getPrice(Coin.firo))
.thenAnswer((realInvocation) => Tuple2(Decimal.ten, 0.00));
when(wallet.coin).thenAnswer((_) => Coin.firo);
when(wallets.getManager("wallet-id"))
.thenAnswer((realInvocation) => Manager(wallet));
//
await tester.pumpWidget(
ProviderScope(
overrides: [
walletsChangeNotifierProvider.overrideWithValue(wallets),
localeServiceChangeNotifierProvider
.overrideWithValue(mockLocaleService),
prefsChangeNotifierProvider.overrideWithValue(mockPrefs),
priceAnd24hChangeNotifierProvider.overrideWithValue(mockPriceService)
],
child: MaterialApp(
theme: ThemeData(
extensions: [
StackColors.fromStackColorTheme(
LightColors(),
),
],
),
home: TransactionCard(transaction: tx, walletId: "wallet-id"),
),
),
);
//
final title = find.text("Sent");
// final price1 = find.text("0.00 USD");
final amount = Util.isDesktop
? find.text("-1.00000000 FIRO")
: find.text("1.00000000 FIRO");
final icon = find.byIcon(FeatherIcons.arrowUp);
expect(title, findsOneWidget);
// expect(price1, findsOneWidget);
expect(amount, findsOneWidget);
// expect(icon, findsOneWidget);
//
await tester.pumpAndSettle(const Duration(seconds: 2));
//
// final price2 = find.text("\$10.00");
// expect(price2, findsOneWidget);
//
// verify(mockManager.addListener(any)).called(1);
verify(mockLocaleService.addListener(any)).called(1);
verify(mockPrefs.currency).called(1);
verify(mockPriceService.getPrice(Coin.firo)).called(1);
verify(wallet.coin.ticker).called(1);
verify(mockLocaleService.locale).called(1);
verifyNoMoreInteractions(mockManager);
verifyNoMoreInteractions(mockLocaleService);
});
testWidgets("Anonymized confirmed tx displays correctly", (tester) async {
final mockManager = MockManager();
final mockLocaleService = MockLocaleService();
final wallets = MockWallets();
final mockPrefs = MockPrefs();
final mockPriceService = MockPriceService();
final tx = Transaction(
txid: "some txid",
confirmedStatus: true,
timestamp: 1648595998,
txType: "Anonymized",
amount: 100000000,
aliens: [],
worthNow: "0.01",
worthAtBlockTimestamp: "0.01",
fees: 3794,
inputSize: 1,
outputSize: 1,
inputs: [],
outputs: [],
address: "",
height: 450123,
subType: "mint",
confirmations: 10,
isCancelled: false);
final CoinServiceAPI wallet = MockFiroWallet();
when(wallet.coin.ticker).thenAnswer((_) => "FIRO");
when(mockLocaleService.locale).thenAnswer((_) => "en_US");
when(mockPrefs.currency).thenAnswer((_) => "USD");
when(mockPrefs.externalCalls).thenAnswer((_) => true);
when(mockPriceService.getPrice(Coin.firo))
.thenAnswer((realInvocation) => Tuple2(Decimal.ten, 0.00));
when(wallet.coin).thenAnswer((_) => Coin.firo);
when(wallets.getManager("wallet-id"))
.thenAnswer((realInvocation) => Manager(wallet));
//
await tester.pumpWidget(
ProviderScope(
overrides: [
walletsChangeNotifierProvider.overrideWithValue(wallets),
localeServiceChangeNotifierProvider
.overrideWithValue(mockLocaleService),
prefsChangeNotifierProvider.overrideWithValue(mockPrefs),
priceAnd24hChangeNotifierProvider.overrideWithValue(mockPriceService)
],
child: MaterialApp(
theme: ThemeData(
extensions: [
StackColors.fromStackColorTheme(
LightColors(),
),
],
),
home: TransactionCard(transaction: tx, walletId: "wallet-id"),
),
),
);
//
final title = find.text("Anonymized");
// final price1 = find.text("0.00 USD");
final amount = find.text("1.00000000 FIRO");
final icon = find.byIcon(FeatherIcons.arrowUp);
expect(title, findsOneWidget);
// expect(price1, findsOneWidget);
expect(amount, findsOneWidget);
// expect(icon, findsOneWidget);
//
await tester.pumpAndSettle(const Duration(seconds: 2));
//
// final price2 = find.text("\$10.00");
// expect(price2, findsOneWidget);
//
// verify(mockManager.addListener(any)).called(1);
verify(mockLocaleService.addListener(any)).called(1);
verify(mockPrefs.currency).called(1);
verify(mockPriceService.getPrice(Coin.firo)).called(1);
verify(wallet.coin.ticker).called(1);
verify(mockLocaleService.locale).called(1);
verifyNoMoreInteractions(mockManager);
verifyNoMoreInteractions(mockLocaleService);
});
testWidgets("Received unconfirmed tx displays correctly", (tester) async {
final mockManager = MockManager();
final mockLocaleService = MockLocaleService();
final wallets = MockWallets();
final mockPrefs = MockPrefs();
final mockPriceService = MockPriceService();
final tx = Transaction(
txid: "some txid",
confirmedStatus: false,
timestamp: 1648595998,
txType: "Received",
amount: 100000000,
aliens: [],
worthNow: "0.01",
worthAtBlockTimestamp: "0.01",
fees: 3794,
inputSize: 1,
outputSize: 1,
inputs: [],
outputs: [],
address: "",
height: 0,
subType: "",
confirmations: 0,
);
final CoinServiceAPI wallet = MockFiroWallet();
when(wallet.coin.ticker).thenAnswer((_) => "FIRO");
when(mockLocaleService.locale).thenAnswer((_) => "en_US");
when(mockPrefs.currency).thenAnswer((_) => "USD");
when(mockPrefs.externalCalls).thenAnswer((_) => true);
when(mockPriceService.getPrice(Coin.firo))
.thenAnswer((realInvocation) => Tuple2(Decimal.ten, 0.00));
when(wallet.coin).thenAnswer((_) => Coin.firo);
when(wallets.getManager("wallet-id"))
.thenAnswer((realInvocation) => Manager(wallet));
await tester.pumpWidget(
ProviderScope(
overrides: [
walletsChangeNotifierProvider.overrideWithValue(wallets),
localeServiceChangeNotifierProvider
.overrideWithValue(mockLocaleService),
prefsChangeNotifierProvider.overrideWithValue(mockPrefs),
priceAnd24hChangeNotifierProvider.overrideWithValue(mockPriceService)
],
child: MaterialApp(
theme: ThemeData(
extensions: [
StackColors.fromStackColorTheme(
LightColors(),
),
],
),
home: TransactionCard(transaction: tx, walletId: "wallet-id"),
),
),
);
final title = find.text("Receiving");
final amount = Util.isDesktop
? find.text("+1.00000000 FIRO")
: find.text("1.00000000 FIRO");
expect(title, findsOneWidget);
expect(amount, findsOneWidget);
await tester.pumpAndSettle(const Duration(seconds: 2));
verify(mockLocaleService.addListener(any)).called(1);
verify(mockPrefs.currency).called(1);
verify(mockPriceService.getPrice(Coin.firo)).called(1);
verify(wallet.coin.ticker).called(1);
verify(mockLocaleService.locale).called(1);
verifyNoMoreInteractions(mockManager);
verifyNoMoreInteractions(mockLocaleService);
});
testWidgets("Tap gesture", (tester) async {
final mockManager = MockManager();
final mockLocaleService = MockLocaleService();
final wallets = MockWallets();
final mockPrefs = MockPrefs();
final mockPriceService = MockPriceService();
final navigator = mockingjay.MockNavigator();
final tx = Transaction(
txid: "some txid",
confirmedStatus: false,
timestamp: 1648595998,
txType: "Received",
amount: 100000000,
aliens: [],
worthNow: "0.01",
worthAtBlockTimestamp: "0.01",
fees: 3794,
inputSize: 1,
outputSize: 1,
inputs: [],
outputs: [],
address: "",
height: 250,
subType: "",
confirmations: 10,
);
final CoinServiceAPI wallet = MockFiroWallet();
when(wallet.coin.ticker).thenAnswer((_) => "FIRO");
when(mockLocaleService.locale).thenAnswer((_) => "en_US");
when(mockPrefs.currency).thenAnswer((_) => "USD");
when(mockPrefs.externalCalls).thenAnswer((_) => true);
when(mockPriceService.getPrice(Coin.firo))
.thenAnswer((realInvocation) => Tuple2(Decimal.ten, 0.00));
when(wallet.coin).thenAnswer((_) => Coin.firo);
when(wallets.getManager("wallet id"))
.thenAnswer((realInvocation) => Manager(wallet));
mockingjay
.when(() => navigator.pushNamed("/transactionDetails",
arguments: Tuple3(tx, Coin.firo, "wallet id")))
.thenAnswer((_) async => {});
await tester.pumpWidget(
ProviderScope(
overrides: [
walletsChangeNotifierProvider.overrideWithValue(wallets),
localeServiceChangeNotifierProvider
.overrideWithValue(mockLocaleService),
prefsChangeNotifierProvider.overrideWithValue(mockPrefs),
priceAnd24hChangeNotifierProvider.overrideWithValue(mockPriceService)
],
child: MaterialApp(
theme: ThemeData(
extensions: [
StackColors.fromStackColorTheme(LightColors()),
],
),
home: mockingjay.MockNavigatorProvider(
navigator: navigator,
child: TransactionCard(transaction: tx, walletId: "wallet id")),
),
),
);
expect(find.byType(GestureDetector), findsOneWidget);
await tester.tap(find.byType(GestureDetector));
await tester.pump();
verify(mockLocaleService.addListener(any)).called(1);
verify(mockPrefs.currency).called(2);
verify(mockLocaleService.locale).called(4);
verify(wallet.coin.ticker).called(1);
verifyNoMoreInteractions(wallet);
verifyNoMoreInteractions(mockLocaleService);
if (Util.isDesktop) {
expect(find.byType(TransactionDetailsView), findsOneWidget);
} else {
mockingjay
.verify(() => navigator.pushNamed("/transactionDetails",
arguments: Tuple3(tx, Coin.firo, "wallet id")))
.called(1);
}
});
}