| 1 | import 'package:cake_wallet/core/address_resolver/address_resolver_utils.dart'; |
| 2 | import 'package:cake_wallet/core/address_resolver/unstoppable/unstoppable_address_provider.dart'; |
| 3 | import 'package:cw_core/crypto_currency.dart'; |
| 4 | import 'package:flutter_test/flutter_test.dart'; |
| 5 | |
| 6 | void main() { |
| 7 | group('AddressResolver', () { |
| 8 | // late MockYatService mockYatService; |
| 9 | // late MockWalletBase mockWallet; |
| 10 | // late MockSettingsStore mockSettingsStore; |
| 11 | // late MockBuildContext mockContext; |
| 12 | // late AddressResolver addressResolverUtils; |
| 13 | // |
| 14 | // setUp(() { |
| 15 | // mockYatService = MockYatService(); |
| 16 | // mockWallet = MockWalletBase(); |
| 17 | // mockSettingsStore = MockSettingsStore(); |
| 18 | // mockContext = MockBuildContext(); |
| 19 | // |
| 20 | // when(mockWallet.type).thenReturn(WalletType.bitcoin); |
| 21 | // when(mockWallet.currency).thenReturn(CryptoCurrency.btc); |
| 22 | // |
| 23 | // addressResolverUtils = AddressResolverUtils( |
| 24 | // yatService: mockYatService, |
| 25 | // wallet: mockWallet, |
| 26 | // settingsStore: mockSettingsStore, |
| 27 | // ); |
| 28 | // }); |
| 29 | |
| 30 | group('extractAddressByType', () { |
| 31 | test('extracts Bitcoin address correctly', () { |
| 32 | final raw = |
| 33 | 'My Bitcoin address is bc1qhg4l43pmq5v5atmtlr7gnwyuxs043cvrut5hkq please use it'; |
| 34 | final result = AddressResolverUtils.extractAddressByType( |
| 35 | raw: raw, |
| 36 | type: CryptoCurrency.btc, |
| 37 | ); |
| 38 | expect(result, 'bc1qhg4l43pmq5v5atmtlr7gnwyuxs043cvrut5hkq'); |
| 39 | }); |
| 40 | |
| 41 | test('extracts Ethereum address correctly', () { |
| 42 | final raw = 'Send ETH to 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 thanks'; |
| 43 | final result = AddressResolverUtils.extractAddressByType( |
| 44 | raw: raw, |
| 45 | type: CryptoCurrency.eth, |
| 46 | ); |
| 47 | expect(result, '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'); |
| 48 | }); |
| 49 | |
| 50 | test('extracts Monero address correctly', () { |
| 51 | final raw = |
| 52 | 'XMR: 85s6zfxGAkdCN21h566R8EFDSfThxCrFiEkhw3JEtaXN2DDfahABLXTjRj385Ro7om5saGWJG7iuE6EyW5MYcoz93DLvNqh'; |
| 53 | final result = AddressResolverUtils.extractAddressByType( |
| 54 | raw: raw, |
| 55 | type: CryptoCurrency.xmr, |
| 56 | ); |
| 57 | expect(result, |
| 58 | '85s6zfxGAkdCN21h566R8EFDSfThxCrFiEkhw3JEtaXN2DDfahABLXTjRj385Ro7om5saGWJG7iuE6EyW5MYcoz93DLvNqh'); |
| 59 | }); |
| 60 | |
| 61 | test('extracts Bitcoin Cash address correctly', () { |
| 62 | final raw = 'BCH: bitcoincash:qr2z7dusk64qnq97azhg0u0hlf7qgwwfzyj92jgmqj'; |
| 63 | final result = AddressResolverUtils.extractAddressByType( |
| 64 | raw: raw, |
| 65 | type: CryptoCurrency.bch, |
| 66 | ); |
| 67 | expect(result, 'bitcoincash:qr2z7dusk64qnq97azhg0u0hlf7qgwwfzyj92jgmqj'); |
| 68 | }); |
| 69 | |
| 70 | test('extracts Nano address correctly', () { |
| 71 | final raw = 'NANO: nano_1natrium1o3z5519ifou7xii8crpxpk8y65qmkih8e8bpsjri651oza8imdd'; |
| 72 | final result = AddressResolverUtils.extractAddressByType( |
| 73 | raw: raw, |
| 74 | type: CryptoCurrency.nano, |
| 75 | ); |
| 76 | expect(result, 'nano_1natrium1o3z5519ifou7xii8crpxpk8y65qmkih8e8bpsjri651oza8imdd'); |
| 77 | }); |
| 78 | |
| 79 | test('returns null for unsupported currency', () { |
| 80 | final raw = 'Some text without an address'; |
| 81 | expect( |
| 82 | () => AddressResolverUtils.extractAddressByType( |
| 83 | raw: raw, |
| 84 | type: CryptoCurrency.btc, |
| 85 | ), |
| 86 | returnsNormally); |
| 87 | |
| 88 | final result = AddressResolverUtils.extractAddressByType( |
| 89 | raw: raw, |
| 90 | type: CryptoCurrency.btc, |
| 91 | ); |
| 92 | expect(result, isNull); |
| 93 | }); |
| 94 | |
| 95 | test('extracts monero address from URI', () { |
| 96 | final raw = |
| 97 | 'monero_wallet:467iotZU5tvG26k2xdZWkJ7gwATFVhfbuV3yDoWx5jHoPwxEi4f5BuJQwkP6GpCb1sZvUVB7nbSkgEuW8NKrh9KKRRga5qz?spend_key=029c559cd7669f14e91fd835144916009f8697ab5ac5c7f7c06e1ff869c17b0b&view_key=afaf646edbff3d3bcee8efd3383ffe5d20c947040f74e1110b70ca0fbb0ef90d'; |
| 98 | final result = AddressResolverUtils.extractAddressByType( |
| 99 | raw: raw, type: CryptoCurrency.xmr, requireSurroundingWhitespaces: false); |
| 100 | expect(result, |
| 101 | '467iotZU5tvG26k2xdZWkJ7gwATFVhfbuV3yDoWx5jHoPwxEi4f5BuJQwkP6GpCb1sZvUVB7nbSkgEuW8NKrh9KKRRga5qz'); |
| 102 | }); |
| 103 | |
| 104 | test('extracts monero address from Tweet', () { |
| 105 | final raw = ''' |
| 106 | #XMR |
| 107 | 89bH6i3ftaWSWuPJJYSQuuApWJ8xzinCEbbnAXN1Z3mGGUuAFdpBUg82R9MvJDSheJ6kW2dyMQEFUGM4tsZqRb2Q75UXqvc |
| 108 | |
| 109 | #BTC Silent Payments |
| 110 | sp1qq0avpawwjg4l66p6lqafj0vlvm6rlhdc6qt0r6dfual835vhs3gvkq63pechaqezvn7j7uj2jucwj5k7nenpw2r86wf42xv6wqdvxuk5rggrul45 |
| 111 | |
| 112 | #LTC MWEB |
| 113 | ltcmweb1qq0at62jjucmawxp78qutn0cqwkwahcfx7fxls0r2ma5llg5w6wyy2qe20gxa3rku2658j88zg9d2j4ttpw35k0a5nrg93h5nq3wyvkcgwc3q4dgc |
| 114 | '''; |
| 115 | final resultXmr = |
| 116 | AddressResolverUtils.extractAddressByType(raw: raw, type: CryptoCurrency.xmr); |
| 117 | expect(resultXmr, |
| 118 | '89bH6i3ftaWSWuPJJYSQuuApWJ8xzinCEbbnAXN1Z3mGGUuAFdpBUg82R9MvJDSheJ6kW2dyMQEFUGM4tsZqRb2Q75UXqvc'); |
| 119 | final resultBtc = |
| 120 | AddressResolverUtils.extractAddressByType(raw: raw, type: CryptoCurrency.btc); |
| 121 | expect(resultBtc, |
| 122 | 'sp1qq0avpawwjg4l66p6lqafj0vlvm6rlhdc6qt0r6dfual835vhs3gvkq63pechaqezvn7j7uj2jucwj5k7nenpw2r86wf42xv6wqdvxuk5rggrul45'); |
| 123 | final resultLtc = |
| 124 | AddressResolverUtils.extractAddressByType(raw: raw, type: CryptoCurrency.ltc); |
| 125 | expect(resultLtc, |
| 126 | 'ltcmweb1qq0at62jjucmawxp78qutn0cqwkwahcfx7fxls0r2ma5llg5w6wyy2qe20gxa3rku2658j88zg9d2j4ttpw35k0a5nrg93h5nq3wyvkcgwc3q4dgc'); |
| 127 | }); |
| 128 | |
| 129 | // test('throws exception for unexpected token', () { |
| 130 | // // Create a custom crypto currency that won't have a pattern |
| 131 | // final customCurrency = CryptoCurrency('CUSTOM', 'Custom'); |
| 132 | // expect(() => AddressResolverUtils.extractAddressByType( |
| 133 | // raw: 'Some text', |
| 134 | // type: customCurrency, |
| 135 | // ), throwsException); |
| 136 | // }); |
| 137 | }); |
| 138 | // |
| 139 | // group('isEmailFormat', () { |
| 140 | // test('returns true for valid email format', () { |
| 141 | // expect(addressResolverUtils.isEmailFormat('user@example.com'), isTrue); |
| 142 | // expect(addressResolverUtils.isEmailFormat('name.surname@domain.co.uk'), isTrue); |
| 143 | // expect(addressResolverUtils.isEmailFormat('user123@subdomain.example.org'), isTrue); |
| 144 | // }); |
| 145 | // |
| 146 | // test('returns false for invalid email format', () { |
| 147 | // expect(addressResolverUtils.isEmailFormat('user@'), isFalse); |
| 148 | // expect(addressResolverUtils.isEmailFormat('@domain.com'), isFalse); |
| 149 | // expect(addressResolverUtils.isEmailFormat('user@domain'), isFalse); |
| 150 | // expect(addressResolverUtils.isEmailFormat('user.domain.com'), isFalse); |
| 151 | // expect(addressResolverUtils.isEmailFormat('user@domain@com'), isFalse); |
| 152 | // expect(addressResolverUtils.isEmailFormat('bc1qhg4l43pmq5v5atmtlr7gnwyuxs043cvrut5hkq'), isFalse); |
| 153 | // }); |
| 154 | // }); |
| 155 | // |
| 156 | // group('resolve', () { |
| 157 | // test('returns ParsedAddress with original text when no resolution is possible', () async { |
| 158 | // final text = 'bc1qhg4l43pmq5v5atmtlr7gnwyuxs043cvrut5hkq'; |
| 159 | // final result = await addressResolverUtils.resolve(mockContext, text, CryptoCurrency.btc); |
| 160 | // |
| 161 | // expect(result, isA<ParsedAddress>()); |
| 162 | // expect(result.addresses, [text]); |
| 163 | // }); |
| 164 | // |
| 165 | // // Note: More comprehensive tests for the resolve method would require |
| 166 | // // mocking all the external services and APIs that the method calls. |
| 167 | // // This would be quite extensive and would require setting up mock |
| 168 | // // responses for each type of address resolution. |
| 169 | // }); |
| 170 | |
| 171 | group('unstoppableDomains', () { |
| 172 | test('contains expected TLDs', () { |
| 173 | expect(UnstoppableAddressProvider.unstoppableDomains, contains('crypto')); |
| 174 | expect(UnstoppableAddressProvider.unstoppableDomains, contains('eth')); |
| 175 | expect(UnstoppableAddressProvider.unstoppableDomains, contains('bitcoin')); |
| 176 | expect(UnstoppableAddressProvider.unstoppableDomains, contains('x')); |
| 177 | expect(UnstoppableAddressProvider.unstoppableDomains, contains('wallet')); |
| 178 | }); |
| 179 | }); |
| 180 | }); |
| 181 | } |