wallet-stack 1.0.0-alpha.131 → 1.0.0-alpha.133
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/locales/base/translation.json +11 -0
- package/package.json +2 -3
- package/src/analytics/Events.tsx +3 -10
- package/src/analytics/Properties.tsx +9 -25
- package/src/analytics/docs.ts +11 -8
- package/src/app/ErrorMessages.ts +1 -7
- package/src/identity/actions.ts +1 -97
- package/src/identity/contactMapping.test.ts +3 -28
- package/src/identity/contactMapping.ts +2 -88
- package/src/identity/reducer.ts +0 -77
- package/src/identity/saga.ts +2 -85
- package/src/identity/selectors.ts +0 -2
- package/src/images/Images.ts +3 -0
- package/src/images/assets/invite-modal.png +0 -0
- package/src/images/assets/invite-modal@1.5x.png +0 -0
- package/src/images/assets/invite-modal@2x.png +0 -0
- package/src/images/assets/invite-modal@3x.png +0 -0
- package/src/images/assets/invite-modal@4x.png +0 -0
- package/src/images/assets/minipay.png +0 -0
- package/src/images/assets/minipay@1.5x.png +0 -0
- package/src/images/assets/minipay@2x.png +0 -0
- package/src/images/assets/minipay@3x.png +0 -0
- package/src/images/assets/minipay@4x.png +0 -0
- package/src/images/assets/valora.png +0 -0
- package/src/images/assets/valora@1.5x.png +0 -0
- package/src/images/assets/valora@2x.png +0 -0
- package/src/images/assets/valora@3x.png +0 -0
- package/src/images/assets/valora@4x.png +0 -0
- package/src/index.d.ts +0 -1
- package/src/navigator/Navigator.tsx +10 -14
- package/src/navigator/Screens.tsx +2 -2
- package/src/navigator/types.tsx +5 -6
- package/src/qrcode/utils.test.tsx +4 -96
- package/src/qrcode/utils.ts +5 -114
- package/src/redux/migrations.test.ts +13 -0
- package/src/redux/migrations.ts +4 -0
- package/src/redux/store.test.ts +1 -2
- package/src/redux/store.ts +1 -1
- package/src/send/SelectRecipientAddress.test.tsx +146 -0
- package/src/send/SelectRecipientAddress.tsx +166 -0
- package/src/send/SendConfirmation.test.tsx +28 -0
- package/src/send/SendConfirmation.tsx +18 -1
- package/src/send/SendInvite.test.tsx +107 -0
- package/src/send/SendInvite.tsx +99 -0
- package/src/send/SendSelectRecipient.test.tsx +44 -223
- package/src/send/SendSelectRecipient.tsx +41 -149
- package/src/send/actions.ts +0 -26
- package/src/send/saga.ts +1 -6
- package/src/components/AccountNumberCard.tsx +0 -23
- package/src/components/ErrorMessageInline.tsx +0 -78
- package/src/components/SingleDigitInput.tsx +0 -53
- package/src/icons/HamburgerCard.tsx +0 -55
- package/src/identity/saga.test.ts +0 -103
- package/src/identity/secureSend.ts +0 -171
- package/src/send/ValidateRecipientAccount.test.tsx +0 -182
- package/src/send/ValidateRecipientAccount.tsx +0 -392
- package/src/send/ValidateRecipientIntro.test.tsx +0 -61
- package/src/send/ValidateRecipientIntro.tsx +0 -136
- package/src/send/__snapshots__/ValidateRecipientAccount.test.tsx.snap +0 -777
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import { expectSaga } from 'redux-saga-test-plan'
|
|
2
|
-
import { select } from 'redux-saga/effects'
|
|
3
|
-
import { showErrorInline } from 'src/alert/actions'
|
|
4
|
-
import { ErrorMessages } from 'src/app/ErrorMessages'
|
|
5
|
-
import {
|
|
6
|
-
Actions,
|
|
7
|
-
ValidateRecipientAddressAction,
|
|
8
|
-
validateRecipientAddressSuccess,
|
|
9
|
-
} from 'src/identity/actions'
|
|
10
|
-
import { AddressValidationType } from 'src/identity/reducer'
|
|
11
|
-
import { watchValidateRecipientAddress } from 'src/identity/saga'
|
|
12
|
-
import { e164NumberToAddressSelector } from 'src/identity/selectors'
|
|
13
|
-
import { currentAccountSelector } from 'src/web3/selectors'
|
|
14
|
-
import {
|
|
15
|
-
mockAccount,
|
|
16
|
-
mockAccount2,
|
|
17
|
-
mockAccountInvite,
|
|
18
|
-
mockE164NumberInvite,
|
|
19
|
-
mockE164NumberToAddress,
|
|
20
|
-
mockInvitableRecipient2,
|
|
21
|
-
} from 'test/values'
|
|
22
|
-
|
|
23
|
-
describe(watchValidateRecipientAddress, () => {
|
|
24
|
-
beforeAll(() => {
|
|
25
|
-
jest.useRealTimers()
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
afterEach(() => {
|
|
29
|
-
jest.clearAllMocks()
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
it('full validation fails if the inputted address does not belong to the recipient', async () => {
|
|
33
|
-
const validateAction: ValidateRecipientAddressAction = {
|
|
34
|
-
type: Actions.VALIDATE_RECIPIENT_ADDRESS,
|
|
35
|
-
userInputOfFullAddressOrLastFourDigits: mockAccount2,
|
|
36
|
-
addressValidationType: AddressValidationType.FULL,
|
|
37
|
-
recipient: mockInvitableRecipient2,
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
await expectSaga(watchValidateRecipientAddress)
|
|
41
|
-
.provide([
|
|
42
|
-
[select(currentAccountSelector), mockAccount],
|
|
43
|
-
[select(e164NumberToAddressSelector), mockE164NumberToAddress],
|
|
44
|
-
])
|
|
45
|
-
.dispatch(validateAction)
|
|
46
|
-
.put(showErrorInline(ErrorMessages.ADDRESS_VALIDATION_NO_MATCH))
|
|
47
|
-
.run()
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
it('full validation succeeds if the inputted address belongs to the recipient', async () => {
|
|
51
|
-
const validateAction: ValidateRecipientAddressAction = {
|
|
52
|
-
type: Actions.VALIDATE_RECIPIENT_ADDRESS,
|
|
53
|
-
userInputOfFullAddressOrLastFourDigits: mockAccountInvite,
|
|
54
|
-
addressValidationType: AddressValidationType.FULL,
|
|
55
|
-
recipient: mockInvitableRecipient2,
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
await expectSaga(watchValidateRecipientAddress)
|
|
59
|
-
.provide([
|
|
60
|
-
[select(currentAccountSelector), mockAccount],
|
|
61
|
-
[select(e164NumberToAddressSelector), mockE164NumberToAddress],
|
|
62
|
-
])
|
|
63
|
-
.dispatch(validateAction)
|
|
64
|
-
.put(validateRecipientAddressSuccess(mockE164NumberInvite, mockAccountInvite.toLowerCase()))
|
|
65
|
-
.run()
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
it('partial validation fails if the inputted address does not belong to the recipient', async () => {
|
|
69
|
-
const validateAction: ValidateRecipientAddressAction = {
|
|
70
|
-
type: Actions.VALIDATE_RECIPIENT_ADDRESS,
|
|
71
|
-
userInputOfFullAddressOrLastFourDigits: mockAccount2.slice(-4),
|
|
72
|
-
addressValidationType: AddressValidationType.PARTIAL,
|
|
73
|
-
recipient: mockInvitableRecipient2,
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
await expectSaga(watchValidateRecipientAddress)
|
|
77
|
-
.provide([
|
|
78
|
-
[select(currentAccountSelector), mockAccount],
|
|
79
|
-
[select(e164NumberToAddressSelector), mockE164NumberToAddress],
|
|
80
|
-
])
|
|
81
|
-
.dispatch(validateAction)
|
|
82
|
-
.put(showErrorInline(ErrorMessages.ADDRESS_VALIDATION_NO_MATCH))
|
|
83
|
-
.run()
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
it('partial validation succeeds if the inputted address belongs to the recipient', async () => {
|
|
87
|
-
const validateAction: ValidateRecipientAddressAction = {
|
|
88
|
-
type: Actions.VALIDATE_RECIPIENT_ADDRESS,
|
|
89
|
-
userInputOfFullAddressOrLastFourDigits: mockAccountInvite.slice(-4),
|
|
90
|
-
addressValidationType: AddressValidationType.PARTIAL,
|
|
91
|
-
recipient: mockInvitableRecipient2,
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
await expectSaga(watchValidateRecipientAddress)
|
|
95
|
-
.provide([
|
|
96
|
-
[select(currentAccountSelector), mockAccount],
|
|
97
|
-
[select(e164NumberToAddressSelector), mockE164NumberToAddress],
|
|
98
|
-
])
|
|
99
|
-
.dispatch(validateAction)
|
|
100
|
-
.put(validateRecipientAddressSuccess(mockE164NumberInvite, mockAccountInvite.toLowerCase()))
|
|
101
|
-
.run()
|
|
102
|
-
})
|
|
103
|
-
})
|
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
import { ErrorMessages } from 'src/app/ErrorMessages'
|
|
2
|
-
import { AddressValidationType, SecureSendPhoneNumberMapping } from 'src/identity/reducer'
|
|
3
|
-
import { Recipient, recipientHasNumber } from 'src/recipients/recipient'
|
|
4
|
-
import Logger from 'src/utils/Logger'
|
|
5
|
-
|
|
6
|
-
const TAG = 'identity/secureSend'
|
|
7
|
-
|
|
8
|
-
// Given addresses can be added and deleted we can't rely on changes in length to signal address changes
|
|
9
|
-
// Not sure if address order in array is consistent so not assuming it
|
|
10
|
-
function newAddressesAdded(oldAddresses: string[], newAddresses: string[]) {
|
|
11
|
-
const oldAddressesSorted = oldAddresses.sort()
|
|
12
|
-
const newAddressesSorted = newAddresses.sort()
|
|
13
|
-
|
|
14
|
-
for (let i = 0; i < newAddressesSorted.length; i += 1) {
|
|
15
|
-
if (oldAddressesSorted[i] !== newAddressesSorted[i]) {
|
|
16
|
-
return true
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
return false
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function last4DigitsAreUnique(addressArr: string[]) {
|
|
24
|
-
const last4DigitArr = addressArr.map((address) => address.slice(-4).toLowerCase())
|
|
25
|
-
const last4DigitSet = new Set()
|
|
26
|
-
last4DigitArr.forEach((endDigits) => last4DigitSet.add(endDigits))
|
|
27
|
-
return last4DigitArr.length === last4DigitSet.size
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Check if there are multiple addresses but somehow a preferred address hasn't been set yet
|
|
31
|
-
// Should never happen in production but makes the change backwards compatible for testing env
|
|
32
|
-
function accidentallyBypassedValidation(
|
|
33
|
-
newAddresses: string[] | null,
|
|
34
|
-
e164Number: string,
|
|
35
|
-
secureSendPhoneNumberMapping: SecureSendPhoneNumberMapping
|
|
36
|
-
) {
|
|
37
|
-
const validatedAddress =
|
|
38
|
-
secureSendPhoneNumberMapping[e164Number] && secureSendPhoneNumberMapping[e164Number].address
|
|
39
|
-
return newAddresses && newAddresses.length > 1 && !validatedAddress
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export function checkIfValidationRequired(
|
|
43
|
-
oldAddresses: string[],
|
|
44
|
-
possibleAddresses: string[],
|
|
45
|
-
userAddress: string,
|
|
46
|
-
secureSendPhoneNumberMapping: SecureSendPhoneNumberMapping,
|
|
47
|
-
e164Number: string
|
|
48
|
-
) {
|
|
49
|
-
// No validation needed if there is only 1 possible address
|
|
50
|
-
if (possibleAddresses.length < 2) {
|
|
51
|
-
return AddressValidationType.NONE
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
if (
|
|
55
|
-
newAddressesAdded(oldAddresses, possibleAddresses) ||
|
|
56
|
-
accidentallyBypassedValidation(possibleAddresses, e164Number, secureSendPhoneNumberMapping)
|
|
57
|
-
) {
|
|
58
|
-
Logger.debug(TAG, 'Address needs to be validated by user')
|
|
59
|
-
// Adding user's address so they don't mistakenly verify with last 4 digits of their own address
|
|
60
|
-
if (last4DigitsAreUnique([userAddress, ...possibleAddresses])) {
|
|
61
|
-
return AddressValidationType.PARTIAL
|
|
62
|
-
}
|
|
63
|
-
return AddressValidationType.FULL
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
return AddressValidationType.NONE
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function hasSpecialChars(address: string, addressValidationType: AddressValidationType) {
|
|
70
|
-
const regex = new RegExp('[^0-9A-Za-z]', 'g')
|
|
71
|
-
const cleanedAddress = address.replace(regex, '')
|
|
72
|
-
|
|
73
|
-
if (cleanedAddress !== address) {
|
|
74
|
-
const errorMessage =
|
|
75
|
-
addressValidationType === AddressValidationType.FULL
|
|
76
|
-
? ErrorMessages.ADDRESS_VALIDATION_FULL_POORLY_FORMATTED
|
|
77
|
-
: ErrorMessages.ADDRESS_VALIDATION_PARTIAL_POORLY_FORMATTED
|
|
78
|
-
throw Error(errorMessage)
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function validateFullAddressAndReturnMatch(
|
|
83
|
-
userInputtedAddress: string,
|
|
84
|
-
possibleRecievingAddresses: string[],
|
|
85
|
-
userAddress: string
|
|
86
|
-
) {
|
|
87
|
-
if (userInputtedAddress.length !== 42 || userInputtedAddress.slice(0, 2) !== '0x') {
|
|
88
|
-
throw Error(ErrorMessages.ADDRESS_VALIDATION_FULL_POORLY_FORMATTED)
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
if (userInputtedAddress === userAddress) {
|
|
92
|
-
throw Error(ErrorMessages.ADDRESS_VALIDATION_FULL_OWN_ADDRESS)
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
if (!possibleRecievingAddresses.includes(userInputtedAddress)) {
|
|
96
|
-
throw Error(ErrorMessages.ADDRESS_VALIDATION_NO_MATCH)
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
return userInputtedAddress
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
function validatePartialAddressAndReturnMatch(
|
|
103
|
-
lastFourDigitsOfUserInputtedAddress: string,
|
|
104
|
-
possibleRecievingAddresses: string[],
|
|
105
|
-
userAddress: string
|
|
106
|
-
) {
|
|
107
|
-
if (lastFourDigitsOfUserInputtedAddress.length !== 4) {
|
|
108
|
-
throw Error(ErrorMessages.ADDRESS_VALIDATION_PARTIAL_POORLY_FORMATTED)
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
if (lastFourDigitsOfUserInputtedAddress === userAddress.slice(-4)) {
|
|
112
|
-
throw Error(ErrorMessages.ADDRESS_VALIDATION_PARTIAL_OWN_ADDRESS)
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const targetAddress = possibleRecievingAddresses.find(
|
|
116
|
-
(address) => address.slice(-4) === lastFourDigitsOfUserInputtedAddress
|
|
117
|
-
)
|
|
118
|
-
|
|
119
|
-
if (!targetAddress) {
|
|
120
|
-
throw Error(ErrorMessages.ADDRESS_VALIDATION_NO_MATCH)
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
return targetAddress
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
export function validateAndReturnMatch(
|
|
127
|
-
userInputOfFullAddressOrLastFourDigits: string,
|
|
128
|
-
possibleRecievingAddresses: string[],
|
|
129
|
-
userAddress: string,
|
|
130
|
-
addressValidationType: AddressValidationType
|
|
131
|
-
) {
|
|
132
|
-
const userInput = userInputOfFullAddressOrLastFourDigits.toLowerCase()
|
|
133
|
-
const possibleAddresses = possibleRecievingAddresses.map((address) => address.toLowerCase())
|
|
134
|
-
const userOwnAddress = userAddress.toLowerCase()
|
|
135
|
-
|
|
136
|
-
hasSpecialChars(userInputOfFullAddressOrLastFourDigits, addressValidationType)
|
|
137
|
-
|
|
138
|
-
if (addressValidationType === AddressValidationType.FULL) {
|
|
139
|
-
return validateFullAddressAndReturnMatch(userInput, possibleAddresses, userOwnAddress)
|
|
140
|
-
}
|
|
141
|
-
return validatePartialAddressAndReturnMatch(userInput, possibleAddresses, userOwnAddress)
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
export function getAddressValidationType(
|
|
145
|
-
recipient: Recipient,
|
|
146
|
-
secureSendPhoneNumberMapping: SecureSendPhoneNumberMapping
|
|
147
|
-
) {
|
|
148
|
-
const e164PhoneNumber = recipient.e164PhoneNumber
|
|
149
|
-
|
|
150
|
-
if (
|
|
151
|
-
!e164PhoneNumber ||
|
|
152
|
-
!secureSendPhoneNumberMapping[e164PhoneNumber] ||
|
|
153
|
-
!secureSendPhoneNumberMapping[e164PhoneNumber].addressValidationType
|
|
154
|
-
) {
|
|
155
|
-
return AddressValidationType.NONE
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
return secureSendPhoneNumberMapping[e164PhoneNumber].addressValidationType
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
export function getSecureSendAddress(
|
|
162
|
-
recipient: Recipient,
|
|
163
|
-
secureSendPhoneNumberMapping: SecureSendPhoneNumberMapping
|
|
164
|
-
) {
|
|
165
|
-
const e164PhoneNumber = recipientHasNumber(recipient) ? recipient.e164PhoneNumber : undefined
|
|
166
|
-
if (!e164PhoneNumber || !secureSendPhoneNumberMapping[e164PhoneNumber]) {
|
|
167
|
-
return undefined
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
return secureSendPhoneNumberMapping[e164PhoneNumber].address
|
|
171
|
-
}
|
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
import { fireEvent, render } from '@testing-library/react-native'
|
|
2
|
-
import * as React from 'react'
|
|
3
|
-
import { Provider } from 'react-redux'
|
|
4
|
-
import { SendOrigin } from 'src/analytics/types'
|
|
5
|
-
import { AddressValidationType } from 'src/identity/reducer'
|
|
6
|
-
import { navigate } from 'src/navigator/NavigationService'
|
|
7
|
-
import { Screens } from 'src/navigator/Screens'
|
|
8
|
-
import ValidateRecipientAccount from 'src/send/ValidateRecipientAccount'
|
|
9
|
-
import { createMockStore, getMockStackScreenProps } from 'test/utils'
|
|
10
|
-
import {
|
|
11
|
-
mockAccountInvite,
|
|
12
|
-
mockCusdAddress,
|
|
13
|
-
mockE164NumberInvite,
|
|
14
|
-
mockInvitableRecipient2,
|
|
15
|
-
} from 'test/values'
|
|
16
|
-
|
|
17
|
-
describe('ValidateRecipientAccount', () => {
|
|
18
|
-
beforeEach(() => {
|
|
19
|
-
jest.clearAllMocks()
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
it('renders correctly when full validation required', () => {
|
|
23
|
-
const store = createMockStore({
|
|
24
|
-
identity: {
|
|
25
|
-
secureSendPhoneNumberMapping: {
|
|
26
|
-
[mockE164NumberInvite]: {
|
|
27
|
-
addressValidationType: AddressValidationType.FULL,
|
|
28
|
-
validationSuccessful: false,
|
|
29
|
-
},
|
|
30
|
-
},
|
|
31
|
-
},
|
|
32
|
-
})
|
|
33
|
-
const tree = render(
|
|
34
|
-
<Provider store={store}>
|
|
35
|
-
<ValidateRecipientAccount
|
|
36
|
-
{...getMockStackScreenProps(Screens.ValidateRecipientAccount, {
|
|
37
|
-
recipient: mockInvitableRecipient2,
|
|
38
|
-
origin: SendOrigin.AppSendFlow,
|
|
39
|
-
})}
|
|
40
|
-
/>
|
|
41
|
-
</Provider>
|
|
42
|
-
)
|
|
43
|
-
expect(tree).toMatchSnapshot()
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
it('renders correctly when partial validation required', () => {
|
|
47
|
-
const store = createMockStore({
|
|
48
|
-
identity: {
|
|
49
|
-
secureSendPhoneNumberMapping: {
|
|
50
|
-
[mockE164NumberInvite]: {
|
|
51
|
-
addressValidationType: AddressValidationType.PARTIAL,
|
|
52
|
-
validationSuccessful: false,
|
|
53
|
-
},
|
|
54
|
-
},
|
|
55
|
-
},
|
|
56
|
-
})
|
|
57
|
-
const tree = render(
|
|
58
|
-
<Provider store={store}>
|
|
59
|
-
<ValidateRecipientAccount
|
|
60
|
-
{...getMockStackScreenProps(Screens.ValidateRecipientAccount, {
|
|
61
|
-
recipient: mockInvitableRecipient2,
|
|
62
|
-
origin: SendOrigin.AppSendFlow,
|
|
63
|
-
})}
|
|
64
|
-
/>
|
|
65
|
-
</Provider>
|
|
66
|
-
)
|
|
67
|
-
expect(tree).toMatchSnapshot()
|
|
68
|
-
})
|
|
69
|
-
|
|
70
|
-
it('typing correct last four of account enables submit button', () => {
|
|
71
|
-
const store = createMockStore({
|
|
72
|
-
identity: {
|
|
73
|
-
secureSendPhoneNumberMapping: {
|
|
74
|
-
[mockE164NumberInvite]: {
|
|
75
|
-
addressValidationType: AddressValidationType.PARTIAL,
|
|
76
|
-
validationSuccessful: false,
|
|
77
|
-
},
|
|
78
|
-
},
|
|
79
|
-
},
|
|
80
|
-
})
|
|
81
|
-
const tree = render(
|
|
82
|
-
<Provider store={store}>
|
|
83
|
-
<ValidateRecipientAccount
|
|
84
|
-
{...getMockStackScreenProps(Screens.ValidateRecipientAccount, {
|
|
85
|
-
recipient: mockInvitableRecipient2,
|
|
86
|
-
origin: SendOrigin.AppSendFlow,
|
|
87
|
-
})}
|
|
88
|
-
/>
|
|
89
|
-
</Provider>
|
|
90
|
-
)
|
|
91
|
-
expect(tree.getByTestId('ConfirmAccountButton')).toBeDisabled()
|
|
92
|
-
fireEvent.changeText(tree.getByTestId('SingleDigitInput/digit0'), mockCusdAddress[38])
|
|
93
|
-
fireEvent.changeText(tree.getByTestId('SingleDigitInput/digit1'), mockCusdAddress[39])
|
|
94
|
-
fireEvent.changeText(tree.getByTestId('SingleDigitInput/digit2'), mockCusdAddress[40])
|
|
95
|
-
fireEvent.changeText(tree.getByTestId('SingleDigitInput/digit3'), mockCusdAddress[41])
|
|
96
|
-
expect(tree.getByTestId('ConfirmAccountButton')).not.toBeDisabled()
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
it('enables submit button for full validation', () => {
|
|
100
|
-
const store = createMockStore({
|
|
101
|
-
identity: {
|
|
102
|
-
secureSendPhoneNumberMapping: {
|
|
103
|
-
[mockE164NumberInvite]: {
|
|
104
|
-
addressValidationType: AddressValidationType.FULL,
|
|
105
|
-
validationSuccessful: false,
|
|
106
|
-
},
|
|
107
|
-
},
|
|
108
|
-
},
|
|
109
|
-
})
|
|
110
|
-
const tree = render(
|
|
111
|
-
<Provider store={store}>
|
|
112
|
-
<ValidateRecipientAccount
|
|
113
|
-
{...getMockStackScreenProps(Screens.ValidateRecipientAccount, {
|
|
114
|
-
recipient: mockInvitableRecipient2,
|
|
115
|
-
origin: SendOrigin.AppSendFlow,
|
|
116
|
-
})}
|
|
117
|
-
/>
|
|
118
|
-
</Provider>
|
|
119
|
-
)
|
|
120
|
-
|
|
121
|
-
expect(tree.getByTestId('ConfirmAccountButton')).toBeDisabled()
|
|
122
|
-
fireEvent.changeText(
|
|
123
|
-
tree.getByTestId('ValidateRecipientAccount/TextInput'),
|
|
124
|
-
mockCusdAddress[38]
|
|
125
|
-
)
|
|
126
|
-
expect(tree.getByTestId('ConfirmAccountButton')).not.toBeDisabled()
|
|
127
|
-
})
|
|
128
|
-
|
|
129
|
-
it('navigates to send enter amount with validated address when validation is successful', () => {
|
|
130
|
-
const store = createMockStore({
|
|
131
|
-
identity: {
|
|
132
|
-
secureSendPhoneNumberMapping: {
|
|
133
|
-
[mockE164NumberInvite]: {
|
|
134
|
-
addressValidationType: AddressValidationType.NONE,
|
|
135
|
-
validationSuccessful: false,
|
|
136
|
-
},
|
|
137
|
-
},
|
|
138
|
-
},
|
|
139
|
-
})
|
|
140
|
-
|
|
141
|
-
const props = getMockStackScreenProps(Screens.ValidateRecipientAccount, {
|
|
142
|
-
recipient: mockInvitableRecipient2,
|
|
143
|
-
origin: SendOrigin.AppSendFlow,
|
|
144
|
-
})
|
|
145
|
-
|
|
146
|
-
const tree = render(
|
|
147
|
-
<Provider store={store}>
|
|
148
|
-
<ValidateRecipientAccount {...props} />
|
|
149
|
-
</Provider>
|
|
150
|
-
)
|
|
151
|
-
|
|
152
|
-
const updatedStore = createMockStore({
|
|
153
|
-
identity: {
|
|
154
|
-
secureSendPhoneNumberMapping: {
|
|
155
|
-
[mockE164NumberInvite]: {
|
|
156
|
-
addressValidationType: AddressValidationType.NONE,
|
|
157
|
-
address: mockAccountInvite,
|
|
158
|
-
validationSuccessful: true,
|
|
159
|
-
},
|
|
160
|
-
},
|
|
161
|
-
},
|
|
162
|
-
})
|
|
163
|
-
|
|
164
|
-
tree.rerender(
|
|
165
|
-
<Provider store={updatedStore}>
|
|
166
|
-
<ValidateRecipientAccount {...props} />
|
|
167
|
-
</Provider>
|
|
168
|
-
)
|
|
169
|
-
|
|
170
|
-
expect(navigate).toHaveBeenCalledWith(Screens.SendEnterAmount, {
|
|
171
|
-
origin: SendOrigin.AppSendFlow,
|
|
172
|
-
isFromScan: false,
|
|
173
|
-
defaultTokenIdOverride: undefined,
|
|
174
|
-
forceTokenId: undefined,
|
|
175
|
-
recipient: {
|
|
176
|
-
...mockInvitableRecipient2,
|
|
177
|
-
address: mockAccountInvite,
|
|
178
|
-
},
|
|
179
|
-
isMiniPayRecipient: false,
|
|
180
|
-
})
|
|
181
|
-
})
|
|
182
|
-
})
|