Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
- added: `AGENT_TEST_MODE` config setting and iOS debug-build `EdgeTestAnimations` switch that quiet the app for automated UI tests
- changed: Blur on iOS now uses `expo-blur`, the same backend as Android 12+, so `rn-id-blurview` (an old-architecture view manager with no new-architecture support) is no longer a dependency.
- changed: Stealth Swap works with Houdini switched off in the exchange settings, as Stealth Send already does
- changed: Swaps with a single provider quote no longer offer the provider picker
- changed: Draw gradients with expo-linear-gradient and scroll around the keyboard with react-native-keyboard-controller, replacing two libraries that rendered through the new architecture's legacy compatibility layers (react-native-linear-gradient and the unmaintained react-native-keyboard-aware-scroll-view).
- changed: The feedback survey now uses the same keyboard offset on both platforms, replacing a per-platform workaround the old scroll library required.
- changed: Upgrade react-native-sound to 0.13.0 and react-native-haptic-feedback to 3.0.0, both now codegen-native under the new architecture.
Expand Down
68 changes: 68 additions & 0 deletions src/__tests__/scenes/SwapConfirmationScene.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
import process from 'process'
import * as React from 'react'

import { PoweredByCard } from '../../components/cards/PoweredByCard'
import * as SwapVerifyTermsModal from '../../components/modals/SwapVerifyTermsModal'
import {
pickBestQuote,
Expand Down Expand Up @@ -468,6 +469,73 @@ describe('SwapConfirmationScene', () => {
})
})

describe('the powered-by card', () => {
const makePickerQuote = (pluginId: string): EdgeSwapQuote => {
const fakeRequest: any = { fromWallet: btcWallet, toWallet: ethWallet }
return {
swapInfo: dummySwapInfo,
request: fakeRequest,
isEstimate: false,
fromNativeAmount: '10000',
toNativeAmount: '10000',
networkFee: { currencyCode: 'BTC', nativeAmount: '1', tokenId: null },
pluginId,
approve: async () => {
throw new Error('unreachable')
},
close: async () => {}
}
}

const renderWithQuotes = (
sceneQuotes: EdgeSwapQuote[]
): ReturnType<typeof render> => {
const rootState: FakeState = { ...fakeRootState, core: { account } }
return render(
<FakeProviders initialState={rootState}>
<SwapConfirmationScene
{...fakeSwapTabSceneProps('swapConfirmation', {
quotes: sceneQuotes,
selectedQuote: sceneQuotes[0],
onApprove: () => undefined,
swapRequest: sceneQuotes[0].request,
swapRequestOptions: {}
})}
/>
</FakeProviders>
)
}

it('cannot open the provider picker with a single quote', () => {
if (btcWallet == null || ethWallet == null) return
const rendered = renderWithQuotes([makePickerQuote('bitcoin')])

expect(rendered.UNSAFE_getByType(PoweredByCard).props.onPress).toBe(
undefined
)
expect(rendered.queryByText(lstrings.tap_to_change_provider)).toBe(null)

rendered.unmount()
})

it('opens the provider picker with several quotes', () => {
if (btcWallet == null || ethWallet == null) return
const rendered = renderWithQuotes([
makePickerQuote('bitcoin'),
makePickerQuote('ethereum')
])

expect(
rendered.UNSAFE_getByType(PoweredByCard).props.onPress
).toBeInstanceOf(Function)
expect(rendered.queryByText(lstrings.tap_to_change_provider)).not.toBe(
null
)

rendered.unmount()
})
})

let quotes: TestSwapQuote[]
let bestQuote: EdgeSwapQuote

Expand Down
119 changes: 19 additions & 100 deletions src/__tests__/scenes/__snapshots__/SwapConfirmationScene.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -1663,47 +1663,26 @@ exports[`SwapConfirmationScene should render with loading props 1`] = `
}
>
<View
accessibilityState={
{
"busy": undefined,
"checked": undefined,
"disabled": false,
"expanded": undefined,
"selected": undefined,
}
}
accessibilityValue={
{
"max": undefined,
"min": undefined,
"now": undefined,
"text": undefined,
}
}
accessible={false}
collapsable={false}
focusable={true}
onClick={[Function]}
onResponderGrant={[Function]}
onResponderMove={[Function]}
onResponderRelease={[Function]}
onResponderTerminate={[Function]}
onResponderTerminationRequest={[Function]}
onStartShouldSetResponder={[Function]}
style={
{
"alignSelf": "stretch",
"borderRadius": 16,
"marginBottom": 11,
"marginLeft": 11,
"marginRight": 11,
"marginTop": 11,
"opacity": 1,
"paddingBottom": 11,
"paddingLeft": 11,
"paddingRight": 11,
"paddingTop": 11,
}
[
{
"alignSelf": "stretch",
"borderRadius": 16,
},
{
"marginBottom": 11,
"marginLeft": 11,
"marginRight": 11,
"marginTop": 11,
},
{
"paddingBottom": 11,
"paddingLeft": 11,
"paddingRight": 11,
"paddingTop": 11,
},
undefined,
]
}
>
<View
Expand Down Expand Up @@ -1824,67 +1803,7 @@ exports[`SwapConfirmationScene should render with loading props 1`] = `
}
/>
</View>
<View
style={
{
"flexDirection": "row",
}
}
>
<Text
adjustsFontSizeToFit={true}
allowFontScaling={false}
minimumFontScale={0.65}
minimumFontSize={11.05}
numberOfLines={1}
style={
[
{
"color": "#FFFFFF",
"fontFamily": "Quicksand-Regular",
"fontSize": 22,
"includeFontPadding": false,
},
{
"color": "#888888",
"fontSize": 17,
},
null,
]
}
>
Tap to Change Provider
</Text>
</View>
</View>
<Text
adjustsFontSizeToFit={true}
allowFontScaling={false}
selectable={false}
style={
[
{
"color": undefined,
"fontSize": 12,
},
[
{
"color": "#00f1a2",
"fontSize": 22,
},
undefined,
],
{
"fontFamily": "Feather",
"fontStyle": "normal",
"fontWeight": "normal",
},
{},
]
}
>
</Text>
</View>
</View>
</View>
Expand Down
7 changes: 5 additions & 2 deletions src/components/scenes/SwapConfirmationScene.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,11 @@ export const SwapConfirmationScene: React.FC<Props> = (props: Props) => {
swapRequest,
swapRequestOptions
} = route.params
// A Stealth Swap's provider is fixed, so its powered-by card is not tappable:
// The powered-by card opens the provider picker only when there is another
// quote to pick. A Stealth Swap's provider is fixed, and a single quote
// leaves nothing to choose:
const isStealth = swapRequest.privacy === 'required'
const canChangeProvider = !isStealth && quotes.length > 1

const dispatch = useDispatch()
const theme = useTheme()
Expand Down Expand Up @@ -541,7 +544,7 @@ export const SwapConfirmationScene: React.FC<Props> = (props: Props) => {
<PoweredByCard
iconUri={getSwapPluginIconUri(selectedQuote.pluginId, theme)}
poweredByText={exchangeName}
onPress={isStealth ? undefined : handlePoweredByTap}
onPress={canChangeProvider ? handlePoweredByTap : undefined}
/>
</EdgeAnim>
{selectedQuote.isEstimate && !showPriceImpact ? (
Expand Down
Loading