Introduce subscription tests (#14472)
This commit is contained in:
parent
da0f0d3a81
commit
6e272a96c8
|
@ -1,14 +1,17 @@
|
||||||
{:lint-as {status-im.utils.views/defview clojure.core/defn
|
{:lint-as {status-im.utils.views/defview clojure.core/defn
|
||||||
status-im.utils.views/letsubs clojure.core/let
|
status-im.utils.views/letsubs clojure.core/let
|
||||||
reagent.core/with-let clojure.core/let
|
reagent.core/with-let clojure.core/let
|
||||||
status-im.utils.fx/defn clj-kondo.lint-as/def-catch-all
|
status-im.utils.fx/defn clj-kondo.lint-as/def-catch-all
|
||||||
utils.re-frame/defn clj-kondo.lint-as/def-catch-all
|
utils.re-frame/defn clj-kondo.lint-as/def-catch-all
|
||||||
quo.react/with-deps-check clojure.core/fn
|
quo.react/with-deps-check clojure.core/fn
|
||||||
quo.previews.preview/list-comp clojure.core/for
|
quo.previews.preview/list-comp clojure.core/for
|
||||||
status-im.utils.styles/def clojure.core/def
|
status-im.utils.styles/def clojure.core/def
|
||||||
status-im.utils.styles/defn clojure.core/defn
|
status-im.utils.styles/defn clojure.core/defn
|
||||||
taoensso.tufte/defnp clojure.core/defn}
|
status-im.test-helpers/deftest-sub clojure.core/defn
|
||||||
|
taoensso.tufte/defnp clojure.core/defn}
|
||||||
:linters {:invalid-arity {:skip-args [status-im.utils.fx/defn utils.re-frame/defn]}
|
:linters {:invalid-arity {:skip-args [status-im.utils.fx/defn utils.re-frame/defn]}
|
||||||
;;TODO remove number when this is fixed
|
;; TODO remove number when this is fixed
|
||||||
;;https://github.com/borkdude/clj-kondo/issues/867
|
;; https://github.com/borkdude/clj-kondo/issues/867
|
||||||
:unresolved-symbol {:exclude [PersistentPriorityMap.EMPTY number]}}}
|
:unresolved-symbol {:exclude [PersistentPriorityMap.EMPTY
|
||||||
|
number
|
||||||
|
status-im.test-helpers/restore-app-db]}}}
|
||||||
|
|
|
@ -346,6 +346,53 @@ keywords and concatenating them into a single string.
|
||||||
(i18n/label :t/biometric-auth-error {:code error-code})
|
(i18n/label :t/biometric-auth-error {:code error-code})
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Tests
|
||||||
|
#### Subscription tests
|
||||||
|
|
||||||
|
Test [layer-3 subscriptions](https://day8.github.io/re-frame/subscriptions/) by
|
||||||
|
actually subscribing to them, so reframe's signal graph gets validated too.
|
||||||
|
|
||||||
|
```clojure
|
||||||
|
;; bad
|
||||||
|
(defn user-recipes
|
||||||
|
[[current-user all-recipes location]]
|
||||||
|
...)
|
||||||
|
|
||||||
|
(re-frame/reg-sub
|
||||||
|
:user/recipes
|
||||||
|
:<- [:current-user]
|
||||||
|
:<- [:all-recipes]
|
||||||
|
:<- [:location]
|
||||||
|
user-recipes)
|
||||||
|
|
||||||
|
(deftest user-recipes-test
|
||||||
|
(testing "builds list of recipes"
|
||||||
|
(let [current-user {...}
|
||||||
|
all-recipes {...}
|
||||||
|
location [...]]
|
||||||
|
(is (= expected (recipes [current-user all-recipes location]))))))
|
||||||
|
|
||||||
|
;; good
|
||||||
|
(require '[status-im.test-helpers :as h])
|
||||||
|
|
||||||
|
(re-frame/reg-sub
|
||||||
|
:user/recipes
|
||||||
|
:<- [:current-user]
|
||||||
|
:<- [:all-recipes]
|
||||||
|
:<- [:location]
|
||||||
|
(fn [[current-user all-recipes location]]
|
||||||
|
...))
|
||||||
|
|
||||||
|
(h/deftest-sub :user/recipes
|
||||||
|
[sub-name]
|
||||||
|
(testing "builds list of recipes"
|
||||||
|
(swap! rf-db/app-db assoc
|
||||||
|
:current-user {...}
|
||||||
|
:all-recipes {...}
|
||||||
|
:location [...])
|
||||||
|
(is (= expected (rf/sub [sub-name])))))
|
||||||
|
```
|
||||||
|
|
||||||
## Project Structure
|
## Project Structure
|
||||||
|
|
||||||
First, the bird's-eye view with some example ClojureScript files:
|
First, the bird's-eye view with some example ClojureScript files:
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
(ns status-im.test-helpers
|
||||||
|
(:require [clojure.spec.alpha :as s]
|
||||||
|
[clojure.string :as string]
|
||||||
|
[clojure.walk :as walk]))
|
||||||
|
|
||||||
|
(defn- subscription-name->test-name
|
||||||
|
[sub-name]
|
||||||
|
(->> [(namespace sub-name)
|
||||||
|
(name sub-name)
|
||||||
|
"test"]
|
||||||
|
(remove nil?)
|
||||||
|
(map #(string/replace % #"\." "-"))
|
||||||
|
(string/join "-")))
|
||||||
|
|
||||||
|
(defmacro ^:private testing-subscription
|
||||||
|
[description & body]
|
||||||
|
`(cljs.test/testing ~description
|
||||||
|
(restore-app-db (fn [] ~@body))))
|
||||||
|
|
||||||
|
(s/fdef deftest-sub
|
||||||
|
:args (s/cat :sub-name keyword?
|
||||||
|
:args (s/coll-of symbol? :count 1)
|
||||||
|
:body (s/* any?)))
|
||||||
|
|
||||||
|
(defmacro deftest-sub
|
||||||
|
"Defines a test based on `sub-name`, executes `body` and restores the app db.
|
||||||
|
|
||||||
|
Any usage of the `cljs.test/testing` macro inside `body` will be modified to
|
||||||
|
also make sure the app db is restored and the subscription cache is reset.
|
||||||
|
|
||||||
|
Expressions in `body` will have access to `sub-name`, which should be used to
|
||||||
|
avoid needlessly repeating the subscription name.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```clojure
|
||||||
|
(require '[status-im.test-helpers :as h])
|
||||||
|
|
||||||
|
(h/deftest-sub :wallet/sorted-tokens
|
||||||
|
[sub-name]
|
||||||
|
(testing \"sorts tokens by name, lowercased\"
|
||||||
|
;; Arrange
|
||||||
|
(swap! rf-db/app-db assoc-in [<db-path>] <value>)
|
||||||
|
|
||||||
|
;; Act and Assert
|
||||||
|
(is (= <expected> (rf/sub [sub-name])))))
|
||||||
|
```"
|
||||||
|
[sub-name args & body]
|
||||||
|
`(let [sub-name# ~sub-name]
|
||||||
|
(cljs.test/deftest ~(symbol (subscription-name->test-name sub-name))
|
||||||
|
(let [~args [sub-name#]]
|
||||||
|
(restore-app-db
|
||||||
|
(fn []
|
||||||
|
~@(clojure.walk/postwalk-replace
|
||||||
|
{'cljs.test/testing `testing-subscription
|
||||||
|
'testing `testing-subscription}
|
||||||
|
body)))))))
|
|
@ -5,10 +5,12 @@
|
||||||
Avoid coupling this namespace with particularities of the Status' domain, thus
|
Avoid coupling this namespace with particularities of the Status' domain, thus
|
||||||
prefer to use it for more general purpose concepts, such as the re-frame event
|
prefer to use it for more general purpose concepts, such as the re-frame event
|
||||||
layer."
|
layer."
|
||||||
|
(:require-macros status-im.test-helpers)
|
||||||
(:require [re-frame.core :as rf]
|
(:require [re-frame.core :as rf]
|
||||||
[re-frame.db :as rf-db]
|
[re-frame.db :as rf-db]
|
||||||
[re-frame.events :as rf-events]
|
[re-frame.events :as rf-events]
|
||||||
[re-frame.registrar :as rf-registrar]
|
[re-frame.registrar :as rf-registrar]
|
||||||
|
[re-frame.subs :as rf-subs]
|
||||||
[taoensso.timbre :as log]))
|
[taoensso.timbre :as log]))
|
||||||
|
|
||||||
(defn db
|
(defn db
|
||||||
|
@ -100,3 +102,15 @@
|
||||||
:fn (fn [{:keys [vargs level]}]
|
:fn (fn [{:keys [vargs level]}]
|
||||||
(swap! logs conj {:args vargs :level level}))})]
|
(swap! logs conj {:args vargs :level level}))})]
|
||||||
(f logs))))
|
(f logs))))
|
||||||
|
|
||||||
|
(defn restore-app-db
|
||||||
|
"Saves current app DB, calls `f` and restores the original app DB.
|
||||||
|
|
||||||
|
Always clears the subscription cache after calling `f`."
|
||||||
|
[f]
|
||||||
|
(rf-subs/clear-subscription-cache!)
|
||||||
|
(let [original-db @rf-db/app-db]
|
||||||
|
(try
|
||||||
|
(f)
|
||||||
|
(finally
|
||||||
|
(reset! rf-db/app-db original-db)))))
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
(ns status-im2.subs.activity-center-test
|
||||||
|
(:require [cljs.test :refer [is testing]]
|
||||||
|
[re-frame.db :as rf-db]
|
||||||
|
[status-im.test-helpers :as h]
|
||||||
|
status-im2.subs.activity-center
|
||||||
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
(h/deftest-sub :activity-center/filter-status-unread-enabled?
|
||||||
|
[sub-name]
|
||||||
|
(testing "returns true when filter status is unread"
|
||||||
|
(swap! rf-db/app-db assoc-in [:activity-center :filter :status] :unread)
|
||||||
|
(is (true? (rf/sub [sub-name]))))
|
||||||
|
|
||||||
|
(testing "returns false when filter status is not unread"
|
||||||
|
(swap! rf-db/app-db assoc-in [:activity-center :filter :status] :all)
|
||||||
|
(is (false? (rf/sub [sub-name])))))
|
|
@ -1,40 +1,76 @@
|
||||||
(ns status-im2.subs.communities-test
|
(ns status-im2.subs.communities-test
|
||||||
(:require [cljs.test :refer [deftest is testing]]
|
(:require [cljs.test :refer [is testing use-fixtures]]
|
||||||
[status-im2.subs.communities :as subs]))
|
[re-frame.db :as rf-db]
|
||||||
|
[status-im.test-helpers :as h]
|
||||||
|
status-im2.subs.communities
|
||||||
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
(deftest community->home-item-test
|
(use-fixtures :each
|
||||||
(testing "has unread messages"
|
{:before #(reset! rf-db/app-db {:communities/enabled? true})})
|
||||||
(is (= {:name "name-1"
|
|
||||||
:muted? true
|
|
||||||
:unread-messages? true
|
|
||||||
:unread-mentions-count 5
|
|
||||||
:community-icon "icon-1"}
|
|
||||||
(subs/community->home-item
|
|
||||||
{:name "name-1"
|
|
||||||
:muted true
|
|
||||||
:images {:thumbnail {:uri "icon-1"}}}
|
|
||||||
{:unviewed-messages-count 1
|
|
||||||
:unviewed-mentions-count 5}))))
|
|
||||||
(testing "no unread messages"
|
|
||||||
(is (= {:name "name-2"
|
|
||||||
:muted? false
|
|
||||||
:unread-messages? false
|
|
||||||
:unread-mentions-count 5
|
|
||||||
:community-icon "icon-2"}
|
|
||||||
(subs/community->home-item
|
|
||||||
{:name "name-2"
|
|
||||||
:muted false
|
|
||||||
:images {:thumbnail {:uri "icon-2"}}}
|
|
||||||
{:unviewed-messages-count 0
|
|
||||||
:unviewed-mentions-count 5})))))
|
|
||||||
|
|
||||||
(deftest calculate-unviewed-counts-test
|
(def community-id "0x1")
|
||||||
(let [chats [{:unviewed-messages-count 1
|
|
||||||
:unviewed-mentions-count 2}
|
(h/deftest-sub :communities
|
||||||
{:unviewed-messages-count 3
|
[sub-name]
|
||||||
:unviewed-mentions-count 0}
|
(testing "returns empty vector if flag is disabled"
|
||||||
{:unviewed-messages-count 2
|
(swap! rf-db/app-db assoc :communities/enabled? false)
|
||||||
:unviewed-mentions-count 1}]]
|
(is (= [] (rf/sub [sub-name]))))
|
||||||
(is (= {:unviewed-messages-count 6
|
|
||||||
:unviewed-mentions-count 3}
|
(testing "returns raw communities if flag is enabled"
|
||||||
(subs/calculate-unviewed-counts chats)))))
|
(let [raw-communities {"0x1" {:id "0x1"}}]
|
||||||
|
(swap! rf-db/app-db assoc
|
||||||
|
:communities/enabled? true
|
||||||
|
:communities raw-communities)
|
||||||
|
(is (= raw-communities (rf/sub [sub-name]))))))
|
||||||
|
|
||||||
|
(h/deftest-sub :communities/section-list
|
||||||
|
[sub-name]
|
||||||
|
(testing "builds sections using the first community name char (uppercased)"
|
||||||
|
(swap! rf-db/app-db assoc :communities
|
||||||
|
{"0x1" {:name "civilized monkeys"}
|
||||||
|
"0x2" {:name "Civilized rats"}})
|
||||||
|
(is (= [{:title "C"
|
||||||
|
:data [{:name "civilized monkeys"}
|
||||||
|
{:name "Civilized rats"}]}]
|
||||||
|
(rf/sub [sub-name]))))
|
||||||
|
|
||||||
|
(testing "sorts by section ascending"
|
||||||
|
(swap! rf-db/app-db assoc :communities
|
||||||
|
{"0x3" {:name "Memorable"}
|
||||||
|
"0x1" {:name "Civilized monkeys"}})
|
||||||
|
(is (= [{:title "C" :data [{:name "Civilized monkeys"}]}
|
||||||
|
{:title "M" :data [{:name "Memorable"}]}]
|
||||||
|
(rf/sub [sub-name]))))
|
||||||
|
|
||||||
|
(testing "builds default section for communities without a name"
|
||||||
|
(swap! rf-db/app-db assoc :communities
|
||||||
|
{"0x2" {:id "0x2"}
|
||||||
|
"0x1" {:id "0x1"}})
|
||||||
|
(is (= [{:title ""
|
||||||
|
:data [{:id "0x2"}
|
||||||
|
{:id "0x1"}]}]
|
||||||
|
(rf/sub [sub-name])))))
|
||||||
|
|
||||||
|
(h/deftest-sub :communities/unviewed-counts
|
||||||
|
[sub-name]
|
||||||
|
(testing "sums counts for a particular community"
|
||||||
|
(swap! rf-db/app-db assoc :chats
|
||||||
|
{"0x100" {:community-id community-id
|
||||||
|
:unviewed-mentions-count 3
|
||||||
|
:unviewed-messages-count 2}
|
||||||
|
"0x101" {:community-id "0x2"
|
||||||
|
:unviewed-mentions-count 7
|
||||||
|
:unviewed-messages-count 9}
|
||||||
|
"0x102" {:community-id community-id
|
||||||
|
:unviewed-mentions-count 5
|
||||||
|
:unviewed-messages-count 1}})
|
||||||
|
(is (= {:unviewed-messages-count 3
|
||||||
|
:unviewed-mentions-count 8}
|
||||||
|
(rf/sub [sub-name community-id]))))
|
||||||
|
|
||||||
|
(testing "defaults to zero when count keys are not present"
|
||||||
|
(swap! rf-db/app-db assoc :chats
|
||||||
|
{"0x100" {:community-id community-id}})
|
||||||
|
(is (= {:unviewed-messages-count 0
|
||||||
|
:unviewed-mentions-count 0}
|
||||||
|
(rf/sub [sub-name community-id])))))
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
(ns status-im2.subs.subs-test
|
(ns status-im2.subs.subs-test
|
||||||
(:require [cljs.test :refer [deftest is testing]]
|
(:require [cljs.test :refer [deftest is testing]]
|
||||||
[status-im2.subs.wallet.transactions :as wallet.transactions]
|
[status-im2.subs.wallet.transactions :as wallet.transactions]
|
||||||
[status-im2.subs.onboarding :as onboarding]
|
[status-im2.subs.onboarding :as onboarding]))
|
||||||
[status-im.utils.money :as money]
|
|
||||||
[status-im2.subs.wallet.wallet :as wallet]))
|
|
||||||
|
|
||||||
(def transactions [{:timestamp "1505912551000"}
|
(def transactions [{:timestamp "1505912551000"}
|
||||||
{:timestamp "1505764322000"}
|
{:timestamp "1505764322000"}
|
||||||
|
@ -40,17 +38,3 @@
|
||||||
{"0x1" {:keycard-pairing "keycard-pairing-code"}}}
|
{"0x1" {:keycard-pairing "keycard-pairing-code"}}}
|
||||||
{})]
|
{})]
|
||||||
(is (= res "keycard-pairing-code")))))
|
(is (= res "keycard-pairing-code")))))
|
||||||
|
|
||||||
(deftest test-balance-total-value
|
|
||||||
(is (= (wallet/get-balance-total-value
|
|
||||||
{:ETH (money/bignumber 1000000000000000000)
|
|
||||||
:SNT (money/bignumber 100000000000000000000)
|
|
||||||
:AST (money/bignumber 10000)}
|
|
||||||
{:ETH {:USD {:from "ETH", :to "USD", :price 677.91, :last-day 658.688}}
|
|
||||||
:SNT {:USD {:from "SNT", :to "USD", :price 0.1562, :last-day 0.15}}
|
|
||||||
:AST {:USD {:from "AST", :to "USD", :price 4, :last-day 3}}}
|
|
||||||
:USD
|
|
||||||
{:ETH 18
|
|
||||||
:SNT 18
|
|
||||||
:AST 4})
|
|
||||||
697.53)))
|
|
|
@ -0,0 +1,133 @@
|
||||||
|
(ns status-im2.subs.wallet.wallet-test
|
||||||
|
(:require [cljs.test :refer [deftest is testing]]
|
||||||
|
[re-frame.db :as rf-db]
|
||||||
|
[status-im.test-helpers :as h]
|
||||||
|
[status-im.utils.money :as money]
|
||||||
|
[status-im2.subs.wallet.wallet :as wallet]
|
||||||
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
(def money-zero (money/bignumber 0))
|
||||||
|
(def money-eth (money/bignumber 8000000000000000000))
|
||||||
|
(def money-snt (money/bignumber 756000000000000000000))
|
||||||
|
(def main-account-id "0x0Fbd")
|
||||||
|
|
||||||
|
(def accounts
|
||||||
|
[{:address "0x0Fbd"
|
||||||
|
:name "Main account"
|
||||||
|
:hidden false
|
||||||
|
:removed false}
|
||||||
|
{:address "0x5B03"
|
||||||
|
:name "Secondary account"
|
||||||
|
:hidden false
|
||||||
|
:removed false}])
|
||||||
|
|
||||||
|
(def wallet
|
||||||
|
{:accounts {main-account-id
|
||||||
|
{:balance {:ETH money-eth :SNT money-snt}
|
||||||
|
:transactions {}
|
||||||
|
:max-block 0}
|
||||||
|
"0x5B03"
|
||||||
|
{:balance {:ETH money-eth :SNT money-snt}
|
||||||
|
:transactions {}
|
||||||
|
:max-block 10}}})
|
||||||
|
|
||||||
|
(def prices
|
||||||
|
{:ETH {:USD {:from "ETH"
|
||||||
|
:to "USD"
|
||||||
|
:price 1282.23}}
|
||||||
|
:SNT {:USD {:from "SNT"
|
||||||
|
:to "USD"
|
||||||
|
:price 0.0232}}})
|
||||||
|
|
||||||
|
(def tokens
|
||||||
|
{"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
|
||||||
|
{:address "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"
|
||||||
|
:name "Ether"
|
||||||
|
:symbol :ETH
|
||||||
|
:decimals 18
|
||||||
|
:chainId 1}
|
||||||
|
"0x744d70fdbe2ba4cf95131626614a1763df805b9e"
|
||||||
|
{:address "0x744d70fdbe2ba4cf95131626614a1763df805b9e"
|
||||||
|
:name "Status Network Token"
|
||||||
|
:symbol :SNT
|
||||||
|
:decimals 18
|
||||||
|
:chainId 1}})
|
||||||
|
|
||||||
|
(h/deftest-sub :balances
|
||||||
|
[sub-name]
|
||||||
|
(swap! rf-db/app-db assoc
|
||||||
|
:multiaccount/accounts accounts
|
||||||
|
:wallet wallet)
|
||||||
|
(is (= [{:ETH money-eth
|
||||||
|
:SNT money-snt}
|
||||||
|
{:ETH money-eth
|
||||||
|
:SNT money-snt}]
|
||||||
|
(rf/sub [sub-name]))))
|
||||||
|
|
||||||
|
(h/deftest-sub :wallet/token->decimals
|
||||||
|
[sub-name]
|
||||||
|
(swap! rf-db/app-db assoc :wallet/all-tokens tokens)
|
||||||
|
(is (= {:SNT 18 :ETH 18}
|
||||||
|
(rf/sub [sub-name]))))
|
||||||
|
|
||||||
|
(deftest get-balance-total-value-test
|
||||||
|
(is (= 697.53
|
||||||
|
(wallet/get-balance-total-value
|
||||||
|
{:ETH (money/bignumber 1000000000000000000)
|
||||||
|
:SNT (money/bignumber 100000000000000000000)
|
||||||
|
:AST (money/bignumber 10000)}
|
||||||
|
{:ETH {:USD {:from "ETH" :to "USD" :price 677.91 :last-day 658.688}}
|
||||||
|
:SNT {:USD {:from "SNT" :to "USD" :price 0.1562 :last-day 0.15}}
|
||||||
|
:AST {:USD {:from "AST" :to "USD" :price 4 :last-day 3}}}
|
||||||
|
:USD
|
||||||
|
{:ETH 18
|
||||||
|
:SNT 18
|
||||||
|
:AST 4}))))
|
||||||
|
|
||||||
|
(h/deftest-sub :portfolio-value
|
||||||
|
[sub-name]
|
||||||
|
(testing "returns fallback value when balances and prices are not available"
|
||||||
|
(is (= "..." (rf/sub [sub-name]))))
|
||||||
|
|
||||||
|
(testing "returns zero when balance is not positive"
|
||||||
|
(let [empty-wallet {:accounts {main-account-id
|
||||||
|
{:balance {:ETH money-zero
|
||||||
|
:SNT money-zero}}}}]
|
||||||
|
(swap! rf-db/app-db assoc
|
||||||
|
:multiaccount/accounts accounts
|
||||||
|
:prices prices
|
||||||
|
:wallet empty-wallet
|
||||||
|
:wallet/all-tokens tokens)
|
||||||
|
(is (= "0" (rf/sub [sub-name])))))
|
||||||
|
|
||||||
|
(testing "returns formatted value in the default USD currency"
|
||||||
|
(swap! rf-db/app-db assoc
|
||||||
|
:multiaccount/accounts accounts
|
||||||
|
:prices prices
|
||||||
|
:wallet wallet
|
||||||
|
:wallet/all-tokens tokens)
|
||||||
|
(is (= "20,550.76" (rf/sub [sub-name])))))
|
||||||
|
|
||||||
|
(h/deftest-sub :account-portfolio-value
|
||||||
|
[sub-name]
|
||||||
|
(testing "returns fallback value when balances and prices are not available"
|
||||||
|
(is (= "..." (rf/sub [sub-name]))))
|
||||||
|
|
||||||
|
(testing "returns zero when balance is not positive"
|
||||||
|
(let [empty-wallet {:accounts {main-account-id
|
||||||
|
{:balance {:ETH money-zero
|
||||||
|
:SNT money-zero}}}}]
|
||||||
|
(swap! rf-db/app-db assoc
|
||||||
|
:multiaccount/accounts accounts
|
||||||
|
:prices prices
|
||||||
|
:wallet empty-wallet
|
||||||
|
:wallet/all-tokens tokens)
|
||||||
|
(is (= "0" (rf/sub [sub-name main-account-id])))))
|
||||||
|
|
||||||
|
(testing "returns formatted value in the default USD currency"
|
||||||
|
(swap! rf-db/app-db assoc
|
||||||
|
:multiaccount/accounts accounts
|
||||||
|
:prices prices
|
||||||
|
:wallet wallet
|
||||||
|
:wallet/all-tokens tokens)
|
||||||
|
(is (= "10,275.38" (rf/sub [sub-name main-account-id])))))
|
Loading…
Reference in New Issue