Compare commits

..
Author SHA1 Message Date
Yevheniia Berdnyk 0f3538756a e2e: separated tests to run in PRs 2024-07-15 12:44:56 +03:00
55 changed files with 337 additions and 941 deletions
+1
View File
@@ -4,6 +4,7 @@ DEFAULT_NETWORK=mainnet_rpc
DEV_BUILD=1
ETHEREUM_DEV_CLUSTER=1
EXTENSIONS=0
FLEET=status.prod
GROUP_CHATS_ENABLED=1
LOG_LEVEL=info
MAILSERVER_CONFIRMATIONS_ENABLED=1
+1 -1
View File
@@ -2,7 +2,7 @@ DEBUG_WEBVIEW=1
DEFAULT_NETWORK=goerli_rpc
ETHEREUM_DEV_CLUSTER=1
EXTENSIONS=0
FLEET=status.staging
FLEET=status.prod
GROUP_CHATS_ENABLED=1
LOG_LEVEL=debug
MAILSERVER_CONFIRMATIONS_ENABLED=0
+1
View File
@@ -3,6 +3,7 @@ DEBUG_WEBVIEW=1
DEFAULT_NETWORK=goerli_rpc
ETHEREUM_DEV_CLUSTER=1
EXTENSIONS=0
FLEET=status.prod
GROUP_CHATS_ENABLED=1
LOG_LEVEL=debug
MAILSERVER_CONFIRMATIONS_ENABLED=1
+1
View File
@@ -2,6 +2,7 @@ DEBUG_WEBVIEW=1
DEFAULT_NETWORK=mainnet_rpc
ETHEREUM_DEV_CLUSTER=1
EXTENSIONS=0
FLEET=status.prod
GROUP_CHATS_ENABLED=1
LOG_LEVEL=info
MAILSERVER_CONFIRMATIONS_ENABLED=1
+1
View File
@@ -2,6 +2,7 @@ DEBUG_WEBVIEW=0
DEFAULT_NETWORK=mainnet_rpc
ETHEREUM_DEV_CLUSTER=0
EXTENSIONS=0
FLEET=status.prod
GROUP_CHATS_ENABLED=1
LOG_LEVEL=
MAILSERVER_CONFIRMATIONS_ENABLED=1
+1 -1
View File
@@ -1 +1 @@
2.29.20538
2.29.0
+1 -1
View File
@@ -99,7 +99,7 @@ pipeline {
--rerun_count=2 \
--testrail_report=True \
-m testrail_id \
-m \"nightly\" \
-m \"new_ui_critical or new_ui_medium\" \
-k \"${params.KEYWORD_EXPRESSION}\" \
--apk=${params.APK_URL ?: apk_path}
"""
+3 -1
View File
@@ -35,11 +35,13 @@ pipeline {
description: 'OBSOLETE ARGUMENT TO BE REMOVED',
defaultValue: 'DUMMY',
)
/* Commented to use TEST_MARKERS values from job params
string(
name: 'TEST_MARKERS',
description: 'Marker expression for matching tests to run.',
defaultValue: 'smoke',
defaultValue: 'new_ui_critical',
)
*/
}
options {
+2 -2
View File
@@ -915,7 +915,7 @@ PODS:
- glog
- RCT-Folly (= 2022.05.16.00)
- React-Core
- react-native-compat (2.11.2):
- react-native-compat (2.12.2):
- glog
- RCT-Folly (= 2022.05.16.00)
- React-Core
@@ -1517,7 +1517,7 @@ SPEC CHECKSUMS:
react-native-blob-util: 600972b1782380a5a7d5db61a3817ea32349dae9
react-native-blur: 799045500f56146afc46245148080e7b7623cb75
react-native-cameraroll: af8eec1e585d053ff485d98ec837f9a8a11b5745
react-native-compat: 3af9add14d349701306d3d052638435f6795ac2c
react-native-compat: 84e00e8dcff9251278c0d48f2bce81f4502e3925
react-native-config: 5330c8258265c1e5fdb8c009d2cabd6badd96727
react-native-get-random-values: 21325b2244dfa6b58878f51f9aa42821e7ba3d06
react-native-hole-view: 6935448993bac79f2b5a4ad7e9741094cf810679
@@ -18,7 +18,6 @@
[{:keys [current-log-level
telemetry-enabled?
light-client-enabled?
store-confirmations-enabled?
current-fleet
test-networks-enabled?
is-goerli-enabled?
@@ -78,15 +77,6 @@
[:wakuv2.ui/toggle-light-client (not light-client-enabled?)])
:accessory :switch
:active light-client-enabled?}
{:size :small
:title (i18n/label :t/store-confirmations)
:accessibility-label :store-confirmations
:container-margin-bottom 8
:on-press
#(re-frame/dispatch
[:wakuv2.ui/toggle-store-confirmations (not store-confirmations-enabled?)])
:accessory :switch
:active store-confirmations-enabled?}
{:size :small
:title "Testnet mode"
:accessibility-label :test-networks-enabled
@@ -124,14 +114,13 @@
(views/defview advanced-settings
[]
(views/letsubs [test-networks-enabled? [:profile/test-networks-enabled?]
is-goerli-enabled? [:profile/is-goerli-enabled?]
light-client-enabled? [:profile/light-client-enabled?]
store-confirmations-enabled? [:profile/store-confirmations-enabled?]
telemetry-enabled? [:profile/telemetry-enabled?]
current-log-level [:log-level/current-log-level]
current-fleet [:fleets/current-fleet]
peer-syncing-enabled? [:profile/peer-syncing-enabled?]]
(views/letsubs [test-networks-enabled? [:profile/test-networks-enabled?]
is-goerli-enabled? [:profile/is-goerli-enabled?]
light-client-enabled? [:profile/light-client-enabled?]
telemetry-enabled? [:profile/telemetry-enabled?]
current-log-level [:log-level/current-log-level]
current-fleet [:fleets/current-fleet]
peer-syncing-enabled? [:profile/peer-syncing-enabled?]]
[:<>
[quo/page-nav
{:type :title
@@ -141,14 +130,13 @@
:on-press #(rf/dispatch [:navigate-back])}]
[list/flat-list
{:data (flat-list-data
{:current-log-level current-log-level
:telemetry-enabled? telemetry-enabled?
:light-client-enabled? light-client-enabled?
:store-confirmations-enabled? store-confirmations-enabled?
:current-fleet current-fleet
:dev-mode? false
:test-networks-enabled? test-networks-enabled?
:is-goerli-enabled? is-goerli-enabled?
:peer-syncing-enabled? peer-syncing-enabled?})
{:current-log-level current-log-level
:telemetry-enabled? telemetry-enabled?
:light-client-enabled? light-client-enabled?
:current-fleet current-fleet
:dev-mode? false
:test-networks-enabled? test-networks-enabled?
:is-goerli-enabled? is-goerli-enabled?
:peer-syncing-enabled? peer-syncing-enabled?})
:key-fn (fn [_ i] (str i))
:render-fn render-item}]]))
+16
View File
@@ -0,0 +1,16 @@
(ns legacy.status-im.utils.hex
(:require
[clojure.string :as string]))
(defn normalize-hex
[hex]
(when hex
(string/lower-case (if (string/starts-with? hex "0x")
(subs hex 2)
hex))))
(defn valid-hex?
[hex]
(let [hex (normalize-hex hex)]
(and (re-matches #"^[0-9a-fA-F]+$" hex)
(not= (js/parseInt hex 16) 0))))
-16
View File
@@ -137,19 +137,3 @@
:on-error #(log/error "failed to set light client"
{:error %
:enabled? enabled?})}]})
(rf/defn toggle-store-confirmations
{:events [:wakuv2.ui/toggle-store-confirmations]}
[{:keys [db]} enabled?]
{:db (assoc-in db
[:profile/profile :wakuv2-config :EnableStoreConfirmationForMessagesSent]
enabled?)
:json-rpc/call [{:method "wakuext_setStoreConfirmationForMessagesSent"
:params [{:enabled enabled?}]
:on-success (fn []
(log/info "store confirmation set successfully" enabled?)
(re-frame/dispatch [:logout]))
:on-error #(log/error "failed to set store confirmation"
{:error %
:enabled? enabled?})}]})
@@ -79,20 +79,14 @@
[counter-view counter])
[rn/view {:style (style/collectible-border theme)}]]]))
(defn invalid-image?
[image-src]
(or (nil? image-src)
(string/blank? image-src)))
(defn view-internal
[{:keys [container-style square? on-press counter image-src native-ID supported-file?
on-collectible-load aspect-ratio gradient-color-index]
:or {gradient-color-index :gradient-1
on-collectible-load (fn [])}}]
(let [theme (quo.theme/use-theme)
[error? set-error] (rn/use-state (invalid-image? image-src))]
(rn/use-effect #(set-error (invalid-image? image-src))
[image-src])
[error? set-error] (rn/use-state (or (nil? image-src)
(string/blank? image-src)))]
[rn/pressable
{:style (merge container-style (style/container aspect-ratio))
:accessibility-label :expanded-collectible
@@ -1,25 +0,0 @@
(ns quo.components.slideshow.slider-bar.component-spec
(:require
[quo.components.slideshow.slider-bar.view :as slider-bar]
[test-helpers.component :as h]))
(h/describe "Slideshow: slider-bar"
(h/test "default render"
(h/render-with-theme-provider [slider-bar/view {:accessibility-label :slider-bar}])
(h/is-truthy (h/query-by-label-text :slider-bar)))
(h/test "render with total-amount and active-index"
(h/render-with-theme-provider [slider-bar/view
{:total-amount 4
:active-index 1
:accessibility-label :slider-bar}])
(h/is-truthy (h/query-by-label-text :slider-bar))
(h/is-equal 4 (count (h/query-all-by-label-text :slide-bar-item))))
(h/test "render with total-amount active-index and possible scroll"
(h/render-with-theme-provider [slider-bar/view
{:total-amount 10
:active-index 7
:accessibility-label :slider-bar}])
(h/is-truthy (h/query-by-label-text :slider-bar))
(h/is-equal 10 (count (h/query-all-by-label-text :slide-bar-item)))))
@@ -1,14 +0,0 @@
(ns quo.components.slideshow.slider-bar.schema)
(def ?schema
[:=>
[:cat
[:map {:closed true}
[:total-amount {:optional true} [:maybe :int]]
[:active-index {:optional true} :int]
[:customization-color {:optional true}
[:maybe :schema.common/customization-color]]
[:blur? {:optional true} [:maybe :boolean]]
[:accessibility-label {:optional true} [:maybe :keyword]]
[:container-style {:optional true} [:maybe :map]]]]
:any])
@@ -1,31 +0,0 @@
(ns quo.components.slideshow.slider-bar.style
(:require
[quo.foundations.colors :as colors]))
(def list-wrapper
{:align-items :center})
(defn list-bar
[bar-width]
{:width bar-width})
(defn item-wrapper
[{:keys [size spacing]}]
{:width size
:height size
:margin-left spacing
:flex 1
:align-items :center
:justify-content :center})
(defn item
[{:keys [size spacing active? customization-color theme blur?]}]
{:width size
:height size
:border-radius spacing
:background-color
(cond
(and blur? active?) colors/white
(and blur? (not active?)) colors/white-opa-10
(and (not blur?) active?) (colors/resolve-color customization-color theme)
:else (colors/theme-colors colors/neutral-20 colors/neutral-80 theme))})
@@ -1,150 +0,0 @@
(ns quo.components.slideshow.slider-bar.view
(:require
[quo.components.slideshow.slider-bar.schema :as component-schema]
[quo.components.slideshow.slider-bar.style :as style]
[quo.theme]
[react-native.core :as rn]
[react-native.reanimated :as reanimated]
[schema.core :as schema]))
(def item-size 8)
(def item-spacing item-size)
(def max-length 6)
(def bar-width (* (+ item-spacing item-size) max-length))
(def micro-scale 0.25)
(def small-scale 0.5)
(def medium-scale 0.75)
(def default-scale 1)
(def items-before-scroll
(/ max-length 2))
(defn- calc-relative-index
"Calculates item index in visible area"
[index active-index total-length]
(let [last-index (dec total-length)]
(cond
(< active-index items-before-scroll) index
(> active-index
(- last-index items-before-scroll)) (+ (- index total-length) max-length)
:else (+ (- index active-index) items-before-scroll))))
(defn- calc-first-item-scale
"Calculates scale for first item in visible area"
[active-index]
(cond
(= active-index items-before-scroll) medium-scale
(> active-index items-before-scroll) small-scale
:else default-scale))
(defn- calc-second-item-scale
"Calculates scale for second item in visible area"
[active-index]
(if (> active-index items-before-scroll)
medium-scale
default-scale))
(defn- calc-last-item-scale
"Calculates scale for last item in visible area"
[active-index total-length]
(let [last-index (dec total-length)]
(if (> active-index (- last-index items-before-scroll))
medium-scale
small-scale)))
(defn- calc-last-but-one-item-scale
"Calculates scale for before last item in visible area"
[active-index total-length]
(if (> active-index (- (dec total-length) items-before-scroll))
default-scale
medium-scale))
(defn- get-scale
[index active-index total-length]
(let [relative-index (calc-relative-index index active-index total-length)]
(if (or (= index active-index)
(< total-length max-length))
default-scale
(cond
(< relative-index 0) micro-scale
(= relative-index 0) (calc-first-item-scale active-index)
(= relative-index 1) (calc-second-item-scale active-index)
(= relative-index 4) (calc-last-but-one-item-scale active-index total-length)
(= relative-index 5) (calc-last-item-scale active-index total-length)
(> relative-index 5) micro-scale
:else
default-scale))))
(defn- bar-item
[index _ _ {:keys [active-index total-length customization-color theme blur?]}]
(let [active? (= index active-index)
shared-scale (reanimated/use-shared-value (get-scale index active-index total-length))]
(rn/use-effect (fn []
(let [new-scale-value (get-scale index active-index total-length)]
(reanimated/animate shared-scale new-scale-value)))
[index active-index total-length])
[rn/view
{:key index
:style (style/item-wrapper {:size item-size
:spacing item-spacing})}
[reanimated/view
{:accessibility-label :slide-bar-item
:style
(reanimated/apply-animations-to-style
{:transform [{:scale shared-scale}]}
(style/item {:size item-size
:spacing item-spacing
:active? active?
:customization-color customization-color
:theme theme
:blur? blur?}))}]]))
(defn- get-item-layout
[_ index]
(let [length (+ item-size item-spacing)]
#js {:length length
:index index
:offset (* index length)}))
(defn- view-internal
[{:keys [customization-color blur? accessibility-label container-style]
:as props}]
(let [active-index (or (:active-index props) 0)
total-amount (or (:total-amount props) 1)
theme (quo.theme/use-theme)
flat-list-ref (rn/use-ref-atom nil)
set-flat-list-ref (rn/use-callback #(reset! flat-list-ref %))
center-position 0.5
data (range total-amount)
scroll-to-index (rn/use-callback
(fn []
(some-> ^js @flat-list-ref
(.scrollToIndex #js {:animated true
:index active-index
:viewOffset item-spacing
:viewPosition center-position})))
[flat-list-ref active-index])]
(rn/use-effect scroll-to-index [active-index])
[rn/view
{:style (merge style/list-wrapper container-style)
:accessibility-label accessibility-label}
[reanimated/flat-list
{:style (style/list-bar bar-width)
:data data
:scroll-enabled false
:ref set-flat-list-ref
:shows-horizontal-scroll-indicator false
:bounces false
:horizontal true
:extra-data (str active-index)
:render-data {:active-index active-index
:total-length total-amount
:customization-color customization-color
:theme theme
:blur? blur?}
:get-item-layout get-item-layout
:render-fn bar-item
:key-fn identity}]]))
(def view (schema/instrument #'view-internal component-schema/?schema))
-4
View File
@@ -147,7 +147,6 @@
quo.components.settings.settings-item.view
quo.components.share.qr-code.view
quo.components.share.share-qr-code.view
quo.components.slideshow.slider-bar.view
quo.components.switchers.group-messaging-card.view
quo.components.tabs.account-selector
quo.components.tabs.segmented-tab
@@ -419,9 +418,6 @@
(def qr-code quo.components.share.qr-code.view/view)
(def share-qr-code quo.components.share.share-qr-code.view/view)
;;;; Slideshow
(def slider-bar quo.components.slideshow.slider-bar.view/view)
;;;; SWITCHER
(def group-messaging-card quo.components.switchers.group-messaging-card.view/view)
-1
View File
@@ -87,7 +87,6 @@
quo.components.settings.reorder-item.component-spec
quo.components.settings.settings-item.component-spec
quo.components.share.share-qr-code.component-spec
quo.components.slideshow.slider-bar.component-spec
quo.components.switchers.base-card.component-spec
quo.components.switchers.group-messaging-card.component-spec
quo.components.tags.collectible-tag.component-spec
+1 -1
View File
@@ -72,7 +72,7 @@
;; CONFIG VALUES
(def log-level (string/upper-case (get-config :LOG_LEVEL "")))
(def fleet (get-config :FLEET ""))
(def fleet (get-config :FLEET "waku.sandbox"))
(def apn-topic (get-config :APN_TOPIC "im.status.ethereum"))
(def default-network (get-config :DEFAULT_NETWORK "goerli_rpc"))
(def max-installations 2)
@@ -170,7 +170,6 @@
[status-im.contexts.preview.quo.settings.settings-item :as settings-item]
[status-im.contexts.preview.quo.share.qr-code :as qr-code]
[status-im.contexts.preview.quo.share.share-qr-code :as share-qr-code]
[status-im.contexts.preview.quo.slideshow.slider-bar :as slider-bar]
[status-im.contexts.preview.quo.style :as style]
[status-im.contexts.preview.quo.switcher.group-messaging-card :as
group-messaging-card]
@@ -503,8 +502,6 @@
:component qr-code/view}
{:name :share-qr-code
:component share-qr-code/view}]
:slideshow [{:name :slider-bar
:component slider-bar/view}]
:switchers [{:name :group-messaging-card
:component group-messaging-card/view}
{:name :switcher-cards
@@ -1,49 +0,0 @@
(ns status-im.contexts.preview.quo.slideshow.slider-bar
(:require
[quo.core :as quo]
[react-native.core :as rn]
[status-im.contexts.preview.quo.preview :as preview]))
(def descriptor
[{:key :total-amount
:type :number}
{:label "Blur (dark only)?"
:key :blur?
:type :boolean}
(preview/customization-color-option)])
(defn view
[]
(let [[state set-state] (rn/use-state {:total-amount 10
:active-index 0
:blur? false
:customization-color :blue})]
[preview/preview-container
{:state state
:set-state set-state
:descriptor descriptor
:blur? (:blur? state)
:show-blur-background? true
:blur-dark-only? true}
[rn/view
{:style {:flex-direction :row
:justify-content :center
:gap 10
:padding 10}}
[quo/button
{:type :outline
:style {:disabled true}
:disabled? (zero? (:active-index state))
:icon-only? true
:on-press (fn []
(set-state (update state :active-index dec)))}
:i/chevron-left]
[quo/button
{:type :outline
:disabled? (= (:active-index state)
(dec (:total-amount state)))
:icon-only? true
:on-press (fn []
(set-state (update state :active-index inc)))}
:i/chevron-right]]
[quo/slider-bar state]]))
+13 -15
View File
@@ -29,21 +29,19 @@
[]
(let [log-enabled? (boolean (not-empty config/log-level))]
(assoc (login)
:deviceName (native-module/get-installation-name)
:rootDataDir (native-module/backup-disabled-data-dir)
:rootKeystoreDir (native-module/keystore-dir)
:logLevel (when log-enabled? config/log-level)
:logEnabled log-enabled?
:logFilePath (native-module/log-file-directory)
:verifyTransactionURL config/verify-transaction-url
:verifyENSURL config/verify-ens-url
:verifyENSContractAddress config/verify-ens-contract-address
:verifyTransactionChainID config/verify-transaction-chain-id
:wakuV2LightClient true
:wakuV2Fleet config/fleet
:wakuV2EnableStoreConfirmationForMessagesSent false
:previewPrivacy config/blank-preview?
:testNetworksEnabled config/test-networks-enabled?)))
:deviceName (native-module/get-installation-name)
:rootDataDir (native-module/backup-disabled-data-dir)
:rootKeystoreDir (native-module/keystore-dir)
:logLevel (when log-enabled? config/log-level)
:logEnabled log-enabled?
:logFilePath (native-module/log-file-directory)
:verifyTransactionURL config/verify-transaction-url
:verifyENSURL config/verify-ens-url
:verifyENSContractAddress config/verify-ens-contract-address
:verifyTransactionChainID config/verify-transaction-chain-id
:wakuV2LightClient true
:previewPrivacy config/blank-preview?
:testNetworksEnabled config/test-networks-enabled?)))
(defn strip-file-prefix
[path]
@@ -0,0 +1,18 @@
(ns status-im.contexts.shell.share.wallet.style
(:require
[quo.foundations.colors :as colors]))
(defn indicator-wrapper-style
[active?]
{:width 8
:height 8
:border-radius 4
:background-color colors/white
:opacity (if active? 1.0 0.5)})
(def indicator-list-style
{:display :flex
:flex-direction :row
:align-items :center
:justify-content :center
:gap 8})
@@ -6,6 +6,7 @@
[react-native.platform :as platform]
[reagent.core :as reagent]
[status-im.contexts.shell.share.style :as style]
[status-im.contexts.shell.share.wallet.style :as wallet-style]
[status-im.contexts.wallet.common.utils :as utils]
[status-im.contexts.wallet.common.utils.networks :as network-utils]
[status-im.contexts.wallet.sheets.network-preferences.view :as network-preferences]
@@ -84,6 +85,16 @@
:on-legacy-press on-legacy-press
:on-settings-press on-settings-press}]]]))))
(defn- indicator
[active?]
[rn/view {:style (wallet-style/indicator-wrapper-style active?)}])
(defn- indicator-list
[num-indicators current-index]
[rn/view {:style wallet-style/indicator-list-style}
(for [i (range num-indicators)]
^{:key i} [indicator (= current-index i)])])
(defn render-item
[{:keys [address] :as account}]
[wallet-qr-code-item
@@ -125,7 +136,4 @@
:render-fn render-item}]
(when (> num-accounts 1)
[rn/view {:style {:margin-top 20}}
[quo/slider-bar
{:total-amount num-accounts
:active-index @current-index
:blur? true}]])]))))
[indicator-list num-accounts @current-index]])]))))
@@ -185,7 +185,7 @@
;; We delay the navigation because we need re-frame to update the DB on time.
;; By doing it, we skip a blink while visiting the collectible detail page.
[:dispatch-later
{:ms 17
{:ms 1
:dispatch [:navigate-to :screen/wallet.collectible]}]]})))
(defn- keep-not-empty-value
@@ -79,20 +79,12 @@
(rf/dispatch [:wallet/clear-collectible-details]))
(defn animated-header
[{:keys [scroll-amount title-opacity page-nav-type theme]}]
(let [blur-amount (header-animations/use-blur-amount scroll-amount)
layer-opacity (header-animations/use-layer-opacity
scroll-amount
(colors/theme-colors colors/white-opa-0
colors/neutral-95-opa-0
theme)
(colors/theme-colors colors/white-opa-50
colors/neutral-95-opa-70-blur
theme))
{{preview-uri :uri} :preview-url
{title :name} :collectible-data
{description :name} :collection-data
id :id} (rf/sub [:wallet/collectible-details])]
[{:keys [scroll-amount title-opacity page-nav-type picture title description theme id]}]
(let [blur-amount (header-animations/use-blur-amount scroll-amount)
layer-opacity (header-animations/use-layer-opacity
scroll-amount
(colors/theme-colors colors/white-opa-0 colors/neutral-95-opa-0 theme)
(colors/theme-colors colors/white-opa-50 colors/neutral-95-opa-70-blur theme))]
[rn/view {:style (style/animated-header)}
[reanimated/blur-view
{:style {:flex 1
@@ -105,7 +97,7 @@
[reanimated/view {:style layer-opacity}
[quo/page-nav
{:type page-nav-type
:picture preview-uri
:picture picture
:title title
:description description
:background :blur
@@ -118,7 +110,7 @@
{:content (fn []
[options-drawer/view
{:name title
:image preview-uri
:image picture
:id id}])
:theme theme}])}]
:center-opacity title-opacity}]]]]))
@@ -152,11 +144,10 @@
[_]
(let [selected-tab (reagent/atom :overview)
on-tab-change #(reset! selected-tab %)]
(fn [{:keys [set-title-bottom theme]}]
(fn [{:keys [collectible set-title-bottom theme]}]
(let [title-ref (rn/use-ref-atom nil)
set-title-ref (rn/use-callback #(reset! title-ref %))
animation-shared-element-id (rf/sub [:animation-shared-element-id])
collectible (rf/sub [:wallet/collectible-details])
collectible-owner (rf/sub [:wallet/collectible-details-owner collectible])
aspect-ratio (rf/sub [:wallet/collectible-aspect-ratio])
gradient-color (rf/sub [:wallet/collectible-gradient-color])
@@ -205,14 +196,14 @@
token-id
{:images [collectible-image]
:index 0
:on-options-press #(rf/dispatch
[:show-bottom-sheet
{:content
(fn []
[options-drawer/view
{:name collectible-name
:image preview-uri
:id id}])}])}])))
:on-options-press #(rf/dispatch [:show-bottom-sheet
{:content
(fn []
[options-drawer/view
{:name collectible-name
:image
preview-uri
:id id}])}])}])))
:on-collectible-load (fn []
;; We need to delay the measurement because the
;; navigation has an animation
@@ -250,24 +241,33 @@
(defn view
[_]
(let [{:keys [top]} (safe-area/get-insets)
theme (quo.theme/use-theme)
title-bottom-coord (rn/use-ref-atom 0)
set-title-bottom (rn/use-callback
(fn [_ y _ height]
(reset! title-bottom-coord
(get-title-bottom-y-position y height))))
scroll-amount (reanimated/use-shared-value 0)
title-opacity (reanimated/use-shared-value 0)]
(let [{:keys [top]} (safe-area/get-insets)
theme (quo.theme/use-theme)
title-bottom-coord (rn/use-ref-atom 0)
set-title-bottom (rn/use-callback
(fn [_ y _ height]
(reset! title-bottom-coord
(get-title-bottom-y-position y height))))
scroll-amount (reanimated/use-shared-value 0)
title-opacity (reanimated/use-shared-value 0)
{:keys [collection-data
collectible-data
preview-url]
:as collectible} (rf/sub [:wallet/collectible-details])]
[rn/view {:style (style/background-color theme)}
[animated-header
{:scroll-amount scroll-amount
{:id (:id collectible)
:scroll-amount scroll-amount
:title-opacity title-opacity
:page-nav-type :title-description
:picture (:uri preview-url)
:title (:name collectible-data)
:description (:name collection-data)
:theme theme}]
[reanimated/scroll-view
{:style (style/scroll-view top)
:on-scroll #(on-scroll % scroll-amount title-opacity title-bottom-coord)}
[collectible-details
{:set-title-bottom set-title-bottom
{:collectible collectible
:set-title-bottom set-title-bottom
:theme theme}]]]))
@@ -2,19 +2,8 @@
(:require
[cljs.test :refer-macros [is testing]]
[re-frame.db :as rf-db]
[status-im.contexts.wallet.common.utils.networks :as network-utils]
status-im.contexts.wallet.send.events
[status-im.contexts.wallet.send.utils :as send-utils]
[test-helpers.unit :as h]
[utils.money :as money]))
(defn collectible-with-balance
[balance]
{:name "DOG #1"
:description
"dogs are cute and this one is the cutestdogs are cute and this one is the cutest"
:ownership [{:address "0x01"
:balance balance}]})
[test-helpers.unit :as h]))
(h/deftest-event :wallet/update-receiver-networks
[event-id dispatch]
@@ -174,298 +163,3 @@
result (dispatch [event-id {:amount amount}])]
(testing "amount set"
(is (match? amount (get-in result [:db :wallet :ui :send :amount]))))))
(h/deftest-event :wallet/clean-send-data
[event-id dispatch]
(let [token-symbol "ETH"
token {:symbol "ETH"
:name "Ether"
:networks #{{:chain-id 421614}
{:chain-id 11155420}
{:chain-id 11155111}}}
receiver-networks [421614 11155420]]
(reset! rf-db/app-db
{:wallet {:ui {:send {:token-display-name token-symbol
:token token
:receiver-networks receiver-networks}
:other-props :value}}})
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui]) :send)))))
(h/deftest-event :wallet/select-address-tab
[event-id dispatch]
(let [expected-db {:wallet {:ui {:send {:select-address-tab "tab"}}}}]
(reset! rf-db/app-db
{:wallet {:ui {:send nil}}})
(is (match? expected-db (:db (dispatch [event-id "tab"]))))))
(h/deftest-event :wallet/clean-send-address
[event-id dispatch]
(reset! rf-db/app-db
{:wallet {:ui {:send {:to-address "0x01"
:recipient {:recipient-type :saved-address
:label "label"}
:other-props :value}}}})
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :to-address)))
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :recipient)))
(is (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :other-props)))
(h/deftest-event :wallet/clean-send-amount
[event-id dispatch]
(reset! rf-db/app-db
{:wallet {:ui {:send {:amount 10
:other-props :value}}}})
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :amount)))
(is (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :other-props)))
(h/deftest-event :wallet/clean-disabled-from-networks
[event-id dispatch]
(reset! rf-db/app-db
{:wallet {:ui {:send {:disabled-from-chain-ids [:optimism]
:other-props :value}}}})
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :disabled-from-chain-ids)))
(is (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :other-props)))
(h/deftest-event :wallet/clean-from-locked-amounts
[event-id dispatch]
(reset! rf-db/app-db
{:wallet {:ui {:send {:from-locked-amounts "value"
:other-props :value}}}})
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :from-locked-amounts)))
(is (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :other-props)))
(h/deftest-event :wallet/disable-from-networks
[event-id dispatch]
(let [expected-db {:wallet {:ui {:send {:disabled-from-chain-ids [:optimism]
:other-props :value}}}}]
(reset! rf-db/app-db
{:wallet {:ui {:send {:other-props :value}}}})
(is (match? expected-db (:db (dispatch [event-id [:optimism]]))))))
(h/deftest-event :wallet/unlock-from-amount
[event-id dispatch]
(let [expected-db {:wallet {:ui {:send {:other-props :value
:from-locked-amounts {}}}}}]
(reset! rf-db/app-db
{:wallet {:ui {:send {:other-props :value
:from-locked-amounts {:chain-id [1 10]}}}}})
(is (match? expected-db (:db (dispatch [event-id :chain-id]))))))
(h/deftest-event :wallet/lock-from-amount
[event-id dispatch]
(let [expected-db {:wallet {:ui {:send {:other-props :value
:from-locked-amounts {:amount 10}}}}}]
(reset! rf-db/app-db
{:wallet {:ui {:send {:other-props :value}}}})
(is (match? expected-db (:db (dispatch [event-id :amount 10]))))))
(h/deftest-event :wallet/clean-selected-token
[event-id dispatch]
(reset! rf-db/app-db
{:wallet {:ui {:send {:other-props :value
:token "ETH"
:token-display-name "ETH"
:tx-type :tx/collectible-erc-721}}}})
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :token)))
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :token-display-name)))
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :tx-type)))
(is (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :other-props)))
(h/deftest-event :wallet/clean-selected-collectible
[event-id dispatch]
(reset! rf-db/app-db
{:wallet {:ui {:send {:other-props :value
:collectible "ETH"
:token-display-name "ETH"
:amount 10}}}})
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :collectible)))
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :token-display-name)))
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :amount)))
(is (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :other-props)))
(h/deftest-event :wallet/clean-suggested-routes
[event-id dispatch]
(reset! rf-db/app-db
{:wallet {:ui {:send
{:other-props :value
:suggested-routes ["1" "2"]
:route "1"
:amount 10
:from-values-by-chain [{:chain-id 1} {:chain-id 10} {:chain-id 42161}]
:to-values-by-chain [{:chain-id 1} {:chain-id 10} {:chain-id 42161}]
:sender-network-values [:eth :arb1]
:receiver-network-values [:eth :arb1]
:network-links [{:from-chain-id 1
:to-chain-id 10
:position-diff 1}]
:loading-suggested-routes? false
:suggested-routes-call-timestamp ["1" "2"]}}}})
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :suggested-routes)))
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :route)))
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :amount)))
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :from-values-by-chain)))
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :to-values-by-chain)))
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :sender-network-values)))
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :receiver-network-values)))
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :network-links)))
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send])
:loading-suggested-routes?)))
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send])
:suggested-routes-call-timestamp)))
(is (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :other-props)))
(h/deftest-event :wallet/suggested-routes-error
[event-id dispatch]
(let [sender-network-amounts [{:chain-id 1 :total-amount (money/bignumber "100") :type :loading}
{:chain-id 10 :total-amount (money/bignumber "200") :type :default}]
receiver-network-amounts [{:chain-id 1 :total-amount (money/bignumber "100") :type :loading}]
expected-result {:db {:wallet {:ui {:send
{:sender-network-values
(send-utils/reset-loading-network-amounts-to-zero
sender-network-amounts)
:receiver-network-values
(send-utils/reset-loading-network-amounts-to-zero
receiver-network-amounts)
:loading-suggested-routes? false
:suggested-routes {:best []}}}}}
:fx [[:dispatch
[:toasts/upsert
{:id :send-transaction-error
:type :negative
:text "error"}]]]}]
(reset! rf-db/app-db
{:wallet {:ui {:send {:sender-network-values sender-network-amounts
:receiver-network-values receiver-network-amounts
:route :values
:loading-suggested-routes? true}}}})
(is (match? expected-result (dispatch [event-id {:message "error"}])))))
(h/deftest-event :wallet/reset-network-amounts-to-zero
[event-id dispatch]
(let [sender-network-values [{:chain-id 1 :total-amount (money/bignumber "100") :type :default}
{:chain-id 10 :total-amount (money/bignumber "200") :type :default}]
receiver-network-values [{:chain-id 1 :total-amount (money/bignumber "100") :type :loading}]
disabled-from-chain-ids [:ethereum]
sender-network-zero (send-utils/reset-network-amounts-to-zero
{:network-amounts sender-network-values
:disabled-chain-ids disabled-from-chain-ids})
receiver-network-zero (send-utils/reset-network-amounts-to-zero
{:network-amounts receiver-network-values
:disabled-chain-ids []})]
(testing "if sender-network-value and receiver-network-value are not empty"
(let [expected-db {:wallet {:ui {:send {:other-props :value
:sender-network-values sender-network-zero
:receiver-network-values receiver-network-zero}}}}]
(reset! rf-db/app-db
{:wallet {:ui {:send {:other-props :value
:sender-network-values sender-network-values
:receiver-network-values receiver-network-values
:network-links [{:from-chain-id 1
:to-chain-id 10
:position-diff 1}]}}}})
(is (match? expected-db (:db (dispatch [event-id]))))))
(testing "if only receiver-network-value is empty"
(let [expected-db {:wallet {:ui {:send {:other-props :value
:sender-network-values sender-network-zero}}}}]
(reset! rf-db/app-db
{:wallet {:ui {:send {:other-props :value
:sender-network-values sender-network-values
:receiver-network-values []
:network-links [{:from-chain-id 1
:to-chain-id 10
:position-diff 1}]}}}})
(is (match? expected-db (:db (dispatch [event-id]))))))
(testing "if receiver-network-value and sender-network-values are empty"
(let [expected-db {:wallet {:ui {:send {:other-props :value}}}}]
(reset! rf-db/app-db
{:wallet {:ui {:send {:other-props :value
:sender-network-values []
:receiver-network-values []
:network-links [{:from-chain-id 1
:to-chain-id 10
:position-diff 1}]}}}})
(is (match? expected-db (:db (dispatch [event-id]))))))))
(h/deftest-event :wallet/select-send-address
[event-id dispatch]
(let [address "eth:arb1:0x01"
prefix "eth:arb1:"
to-address "0x01"
recipient {:type :saved-address
:label "0x01...23f"}
stack-id :screen/wallet.select-address
start-flow? false
tx-type :tx/collectible-erc-721]
(testing "testing when collectible balance is more than 1"
(let [collectible (collectible-with-balance 2)
testnet-enabled? false
goerli-enabled? false
receiver-networks (network-utils/resolve-receiver-networks
{:prefix prefix
:testnet-enabled? testnet-enabled?
:goerli-enabled? goerli-enabled?})
expected-result {:db {:wallet {:ui {:send {:other-props :value
:recipient recipient
:to-address to-address
:address-prefix prefix
:receiver-preferred-networks
receiver-networks
:receiver-networks receiver-networks
:tx-type tx-type
:collectible collectible}}}
:profile/profile {:test-networks-enabled? false
:is-goerli-enabled? false}}
:fx [nil
[:dispatch
[:wallet/wizard-navigate-forward
{:current-screen stack-id
:start-flow? start-flow?
:flow-id :wallet-send-flow}]]]}]
(reset! rf-db/app-db
{:wallet {:ui {:send {:other-props :value
:tx-type tx-type
:collectible collectible}}}
:profile/profile {:test-networks-enabled? testnet-enabled?
:is-goerli-enabled? goerli-enabled?}})
(is (match? expected-result
(dispatch [event-id
{:address address
:recipient recipient
:stack-id stack-id
:start-flow? start-flow?}])))))
(testing "testing when collectible balance is 1"
(let [collectible (collectible-with-balance 1)
testnet-enabled? false
goerli-enabled? false
receiver-networks (network-utils/resolve-receiver-networks
{:prefix prefix
:testnet-enabled? testnet-enabled?
:goerli-enabled? goerli-enabled?})
expected-result {:db {:wallet {:ui {:send {:other-props :value
:recipient recipient
:to-address to-address
:address-prefix prefix
:receiver-preferred-networks
receiver-networks
:receiver-networks receiver-networks
:tx-type tx-type
:collectible collectible}}}
:profile/profile {:test-networks-enabled? false
:is-goerli-enabled? false}}
:fx [[:dispatch [:wallet/get-suggested-routes {:amount 1}]]
[:dispatch
[:wallet/wizard-navigate-forward
{:current-screen stack-id
:start-flow? start-flow?
:flow-id :wallet-send-flow}]]]}]
(reset! rf-db/app-db
{:wallet {:ui {:send {:other-props :value
:tx-type tx-type
:collectible collectible}}}
:profile/profile {:test-networks-enabled? testnet-enabled?
:is-goerli-enabled? goerli-enabled?}})
(is (match? expected-result
(dispatch [event-id
{:address address
:recipient recipient
:stack-id stack-id
:start-flow? start-flow?}])))))))
@@ -1,8 +1,8 @@
(ns status-im.contexts.wallet.send.utils
(:require
[legacy.status-im.utils.hex :as utils.hex]
[native-module.core :as native-module]
[status-im.contexts.wallet.common.utils.networks :as network-utils]
[utils.hex :as utils.hex]
[utils.money :as money]))
(defn amount-in-hex
@@ -1,14 +1,17 @@
(ns status-im.contexts.wallet.wallet-connect.effects
(:require
[cljs-bean.core :as bean]
[native-module.core :as native-module]
[promesa.core :as promesa]
[re-frame.core :as rf]
[react-native.wallet-connect :as wallet-connect]
[status-im.config :as config]
[status-im.constants :as constants]
[status-im.contexts.wallet.wallet-connect.signing :as signing]
[status-im.contexts.wallet.wallet-connect.core :as wallet-connect-core]
[status-im.contexts.wallet.wallet-connect.transactions :as transactions]
[utils.i18n :as i18n]
[utils.security.core :as security]))
[utils.security.core :as security]
[utils.transforms :as transforms]))
(rf/reg-fx
:effects.wallet-connect/init
@@ -76,48 +79,36 @@
(rf/reg-fx
:effects.wallet-connect/sign-message
(fn [{:keys [password address data rpc-method on-success on-error]}]
(let [password (security/safe-unmask-data password)]
(-> (condp =
rpc-method
:personal-sign
(signing/personal-sign password address data)
:eth-sign
(signing/eth-sign password address data)
(signing/personal-sign password address data))
(promesa/then on-success)
(promesa/catch on-error)))))
(fn [{:keys [password address data on-success on-error]}]
(-> {:data data
:account address
:password (security/safe-unmask-data password)}
bean/->js
transforms/clj->json
native-module/sign-message
(promesa/then wallet-connect-core/extract-native-call-signature)
(promesa/then on-success)
(promesa/catch on-error))))
(rf/reg-fx
:effects.wallet-connect/sign-transaction
(fn [{:keys [password address chain-id tx on-success on-error]}]
(-> (transactions/sign-transaction (security/safe-unmask-data password)
address
tx
chain-id)
(-> (transactions/sign-transaction (security/safe-unmask-data password) address tx chain-id)
(promesa/then on-success)
(promesa/catch on-error))))
(rf/reg-fx
:effects.wallet-connect/send-transaction
(fn [{:keys [password address chain-id tx on-success on-error]}]
(-> (transactions/send-transaction (security/safe-unmask-data password)
address
tx
chain-id)
(-> (transactions/send-transaction (security/safe-unmask-data password) address tx chain-id)
(promesa/then on-success)
(promesa/catch on-error))))
(rf/reg-fx
:effects.wallet-connect/sign-typed-data
(fn [{:keys [password address data version chain-id on-success on-error]}]
(-> (signing/eth-sign-typed-data (security/safe-unmask-data password)
address
data
chain-id
version)
(fn [{:keys [password address data version on-success on-error]}]
(-> (wallet-connect-core/sign-typed-data version data address (security/safe-unmask-data password))
(promesa/then wallet-connect-core/extract-native-call-signature)
(promesa/then on-success)
(promesa/catch on-error))))
@@ -12,14 +12,14 @@
method (wallet-connect-core/get-request-method event)]
{:fx [(condp = method
constants/wallet-connect-personal-sign-method
[:dispatch [:wallet-connect/respond-sign-message password :personal-sign]]
constants/wallet-connect-eth-sign-method
[:dispatch [:wallet-connect/respond-sign-message password :eth-sign]]
[:dispatch [:wallet-connect/respond-personal-sign password]]
constants/wallet-connect-eth-send-transaction-method
[:dispatch [:wallet-connect/respond-send-transaction-data password]]
constants/wallet-connect-eth-sign-method
[:dispatch [:wallet-connect/respond-eth-sign password]]
constants/wallet-connect-eth-sign-transaction-method
[:dispatch [:wallet-connect/respond-sign-transaction-data password]]
@@ -30,27 +30,35 @@
[:dispatch [:wallet-connect/respond-sign-typed-data password :v4]])]})))
(rf/reg-event-fx
:wallet-connect/respond-sign-message
(fn [{:keys [db]} [password rpc-method]]
:wallet-connect/respond-eth-sign
(fn [{:keys [db]} [password]]
(let [{:keys [address raw-data]} (get db :wallet-connect/current-request)]
{:fx [[:effects.wallet-connect/sign-message
{:password password
:address address
:data raw-data
:on-error #(rf/dispatch [:wallet-connect/on-sign-error %])
:on-success #(rf/dispatch [:wallet-connect/send-response {:result %}])}]]})))
(rf/reg-event-fx
:wallet-connect/respond-personal-sign
(fn [{:keys [db]} [password]]
(let [{:keys [address raw-data]} (get db :wallet-connect/current-request)]
{:fx [[:effects.wallet-connect/sign-message
{:password password
:address address
:data raw-data
:rpc-method rpc-method
:on-error #(rf/dispatch [:wallet-connect/on-sign-error %])
:on-success #(rf/dispatch [:wallet-connect/send-response {:result %}])}]]})))
(rf/reg-event-fx
:wallet-connect/respond-sign-typed-data
(fn [{:keys [db]} [password typed-data-version]]
(let [{:keys [address raw-data event]} (get db :wallet-connect/current-request)
chain-id (get-in event [:params :chainId])]
(let [{:keys [address raw-data]} (get db :wallet-connect/current-request)]
{:fx [[:effects.wallet-connect/sign-typed-data
{:password password
:address address
:data raw-data
:chain-id chain-id
:version typed-data-version
:on-error #(rf/dispatch [:wallet-connect/on-sign-error %])
:on-success #(rf/dispatch [:wallet-connect/send-response {:result %}])}]]})))
@@ -1,61 +0,0 @@
(ns status-im.contexts.wallet.wallet-connect.rpc
(:require [oops.core :as oops]
[promesa.core :as promesa]
[status-im.common.json-rpc.events :as rpc-events]
[status-im.constants :as constants]
[utils.hex :as hex]
[utils.transforms :as transforms]))
(defn- call-rpc
"Helper to handle RPC calls to status-go as promises"
[method & args]
(promesa/create
(fn [p-resolve p-reject]
(rpc-events/call {:method method
:params args
:on-success p-resolve
:on-error p-reject
:js-response true}))))
(defn wallet-build-transaction
[chain-id tx]
(promesa/let [res (call-rpc :wallet_buildTransaction chain-id tx)]
{:message-to-sign (oops/oget res :messageToSign)
:tx-args (oops/oget res :txArgs)}))
(defn wallet-build-raw-transaction
[chain-id tx-args signature]
(-> (call-rpc "wallet_buildRawTransaction"
chain-id
(transforms/js-stringify tx-args 0)
signature)
(promesa/then #(oops/oget % "rawTx"))))
(defn wallet-send-transaction-with-signature
[chain-id tx-args signature]
(call-rpc "wallet_sendTransactionWithSignature"
chain-id
constants/transaction-pending-type-wallet-connect-transfer
(transforms/js-stringify tx-args 0)
signature))
(defn wallet-sign-message
[message address password]
(-> (call-rpc "wallet_signMessage"
message
address
password)
(promesa/then hex/normalize-hex)))
(defn wallet-hash-message-eip-191
[message]
(call-rpc "wallet_hashMessageEIP191" message))
(defn wallet-safe-sign-typed-data
[data address password chain-id legacy?]
(call-rpc "wallet_safeSignTypedDataForDApps"
data
address
password
chain-id
legacy?))
@@ -1,32 +0,0 @@
(ns status-im.contexts.wallet.wallet-connect.signing
(:require [native-module.core :as native-module]
[promesa.core :as promesa]
[status-im.contexts.wallet.wallet-connect.core :as core]
[status-im.contexts.wallet.wallet-connect.rpc :as rpc]
[utils.hex :as hex]
[utils.transforms :as transforms]))
(defn eth-sign
[password address data]
(-> {:data data
:account address
:password password}
transforms/clj->json
native-module/sign-message
(promesa/then core/extract-native-call-signature)))
(defn personal-sign
[password address data]
(-> (rpc/wallet-hash-message-eip-191 data)
(promesa/then #(rpc/wallet-sign-message % address password))
(promesa/then hex/prefix-hex)))
(defn eth-sign-typed-data
[password address data chain-id-eip155 version]
(let [legacy? (= version :v1)
chain-id (core/eip155->chain-id chain-id-eip155)]
(rpc/wallet-safe-sign-typed-data data
address
password
chain-id
legacy?)))
@@ -1,10 +1,23 @@
(ns status-im.contexts.wallet.wallet-connect.transactions
(:require [cljs-bean.core :as bean]
[clojure.string :as string]
[oops.core :as oops]
[promesa.core :as promesa]
[status-im.contexts.wallet.wallet-connect.rpc :as rpc]
[status-im.common.json-rpc.events :as rpc-events]
[status-im.constants :as constants]
[utils.transforms :as transforms]))
(defn- call-rpc
"Helper to handle RPC calls to status-go as promises"
[method & args]
(promesa/create
(fn [p-resolve p-reject]
(rpc-events/call {:method method
:params (vec args)
:on-success p-resolve
:on-error p-reject
:js-response true}))))
(defn- strip-hex-prefix
"Strips the extra 0 in hex value if present"
[hex-value]
@@ -33,22 +46,53 @@
bean/->js
(transforms/js-stringify 0)))
(defn wallet-sign-message-rpc
[password address data]
(-> (call-rpc "wallet_signMessage"
data
address
password)
;; NOTE: removing `0x`, as status-go expects the signature without it.
(promesa/then #(subs % 2))))
(defn- wallet-build-transaction-rpc
[chain-id tx]
(-> (call-rpc "wallet_buildTransaction" chain-id tx)
(promesa/then #(hash-map :message-to-sign (oops/oget % "messageToSign")
:tx-args (oops/oget % "txArgs")))))
(defn- wallet-build-raw-transaction-rpc
[chain-id tx-args signature]
(-> (call-rpc "wallet_buildRawTransaction"
chain-id
(transforms/js-stringify tx-args 0)
signature)
(promesa/then #(oops/oget % "rawTx"))))
(defn- wallet-send-transaction-with-signature-rpc
[chain-id tx-args signature]
(call-rpc "wallet_sendTransactionWithSignature"
chain-id
constants/transaction-pending-type-wallet-connect-transfer
(transforms/js-stringify tx-args 0)
signature))
(defn sign-transaction
[password address tx chain-id]
(promesa/let
[formatted-tx (prepare-transaction-for-rpc tx)
{:keys [message-to-sign tx-args]} (rpc/wallet-build-transaction chain-id formatted-tx)
signature (rpc/wallet-sign-message message-to-sign address password)
raw-tx (rpc/wallet-build-raw-transaction chain-id tx-args signature)]
{:keys [message-to-sign tx-args]} (wallet-build-transaction-rpc chain-id formatted-tx)
signature (wallet-sign-message-rpc password address message-to-sign)
raw-tx (wallet-build-raw-transaction-rpc chain-id tx-args signature)]
raw-tx))
(defn send-transaction
[password address tx chain-id]
(promesa/let
[formatted-tx (prepare-transaction-for-rpc tx)
{:keys [message-to-sign tx-args]} (rpc/wallet-build-transaction chain-id formatted-tx)
signature (rpc/wallet-sign-message message-to-sign address password)
tx (rpc/wallet-send-transaction-with-signature chain-id
{:keys [message-to-sign tx-args]} (wallet-build-transaction-rpc chain-id formatted-tx)
signature (wallet-sign-message-rpc password address message-to-sign)
tx (wallet-send-transaction-with-signature-rpc chain-id
tx-args
signature)]
tx))
-6
View File
@@ -87,12 +87,6 @@
(fn [profile]
(get-in profile [:wakuv2-config :LightClient])))
(re-frame/reg-sub
:profile/store-confirmations-enabled?
:<- [:profile/profile]
(fn [profile]
(get-in profile [:wakuv2-config :EnableStoreConfirmationForMessagesSent])))
(re-frame/reg-sub
:profile/telemetry-enabled?
:<- [:profile/profile]
+1 -1
View File
@@ -1,12 +1,12 @@
(ns status-im.subs.wallet.activities
(:require
[legacy.status-im.utils.hex :as utils.hex]
[native-module.core :as native-module]
[quo.foundations.resources :as quo.resources]
[quo.foundations.resources]
[re-frame.core :as rf]
[status-im.contexts.wallet.common.activity-tab.constants :as constants]
[utils.datetime :as datetime]
[utils.hex :as utils.hex]
[utils.money :as money]))
(def precision 6)
@@ -50,7 +50,7 @@
:<- [:wallet-connect/current-request]
(fn [request]
(-> request
(get-in [:event :params :chainId])
(get-in [:raw-data :params :chainId])
(wallet-connect-core/eip155->chain-id)
(networks/get-network-details))))
-27
View File
@@ -1,27 +0,0 @@
(ns utils.hex
(:require
[clojure.string :as string]
[schema.core :as schema]))
(defn normalize-hex
[hex]
(when hex
(string/lower-case (if (string/starts-with? hex "0x")
(subs hex 2)
hex))))
(schema/=> normalize-hex
[:=>
[:cat [:maybe :string]]
[:maybe :string]])
(defn prefix-hex
[hex]
(if (string/starts-with? hex "0x")
hex
(str "0x" hex)))
(schema/=> prefix-hex
[:=>
[:cat :string]
:string])
+3 -3
View File
@@ -3,7 +3,7 @@
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
"owner": "status-im",
"repo": "status-go",
"version": "fix/avatar-no-pk",
"commit-sha1": "aba9e91b61e4b25f268d75d12404407d597a9518",
"src-sha256": "0jf7fq62a7h62fy5kwk4gan3ffspzwaz4q6drr7k7lh246gvi331"
"version": "v0.181.35",
"commit-sha1": "1ef2434b0644581e3c0404d767550cbfee8ad829",
"src-sha256": "1dfw4cff1blg063xxrh78dgivcar92k1fspcr84ra1fxw674kmfk"
}
+1 -3
View File
@@ -12,6 +12,4 @@ markers =
testrail_case_id: case ID in testrail
flaky: flaky tests for re-run if necessary
transaction: all cases that are related to transaction completion in Ropsten network
smoke: PR tests
nightly: nightly tests
secured: tests where SauceLabs session link is not posted in PR comments
new_ui_critical: PR tests in new UI
+43 -19
View File
@@ -108,23 +108,51 @@ class TestrailReport(BaseTestReport):
test_cases['pr'] = dict()
test_cases['nightly'] = dict()
test_cases['upgrade'] = dict()
## PR e2e old UI
# test_cases['pr']['critical'] = 730
# test_cases['pr']['contacts'] = 50831
# test_cases['pr']['public_chat'] = 50654
# test_cases['pr']['one_to_one_chat'] = 50655
# test_cases['pr']['group_chat'] = 50656
# test_cases['pr']['onboarding'] = 50659
# test_cases['pr']['recovery'] = 50660
# test_cases['pr']['wallet'] = 50661
# test_cases['pr']['send_tx'] = 50662
# test_cases['pr']['keycard_tx'] = 50663
# test_cases['pr']['1_1_chat_commands'] = 50825
# test_cases['pr']['ens'] = 50827
# test_cases['pr']['sync'] = 50834
# test_cases['pr']['browser'] = 50812
# PR e2e
test_cases['pr']['critical'] = 50955
# test_cases['pr']['one_to_one_chat'] = 50956
# test_cases['pr']['community_single'] = 50983
test_cases['pr']['one_to_one_chat'] = 50956
test_cases['pr']['deep_links'] = 51535
test_cases['pr']['group_chat'] = 50964
test_cases['pr']['community_single'] = 50983
test_cases['pr']['community_multiple'] = 50982
test_cases['pr']['activity_centre_contact_request'] = 50984
test_cases['pr']['activity_centre_other'] = 51005
test_cases['pr']['wallet'] = 59443
# Nightly e2e
test_cases['nightly']['critical'] = 50955
test_cases['nightly']['one_to_one_chat'] = 50956
test_cases['nightly']['deep_links'] = 51535
test_cases['nightly']['group_chat'] = 50964
test_cases['nightly']['community_single'] = 50983
test_cases['nightly']['community_multiple'] = 50982
test_cases['nightly']['activity_centre_contact_request'] = 50984
test_cases['nightly']['activity_centre_other'] = 51005
test_cases['nightly']['wallet'] = 59443
## Nightly e2e
# test_cases['nightly']['activity_center'] = 736
# test_cases['nightly']['chat'] = 50811
# test_cases['nightly']['browser'] = 50826
# test_cases['nightly']['profile'] = 50828
# test_cases['nightly']['deep_link'] = 50836
# test_cases['nightly']['share_profile'] = 50837
# test_cases['nightly']['chat_2'] = 50838
# test_cases['nightly']['group_chat'] = 50839
# test_cases['nightly']['pairing'] = 50840
# test_cases['nightly']['activity_center'] = 50833
# test_cases['nightly']['timeline'] = 50842
# test_cases['nightly']['community'] = 50841
# test_cases['nightly']['permissions'] = 50843
# test_cases['nightly']['scan qr'] = 50844
# test_cases['nightly']['mentions'] = 50845
# test_cases['nightly']['mutual_contact_requests'] = 50857
# test_cases['nightly']['keycard'] = 50850
# test_cases['nightly']['wallet'] = 50851
## Upgrade e2e
# test_cases['upgrade']['general'] = 881
@@ -135,15 +163,11 @@ class TestrailReport(BaseTestReport):
key, value = arg.split('=')
case_ids = value.split(',')
if len(case_ids) == 0:
if 'smoke' in argv:
# if 'critical' in argv:
if 'new_ui_critical' in argv:
for category in test_cases['pr']:
for case in self.get_cases([test_cases['pr'][category]]):
case_ids.append(case['id'])
case_ids.extend([703133, 702742, 702745])
elif 'nightly' in argv:
for category in test_cases['nightly']:
for case in self.get_cases([test_cases['nightly'][category]]):
case_ids.append(case['id'])
elif 'upgrade' in argv and 'not upgrade' not in argv:
for case in self.get_cases([test_cases['upgrade']['general']]):
case_ids.append(case['id'])
@@ -11,7 +11,7 @@ from views.sign_in_view import SignInView
@pytest.mark.xdist_group(name="new_two_2")
@marks.nightly
@marks.new_ui_critical
class TestActivityCenterContactRequestMultipleDevicePR(MultipleSharedDeviceTestCase):
def prepare_devices(self):
@@ -238,7 +238,7 @@ class TestActivityCenterContactRequestMultipleDevicePR(MultipleSharedDeviceTestC
@pytest.mark.xdist_group(name="new_four_2")
@marks.nightly
@marks.new_ui_critical
class TestActivityMultipleDevicePR(MultipleSharedDeviceTestCase):
def prepare_devices(self):
@@ -378,7 +378,7 @@ class TestActivityMultipleDevicePR(MultipleSharedDeviceTestCase):
@pytest.mark.xdist_group(name="new_six_2")
@marks.nightly
@marks.new_ui_critical
class TestActivityMultipleDevicePRTwo(MultipleSharedDeviceTestCase):
def prepare_devices(self):
+39 -16
View File
@@ -18,7 +18,7 @@ from selenium.webdriver.support.wait import WebDriverWait
from urllib3.exceptions import MaxRetryError, ProtocolError
from support.api.network_api import NetworkApi
from tests import test_suite_data, start_threads, appium_container, pytest_config_global, transl
from tests import test_suite_data, start_threads, appium_container, pytest_config_global, transl, run_in_parallel
from tests.conftest import sauce_username, sauce_access_key, apibase, github_report, run_name
executor_sauce_lab = 'https://%s:%s@ondemand.%s:443/wd/hub' % (sauce_username, sauce_access_key, apibase)
@@ -60,14 +60,11 @@ def add_local_devices_to_capabilities():
return updated_capabilities
def get_capabilities_sauce_lab():
def get_common_capabilities():
caps = dict()
caps['platformName'] = 'Android'
caps['idleTimeout'] = 1000
caps['appium:app'] = 'sauce-storage:' + test_suite_data.apk_name
caps['appium:deviceName'] = 'Android GoogleAPI Emulator'
caps['appium:deviceOrientation'] = 'portrait'
caps['appium:platformVersion'] = '14.0'
caps['appium:automationName'] = 'UiAutomator2'
caps['appium:newCommandTimeout'] = 600
caps['appium:idleTimeout'] = 1000
@@ -81,7 +78,6 @@ def get_capabilities_sauce_lab():
caps['appium:enforceXPath1'] = True
caps['enforceXPath1'] = True
caps['sauce:options'] = dict()
caps['sauce:options']['appiumVersion'] = '2.0.0'
caps['sauce:options']['username'] = sauce_username
caps['sauce:options']['accessKey'] = sauce_access_key
caps['sauce:options']['build'] = run_name
@@ -89,6 +85,15 @@ def get_capabilities_sauce_lab():
caps['sauce:options']['maxDuration'] = 3600
caps['sauce:options']['idleTimeout'] = 1000
caps['sauce:options']['android.gpu.mode'] = 'hardware'
return caps
def get_capabilities_sauce_lab():
caps = get_common_capabilities()
caps['appium:app'] = 'sauce-storage:' + test_suite_data.apk_name
caps['appium:deviceName'] = 'Android GoogleAPI Emulator'
caps['appium:platformVersion'] = '14.0'
caps['sauce:options']['appiumVersion'] = '2.0.0'
options = AppiumOptions()
options.load_capabilities(caps)
@@ -96,10 +101,17 @@ def get_capabilities_sauce_lab():
return options
# def update_capabilities_sauce_lab(new_capabilities: dict):
# caps = get_capabilities_sauce_lab().copy()
# caps.update(new_capabilities)
# return caps
def get_capabilities_real_device():
caps = get_common_capabilities()
caps['appium:app'] = 'sauce-storage:' + pytest_config_global['apk_real_device']
caps['appium:deviceName'] = pytest_config_global['real_device_name']
caps['appium:platformVersion'] = '14'
caps['sauce:options']['appiumVersion'] = 'latest'
options = AppiumOptions()
options.load_capabilities(caps)
return options
def get_app_path():
@@ -306,12 +318,23 @@ def create_shared_drivers(quantity):
asyncio.set_event_loop(loop)
print('SC Executor: %s' % executor_sauce_lab)
try:
drivers = loop.run_until_complete(start_threads(test_suite_data.current_test.name,
quantity,
Driver,
drivers,
command_executor=executor_sauce_lab,
options=get_capabilities_sauce_lab()))
if pytest_config_global['apk_real_device']:
commands = [
(Driver, {'command_executor': executor_sauce_lab, 'options': get_capabilities_real_device()}),
]
if quantity > 1:
for i in range(quantity - 1):
commands.append(
(Driver, {'command_executor': executor_sauce_lab, 'options': get_capabilities_sauce_lab()})
)
drivers = loop.run_until_complete(run_in_parallel((tuple(commands))))
else:
drivers = loop.run_until_complete(start_threads(test_suite_data.current_test.name,
quantity,
Driver,
drivers,
command_executor=executor_sauce_lab,
options=get_capabilities_sauce_lab()))
if len(drivers) < quantity:
test_suite_data.current_test.testruns[-1].error = "Not all %s drivers are created" % quantity
+11 -1
View File
@@ -46,7 +46,7 @@ def pytest_addoption(parser):
help='Android device platform version')
parser.addoption('--log_steps',
action='store',
default=False,
default=True,
help='Display each test step in terminal as plain text: True/False')
parser.addoption('--pr_number',
action='store',
@@ -75,6 +75,16 @@ def pytest_addoption(parser):
default=None,
help='Url or local path to apk for upgrade')
# running on real devices
parser.addoption('--apk_real_device',
action='store',
default=None,
help='Url or local path to apk to be run on real device')
parser.addoption('--real_device_name',
action='store',
default='Samsung Galaxy S.*',
help='Real device name or name pattern')
# chat bot
parser.addoption('--messages_number',
@@ -13,7 +13,7 @@ from views.sign_in_view import SignInView
@pytest.mark.xdist_group(name="new_one_2")
@marks.nightly
@marks.new_ui_critical
class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
def prepare_devices(self):
@@ -271,7 +271,6 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
self.errors.verify_no_errors()
@marks.testrail_id(702745)
@marks.smoke
def test_1_1_chat_non_latin_messages_stack_update_profile_photo(self):
self.home_1.navigate_back_to_home_view()
self.home_1.profile_button.click()
@@ -534,7 +533,7 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
@pytest.mark.xdist_group(name="new_six_2")
@marks.nightly
@marks.new_ui_critical
class TestOneToOneChatMultipleSharedDevicesNewUiTwo(MultipleSharedDeviceTestCase):
def prepare_devices(self):
@@ -12,7 +12,7 @@ from views.sign_in_view import SignInView
@pytest.mark.xdist_group(name="new_one_3")
@marks.nightly
@marks.new_ui_critical
class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
def prepare_devices(self):
@@ -15,7 +15,7 @@ from views.sign_in_view import SignInView
@pytest.mark.xdist_group(name="new_one_1")
@marks.nightly
@marks.new_ui_critical
class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase):
def prepare_devices(self):
@@ -47,7 +47,6 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase):
self.drivers[0].fail("Not navigated to channel view after reopening app")
@marks.testrail_id(702742)
@marks.smoke
def test_community_copy_and_paste_message_in_chat_input(self):
message_texts = ['mmmeowesage_text', 'https://status.im']
if not self.channel.chat_message_input.is_element_displayed():
@@ -153,7 +152,6 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase):
self.errors.verify_no_errors()
@marks.testrail_id(703133)
@marks.smoke
def test_restore_multiaccount_with_waku_backup_remove_switch(self):
self.home.reopen_app(sign_in=False)
self.home.just_fyi("Restore user with predefined communities and contacts")
@@ -263,7 +261,7 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase):
self.home.community_card_item.wait_for_elements(seconds=120)
expected_communities = {
# ' 0xUX': ['Design', 'Ethereum', 'Collaboration'],
' 0xUX': ['Design', 'Ethereum', 'Collaboration'],
'Status': ['Web3', 'Blockchain', 'Ethereum'],
'Status Inu': ['News', 'Social', 'Web3'],
}
@@ -303,7 +301,7 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase):
@pytest.mark.xdist_group(name="new_three_2")
@marks.nightly
@marks.new_ui_critical
class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
def prepare_devices(self):
@@ -828,7 +826,7 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
@pytest.mark.xdist_group(name="new_five_2")
@marks.nightly
@marks.new_ui_critical
class TestCommunityMultipleDeviceMergedTwo(MultipleSharedDeviceTestCase):
def prepare_devices(self):
@@ -6,7 +6,7 @@ from views.sign_in_view import SignInView
@pytest.mark.xdist_group(name="new_one_1")
@marks.nightly
@marks.new_ui_critical
class TestDeepLinksOneDevice(MultipleSharedDeviceTestCase):
def prepare_devices(self):
+2 -4
View File
@@ -13,9 +13,8 @@ from views.sign_in_view import SignInView
@pytest.mark.xdist_group(name="new_four_2")
@marks.nightly
@marks.new_ui_critical
@marks.secured
@marks.smoke
class TestWalletMultipleDevice(MultipleSharedDeviceTestCase):
def prepare_devices(self):
@@ -175,8 +174,7 @@ class TestWalletMultipleDevice(MultipleSharedDeviceTestCase):
@pytest.mark.xdist_group(name="new_one_2")
@marks.nightly
@marks.smoke
@marks.new_ui_critical
class TestWalletOneDevice(MultipleSharedDeviceTestCase):
def prepare_devices(self):
+2 -2
View File
@@ -5,8 +5,8 @@ testrail_id = pytest.mark.testrail_id # atomic tests
critical = pytest.mark.critical
medium = pytest.mark.medium
# new ui
nightly = pytest.mark.nightly
smoke = pytest.mark.smoke
new_ui_critical = pytest.mark.new_ui_critical
new_ui_medium = pytest.mark.new_ui_medium
flaky = pytest.mark.flaky
upgrade = pytest.mark.upgrade
Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

+1
View File
@@ -579,6 +579,7 @@ class HomeView(BaseView):
def get_link_to_profile(self):
self.show_qr_code_button.click()
self.link_to_profile_button.click()
self.sharing_text_native.wait_for_visibility_of_element()
link_to_profile = self.sharing_text_native.text
self.click_system_back_button()
return link_to_profile
+3 -3
View File
@@ -3,7 +3,7 @@ import os
from selenium.common.exceptions import NoSuchElementException
from tests import common_password, appium_root_project_path
from tests import common_password, appium_root_project_path, pytest_config_global
from tests.base_test_case import get_app_path
from views.base_element import Button, EditBox, Text
from views.base_view import BaseView
@@ -244,8 +244,8 @@ class SignInView(BaseView):
self.generate_keys_button.click_until_presence_of_element(self.profile_title_input)
self.set_profile(username)
self.set_password(password)
# if self.enable_biometric_maybe_later_button.is_element_displayed(10):
# self.enable_biometric_maybe_later_button.click()
if pytest_config_global['apk_real_device']:
self.enable_biometric_maybe_later_button.wait_and_click()
# self.next_button.click_until_absense_of_element(self.element_by_translation_id("intro-wizard-title2"))
# if keycard:
# keycard_flow = self.keycard_storage_button.click()
+1 -2
View File
@@ -2757,6 +2757,5 @@
"value-higher-than-send-amount": "This value is higher than entered amount to send",
"swaps-powered-by": "Swaps powered by {{provider}}",
"max-slippage": "Max slippage",
"pay": "Pay",
"store-confirmations": "Store confirmations"
"pay": "Pay"
}