Move chats to status-go

This commit moves chats to status-go.

I have changed the logic to load all chats in one go for simplicity and
while that might have a performance impact, I think it's premature to
  optimize this flow as there will be more changes to the login flow.

Also currently this is likely to be slower as we need to wait for the
 status-service to be initialized, as well as realm.

No migration is provided as we are past the point of no return, so by
installing this version you will lose your chats.

Signed-off-by: Andrea Maria Piana <andrea.maria.piana@gmail.com>
This commit is contained in:
Andrea Maria Piana 2019-07-30 19:16:52 +02:00
parent f464269263
commit 6fa482a776
No known key found for this signature in database
GPG Key ID: AA6CCA6DE0E06424
24 changed files with 344 additions and 294 deletions

View File

@ -101,8 +101,9 @@
(or (get (:chats db) chat-id)
(create-new-chat chat-id cofx))
chat-props)]
{:db (update-in db [:chats chat-id] merge chat)
:data-store/tx [(chats-store/save-chat-tx chat)]}))
(fx/merge cofx
{:db (update-in db [:chats chat-id] merge chat)}
(chats-store/save-chat-rpc chat))))
(fx/defn add-public-chat
"Adds new public group chat to db & realm"
@ -138,22 +139,25 @@
:clock-value)
deleted-at-clock-value
(utils.clocks/send 0))]
{:db (update-in db [:chats chat-id] merge
{:messages empty-message-map
:message-groups {}
:last-message-content nil
:last-message-content-type nil
:unviewed-messages-count 0
:deleted-at-clock-value last-message-clock-value})
:data-store/tx [(chats-store/clear-history-tx chat-id last-message-clock-value)
(messages-store/delete-chat-messages-tx chat-id)]}))
(fx/merge
cofx
{:db (update-in db [:chats chat-id] merge
{:messages empty-message-map
:message-groups {}
:last-message-content nil
:last-message-content-type nil
:unviewed-messages-count 0
:deleted-at-clock-value last-message-clock-value})
:data-store/tx [(messages-store/delete-chat-messages-tx chat-id)]}
#(chats-store/save-chat-rpc % (get-in % [:db :chats chat-id])))))
(fx/defn deactivate-chat
[{:keys [db now] :as cofx} chat-id]
{:db (-> db
(assoc-in [:chats chat-id :is-active] false)
(assoc-in [:current-chat-id] nil))
:data-store/tx [(chats-store/deactivate-chat-tx chat-id now)]})
(fx/merge cofx
{:db (-> db
(assoc-in [:chats chat-id :is-active] false)
(assoc-in [:current-chat-id] nil))}
#(chats-store/save-chat-rpc % (get-in % [:db :chats chat-id]))))
(fx/defn remove-chat
"Removes chat completely from app, producing all necessary effects for that"

View File

@ -1,6 +1,8 @@
(ns status-im.chat.models.loading
(:require [re-frame.core :as re-frame]
[status-im.data-store.chats :as data-store.chats]
[status-im.chat.commands.core :as commands]
[status-im.transport.filters.core :as filters]
[status-im.chat.models :as chat-model]
[status-im.ethereum.json-rpc :as json-rpc]
[status-im.mailserver.core :as mailserver]
@ -55,35 +57,7 @@
(fx/defn update-chats-in-app-db
{:events [:chats-list/load-success]}
[{:keys [db] :as cofx} chats]
(fx/merge cofx
{:db (assoc db :chats chats)}
(commands/load-commands commands/register)))
(defn- unkeywordize-chat-names
[chats]
(reduce-kv
(fn [acc chat-keyword chat]
(assoc acc (name chat-keyword) chat))
{}
chats))
(defn load-chats-from-rpc
[cofx]
(fx/merge cofx
{::json-rpc/call [{:method "status_chats"
:params []
:on-error
#(log/error "can't retrieve chats list from status-go:" %)
:on-success
#(re-frame/dispatch
[:chats-list/load-success
(unkeywordize-chat-names (:chats %))])}]}))
(defn initialize-chats-legacy
"Use realm + clojure to manage chats"
[{:keys [db get-all-stored-chats] :as cofx}
from to]
[{:keys [db] :as cofx} new-chats]
(let [old-chats (:chats db)
chats (reduce (fn [acc {:keys [chat-id] :as chat}]
(assoc acc chat-id
@ -92,17 +66,26 @@
:referenced-messages {}
:messages empty-message-map)))
{}
(get-all-stored-chats from to))
new-chats)
chats (merge old-chats chats)]
(update-chats-in-app-db cofx chats)))
(fx/merge cofx
{:db (assoc db :chats chats
:chats/loading? false)}
(filters/load-filters)
(commands/load-commands commands/register))))
(defn load-chats-from-rpc
[cofx from to]
(data-store.chats/fetch-chats-rpc cofx {:from 0
:to 10
:on-success
#(re-frame/dispatch
[:chats-list/load-success %])}))
(fx/defn initialize-chats
"Initialize persisted chats on startup"
[cofx
{:keys [from to] :or {from 0 to nil}}]
(if config/use-status-go-protocol?
(load-chats-from-rpc cofx)
(initialize-chats-legacy cofx from to)))
(load-chats-from-rpc cofx from -1))
(defn load-more-messages
"Loads more messages for current chat"

View File

@ -19,6 +19,8 @@
[{:keys [db] :as cofx} chat-id removed-chat-messages]
(let [removed-messages-ids (map :message-id removed-chat-messages)
removed-unseen-count (count (remove :seen removed-chat-messages))
unviewed-messages-count (- (get-in db [:chats chat-id :unviewed-messages-count])
removed-unseen-count)
db (-> db
;; remove messages
(update-in [:chats chat-id :messages]
@ -32,8 +34,9 @@
(chat.models/upsert-chat
{:chat-id chat-id
:unviewed-messages-count
(- (get-in db [:chats chat-id :unviewed-messages-count])
removed-unseen-count)})
(if (pos? unviewed-messages-count)
unviewed-messages-count
0)})
;; recompute message group
(chat.models.loading/group-chat-messages
chat-id

View File

@ -2,7 +2,9 @@
(:require [goog.object :as object]
[re-frame.core :as re-frame]
[status-im.data-store.messages :as messages]
[status-im.utils.fx :as fx]
[status-im.data-store.realm.core :as core]
[status-im.ethereum.json-rpc :as json-rpc]
[status-im.ethereum.core :as ethereum]
[taoensso.timbre :as log]
[status-im.utils.clocks :as utils.clocks]
@ -16,6 +18,10 @@
(and (coll? v)
(empty? v)))) e)))
(def one-to-one-chat-type 1)
(def public-chat-type 2)
(def private-group-chat-type 3)
(defn- event->string
"Transform an event in an a vector with keys in alphabetical order, to compute
a predictable id"
@ -31,121 +37,124 @@
(defn marshal-membership-updates [updates]
(mapcat (fn [{:keys [signature events from]}]
(map #(assoc %
:id (event-id %)
:signature signature
:from from) events)) updates))
(map #(-> %
(assoc
:clockValue (:clock-value %)
:id (event-id %)
:signature signature
:from from)
(dissoc :clock-value)) events)) updates))
(defn unmarshal-membership-updates [chat-id updates]
(->> updates
vals
(group-by :signature)
(map (fn [[signature events]]
{:events (map #(-> (dissoc % :signature :from :id)
{:events (map #(-> %
(assoc :clock-value (:clockValue %))
(dissoc :signature :from :id :clockValue)
remove-empty-vals) events)
:from (-> events first :from)
:signature signature
:chat-id chat-id}))))
(defn- normalize-chat [{:keys [chat-id] :as chat}]
(defn type->rpc [{:keys [public? group-chat] :as chat}]
(assoc chat :chatType (cond
public? public-chat-type
group-chat private-group-chat-type
:else one-to-one-chat-type)))
(defn rpc->type [{:keys [chatType] :as chat}]
(cond
(= public-chat-type chatType) (assoc chat :public? true :group-chat true)
(= private-group-chat-type chatType) (assoc chat :public? false :group-chat true)
:else (assoc chat :public? false :group-chat false)))
(defn- marshal-members [{:keys [admins contacts members-joined chatType] :as chat}]
(cond-> chat
(= chatType private-group-chat-type)
(assoc :members (map #(hash-map :id %
:admin (boolean (admins %))
:joined (boolean (members-joined %))) contacts))
:always
(dissoc :admins :contacts :members-joined)))
(defn- unmarshal-members [{:keys [members chatType] :as chat}]
(cond
(= public-chat-type chatType) (assoc chat
:contacts #{}
:admins #{}
:members-joined #{})
(= private-group-chat-type chatType) (merge chat
(reduce (fn [acc member]
(cond-> acc
(:admin member)
(update :admins conj (:id member))
(:joined member)
(update :members-joined conj (:id member))
:always
(update :contacts conj (:id member))))
{:admins #{}
:members-joined #{}
:contacts #{}}
members))
:else
(assoc chat
:contacts #{(:id chat)}
:admins #{}
:members-joined #{})))
(defn- ->rpc [chat]
(-> chat
(update :admins #(into #{} %))
(update :contacts #(into #{} %))
(update :members-joined #(into #{} %))
(update :tags #(into #{} %))
(update :membership-updates (partial unmarshal-membership-updates chat-id))
type->rpc
marshal-members
(update :membership-updates marshal-membership-updates)
(utils/update-if-present :last-message-content messages/prepare-content)
(clojure.set/rename-keys {:chat-id :id
:membership-updates :membershipUpdates
:unviewed-messages-count :unviewedMessagesCount
:last-message-content :lastMessageContent
:last-message-content-type :lastMessageContentType
:deleted-at-clock-value :deletedAtClockValue
:is-active :active
:last-clock-value :lastClockValue})
(dissoc :referenced-messages :message-groups :gaps-loaded? :pagination-info
:public? :group-chat :messages
:might-have-join-time-messages?
:group-chat-local-version :loaded-unviewed-messages-ids
:messages-initialized? :contacts :admins :members-joined)))
(defn- <-rpc [chat]
(-> chat
rpc->type
unmarshal-members
(clojure.set/rename-keys {:id :chat-id
:membershipUpdates :membership-updates
:unviewedMessagesCount :unviewed-messages-count
:lastMessageContent :last-message-content
:lastMessageContentType :last-message-content-type
:deletedAtClockValue :deleted-at-clock-value
:active :is-active
:lastClockValue :last-clock-value})
(update :membership-updates (partial unmarshal-membership-updates (:id chat)))
(update :last-message-content utils/safe-read-message-content)
(update :last-clock-value utils.clocks/safe-timestamp)
(update :last-message-content utils/safe-read-message-content)))
(assoc :group-chat-local-version 1) ;; TODO(cammellos): this can be removed
(dissoc :chatType :members)))
(re-frame/reg-cofx
:data-store/all-chats
(fn [cofx _]
(assoc cofx :get-all-stored-chats
(fn [from to]
(map normalize-chat
(-> @core/account-realm
(core/get-all :chat)
(core/sorted :timestamp :desc)
(core/page from to)
(core/all-clj :chat)))))))
(fx/defn save-chat-rpc [cofx {:keys [chat-id] :as chat}]
(json-rpc/call {:method "shhext_saveChat"
:params [(->rpc chat)]
:on-success #(log/debug "saved chat" chat-id "successfuly")
:on-failure #(log/error "failed to save chat" chat-id %)}))
(defn save-chat-tx
"Returns tx function for saving chat"
[chat]
(fn [realm]
(log/debug "saving chat" chat)
(core/create
realm
:chat
(-> chat
(update :membership-updates marshal-membership-updates)
(utils/update-if-present :last-message-content messages/prepare-content))
true)))
(fx/defn fetch-chats-rpc [cofx {:keys [from to on-success]}]
(json-rpc/call {:method "shhext_chats"
:params [from to]
:on-success #(on-success (map <-rpc %))
:on-failure #(log/error "failed to fetch chats" from to %)}))
;; Only used in debug mode
(defn delete-chat-tx
"Returns tx function for hard deleting the chat"
[chat-id]
(fn [realm]
(core/delete realm (core/get-by-field realm :chat :chat chat-id))))
(defn- get-chat-by-id [chat-id realm]
(.objectForPrimaryKey realm "chat" chat-id))
(defn clear-history-tx
"Returns tx function for clearing the history of chat"
[chat-id deleted-at-clock-value]
(fn [realm]
(let [chat (get-chat-by-id chat-id realm)]
(doto chat
(aset "last-message-content" nil)
(aset "last-message-content-type" nil)
(aset "deleted-at-clock-value" deleted-at-clock-value)))))
(defn deactivate-chat-tx
"Returns tx function for deactivating chat"
[chat-id now]
(fn [realm]
(let [chat (get-chat-by-id chat-id realm)]
(doto chat
(aset "is-active" false)))))
(defn add-chat-contacts-tx
"Returns tx function for adding chat contacts"
[chat-id contacts]
(fn [realm]
(let [chat (get-chat-by-id chat-id realm)
existing-contacts (object/get chat "contacts")]
(aset chat "contacts"
(clj->js (into #{} (concat contacts
(core/list->clj existing-contacts))))))))
(defn remove-chat-contacts-tx
"Returns tx function for removing chat contacts"
[chat-id contacts]
(fn [realm]
(let [chat (get-chat-by-id chat-id realm)
existing-contacts (object/get chat "contacts")]
(aset chat "contacts"
(clj->js (remove (into #{} contacts)
(core/list->clj existing-contacts)))))))
(defn add-chat-tag-tx
"Returns tx function for adding chat contacts"
[chat-id tag]
(fn [realm]
(let [chat (get-chat-by-id chat-id realm)
existing-tags (object/get chat "tags")]
(aset chat "tags"
(clj->js (into #{} (concat tag
(core/list->clj existing-tags))))))))
(defn remove-chat-tag-tx
"Returns tx function for removing chat contacts"
[chat-id tag]
(fn [realm]
(let [chat (get-chat-by-id chat-id realm)
existing-tags (object/get chat "tags")]
(aset chat "tags"
(clj->js (remove (into #{} tag)
(core/list->clj existing-tags)))))))
(defn delete-chat-rpc [chat-id chat-type]
(json-rpc/call {:method "shhext_deleteChat"
:params [chat-id chat-type]
:on-success #(log/debug "deleteed chat" chat-id chat-type)
:on-failure #(log/error "failed to delete chat" chat-id chat-type %)}))

View File

@ -1,5 +1,8 @@
(ns status-im.data-store.contacts
(:require [re-frame.core :as re-frame]
[status-im.utils.fx :as fx]
[status-im.data-store.chats :as data-store.chats]
[status-im.ethereum.json-rpc :as json-rpc]
[taoensso.timbre :as log]
[status-im.data-store.realm.core :as core]))
@ -69,9 +72,7 @@
(when-let [user-messages
(get-messages-by-messages-ids messages-ids)]
(core/delete realm user-messages))
(when-let [chat
(get-chat public-key)]
(core/delete realm chat))))
(data-store.chats/delete-chat-rpc public-key data-store.chats/one-to-one-chat-type)))
(defn delete-contact-tx
"Returns tx function for deleting contact"

View File

@ -32,6 +32,11 @@
"shhext_loadFilters" {}
"shhext_loadFilter" {}
"shhext_removeFilters" {}
"shhext_chats" {}
"shhext_saveChat" {}
"shhext_contacts" {}
"shhext_deleteChat" {}
"shhext_saveContact" {}
"status_joinPublicChat" {}
"status_chats" {}
"status_startOneOnOneChat" {}

View File

@ -114,16 +114,6 @@
(fn [cofx [_ encryption-key error]]
(init/handle-init-store-error cofx encryption-key)))
(handlers/register-handler-fx
:init-rest-of-chats
[(re-frame/inject-cofx :web3/get-web3)
(re-frame/inject-cofx :data-store/all-chats)]
(fn [{:keys [db] :as cofx} [_]]
(log/debug "PERF" :init-rest-of-chats (.now js/Date))
(fx/merge cofx
{:db (assoc db :chats/loading? false)}
(chat.loading/initialize-chats {:from 10}))))
(defn multiaccount-change-success
[{:keys [db] :as cofx} [_ address nodes]]
(let [{:node/keys [status]} db]
@ -135,15 +125,13 @@
(multiaccounts.login/login)
(node/initialize (get-in db [:multiaccounts/login :address])))
(init/initialize-multiaccount address)
(mailserver/initialize-ranges)
(chat.loading/initialize-chats {:to 10}))))
(mailserver/initialize-ranges))))
(handlers/register-handler-fx
:init.callback/multiaccount-change-success
[(re-frame/inject-cofx :web3/get-web3)
(re-frame/inject-cofx :data-store/get-all-contacts)
(re-frame/inject-cofx :data-store/get-all-installations)
(re-frame/inject-cofx :data-store/all-chats)
(re-frame/inject-cofx :data-store/all-chat-requests-ranges)]
multiaccount-change-success)

View File

@ -5,7 +5,7 @@
[clojure.string :as string]
[re-frame.core :as re-frame]
[status-im.multiaccounts.model :as multiaccounts.model]
[status-im.pairing.core :as pairing]
[status-im.utils.pairing :as pairing.utils]
[status-im.chat.models :as models.chat]
[status-im.chat.models.message :as models.message]
[status-im.contact.core :as models.contact]
@ -125,7 +125,7 @@
members-allowed (filter
(fn [pk]
(if (= pk current-public-key)
(pairing/has-paired-installations? cofx)
(pairing.utils/has-paired-installations? cofx)
true))
members)
destinations (map (fn [member]

View File

@ -5,6 +5,7 @@
[status-im.data-store.core :as data-store]
[status-im.ethereum.json-rpc :as json-rpc]
[status-im.ethereum.subscriptions :as ethereum.subscriptions]
[status-im.chat.models.loading :as chat.loading]
[status-im.ethereum.transactions.core :as transactions]
[status-im.fleet.core :as fleet]
[status-im.i18n :as i18n]
@ -207,6 +208,7 @@
(tribute-to-talk/init)
(mobile-network/on-network-status-change)
(protocol/initialize-protocol)
(chat.loading/initialize-chats {:to -1})
(universal-links/process-stored-event)
(chaos-mode/check-chaos-mode)
(finish-keycard-setup)

View File

@ -3,6 +3,7 @@
[clojure.string :as string]
[status-im.i18n :as i18n]
[status-im.utils.fx :as fx]
[status-im.utils.pairing :as pairing.utils]
[status-im.ethereum.json-rpc :as json-rpc]
[status-im.contact.device-info :as device-info]
[status-im.contact.db :as contact.db]
@ -79,12 +80,6 @@
{:transport/confirm-messages-processed [{:web3 (:web3 db)
:js-obj raw-message}]})
(defn has-paired-installations? [cofx]
(->>
(get-in cofx [:db :pairing/installations])
vals
(some :enabled?)))
(defn send-pair-installation [cofx payload]
(let [{:keys [web3]} (:db cofx)
current-public-key (multiaccounts.model/current-public-key cofx)]
@ -303,7 +298,7 @@
:payload payload}]}))
(fx/defn send-installation-message-fx [cofx payload]
(when (has-paired-installations? cofx)
(when (pairing.utils/has-paired-installations? cofx)
(protocol/send payload nil cofx)))
(fx/defn sync-public-chat [cofx chat-id]

View File

@ -80,7 +80,6 @@
"discovery.summary" (summary cofx event)
"subscriptions.data" (ethereum.subscriptions/handle-signal cofx event)
"subscriptions.error" (ethereum.subscriptions/handle-error cofx event)
"status.chats.did-change" (chat.loading/load-chats-from-rpc cofx)
"whisper.filter.added" (transport.filters/handle-negotiated-filter cofx event)
"messages.new" (transport.message/receive-messages cofx event)
"wallet" (ethereum.subscriptions/new-wallet-event cofx event)

View File

@ -40,7 +40,6 @@
[{:keys [db web3 all-installations] :as cofx}]
(fx/merge cofx
(fetch-node-info-fx)
(transport.filters/load-filters)
(pairing/init all-installations)
(publisher/start-fx)
(mailserver/connect-to-mailserver)

View File

@ -5,6 +5,7 @@
[status-im.constants :as constants]
[status-im.ethereum.core :as ethereum]
[status-im.transport.db :as transport.db]
[status-im.utils.pairing :as pairing.utils]
[status-im.data-store.transport :as transport-store]
[status-im.transport.utils :as transport.utils]
[status-im.tribute-to-talk.whitelist :as whitelist]
@ -12,12 +13,6 @@
[status-im.utils.fx :as fx]
[taoensso.timbre :as log]))
(defn has-paired-installations? [cofx]
(->>
(get-in cofx [:db :pairing/installations])
vals
(some :enabled?)))
(defn discovery-topic-hash [] (transport.utils/get-topic constants/contact-discovery))
(defprotocol StatusMessage
@ -107,7 +102,7 @@
:user-message
(fx/merge cofx
(when (has-paired-installations? cofx)
(when (pairing.utils/has-paired-installations? cofx)
(send-direct-message current-public-key nil this))
(send-with-pubkey params)))))
(receive [this chat-id signature timestamp cofx]

View File

@ -150,11 +150,6 @@
(views/letsubs [search-filter [:search/filter]
logging-in? [:multiaccounts/login]
{:keys [all-home-items chats]} [:home-items]]
{:component-did-mount
(fn [this]
(let [[_ loading?] (.. this -props -argv)]
(when loading?
(re-frame/dispatch [:init-rest-of-chats]))))}
[react/view {:style styles/chat-list-view}
[react/view {:style styles/chat-list-header}
[search-input search-filter]

View File

@ -16,38 +16,3 @@
(assoc :current-chat-id chat-id))}
(navigation/navigate-to-cofx :group-chat-profile nil))))
(handlers/register-handler-fx
:add-new-group-chat-participants
[(re-frame/inject-cofx :random-id-generator)]
(fn [{{:keys [current-chat-id selected-participants] :as db} :db
now :now random-id-generator :random-id-generator :as cofx} _]
(let [message-id (random-id-generator)
participants (concat (get-in db [:chats current-chat-id :contacts]) selected-participants)
contacts (:contacts/contacts db)
added-participants-names (map #(get-in contacts [% :name]) selected-participants)]
(fx/merge cofx
{:db (-> db
(assoc-in [:chats current-chat-id :contacts] participants)
(assoc :selected-participants #{}))
:data-store/tx [(chats-store/add-chat-contacts-tx current-chat-id selected-participants)]}
#_(models.message/receive
(models.message/system-message current-chat-id message-id now
(str "You've added " (apply str (interpose ", " added-participants-names)))))
#_(transport/send (protocol/GroupAdminUpdate. nil participants current-chat-id) current-chat-id)))))
(handlers/register-handler-fx
:remove-group-chat-participants
[(re-frame/inject-cofx :random-id-generator)]
(fn [{{:keys [current-chat-id] :as db} :db now :now random-id-generator :random-id-generator :as cofx}
[_ removed-participants]]
(let [message-id (random-id-generator)
participants (remove removed-participants (get-in db [:chats current-chat-id :contacts]))
contacts (:contacts/contacts db)
removed-participants-names (map #(get-in contacts [% :name]) removed-participants)]
(fx/merge cofx
{:db (assoc-in db [:chats current-chat-id :contacts] participants)
:data-store/tx [(chats-store/remove-chat-contacts-tx current-chat-id removed-participants)]}
#_(models.message/receive
(models.message/system-message current-chat-id message-id now
(str "You've removed " (apply str (interpose ", " removed-participants-names)))))
#_(transport/send (protocol/GroupAdminUpdate. nil participants current-chat-id) current-chat-id)))))

View File

@ -126,9 +126,6 @@
{:keys [search-filter chats all-home-items]} [:home-items]
window-width [:dimensions/window-width]
two-pane-ui-enabled? [:two-pane-ui-enabled?]]
{:component-did-mount (fn [this]
(let [[_ loading?] (.. this -props -argv)]
(when loading? (utils/set-timeout #(re-frame/dispatch [:init-rest-of-chats]) 100))))}
(let [home-width (if (> window-width constants/two-pane-min-width)
(max constants/left-pane-min-width (/ window-width 3))
window-width)]

View File

@ -0,0 +1,11 @@
(ns ^{:doc "Pairing utils"}
status-im.utils.pairing)
(defn has-paired-installations? [cofx]
(let [our-installation-id (get-in cofx [:db :multiaccount :installation-id])]
(->>
(get-in cofx [:db :pairing/installations])
vals
(some (fn [{:keys [enabled? installation-id]}]
(and (not= installation-id our-installation-id)
enabled?))))))

View File

@ -2,7 +2,7 @@
"_comment": "DO NOT EDIT THIS FILE BY HAND. USE 'scripts/update-status-go.sh <tag>' instead",
"owner": "status-im",
"repo": "status-go",
"version": "9de77b21b22aeca3c71050ed4f7809f500e63191",
"commit-sha1": "9de77b21b22aeca3c71050ed4f7809f500e63191",
"src-sha256": "1wpyijxqcq1c1ra6vp6sr8zg91r0awpdx5ypgdrvhlnl3mba4k1g"
"version": "a3a413b5d98f227ff541ad9527c8d24e9c9ce653",
"commit-sha1": "a3a413b5d98f227ff541ad9527c8d24e9c9ce653",
"src-sha256": "07sgvpmmjiigga73gymbq1ifm047frmrxn3dr26ihw50p0kp0fwh"
}

View File

@ -13,8 +13,7 @@
:db {:contacts/contacts {chat-id
{:name contact-name}}}}
response (chat/upsert-chat cofx chat-props)
actual-chat (get-in response [:db :chats chat-id])
store-chat-fx (:data-store/tx response)]
actual-chat (get-in response [:db :chats chat-id])]
(testing "it adds the chat to the chats collection"
(is actual-chat))
(testing "it adds the extra props"
@ -26,9 +25,7 @@
(testing "it sets the timestamp"
(is (= "now" (:timestamp actual-chat))))
(testing "it adds the contact-id to the contact field"
(is (= chat-id (-> actual-chat :contacts first))))
(testing "it adds the fx to store a chat"
(is store-chat-fx))))
(is (= chat-id (-> actual-chat :contacts first))))))
(testing "upserting an existing chat"
(let [chat-id "some-chat-id"
chat-props {:chat-id chat-id
@ -37,24 +34,19 @@
cofx {:db {:chats {chat-id {:is-active true
:name "old-name"}}}}
response (chat/upsert-chat cofx chat-props)
actual-chat (get-in response [:db :chats chat-id])
store-chat-fx (:data-store/tx response)]
actual-chat (get-in response [:db :chats chat-id])]
(testing "it adds the chat to the chats collection"
(is actual-chat))
(testing "it adds the extra props"
(is (= "some" (:extra-prop actual-chat))))
(testing "it updates existins props"
(is (= "new-name" (:name actual-chat))))
(testing "it adds the fx to store a chat"
(is store-chat-fx)))))
(is (= "new-name" (:name actual-chat)))))))
(deftest add-public-chat
(let [topic "topic"
fx (chat/add-public-chat {:db {}} topic)
store-fx (:data-store/tx fx)
chat (get-in fx [:db :chats topic])]
(testing "it saves the chat in the database"
(is store-fx))
(testing "it sets the name"
(is (= topic (:name chat))))
(testing "it sets the participants"
@ -104,7 +96,7 @@
(testing "it adds the relevant transactions for realm"
(let [actual (chat/clear-history cofx chat-id)]
(is (:data-store/tx actual))
(is (= 2 (count (:data-store/tx actual))))))))
(is (= 1 (count (:data-store/tx actual))))))))
(deftest remove-chat-test
(let [chat-id "1"
@ -142,7 +134,7 @@
(testing "it adds the relevant transactions for realm"
(let [actual (chat/remove-chat cofx chat-id)]
(is (:data-store/tx actual))
(is (= 6 (count (:data-store/tx actual))))))))
(is (= 4 (count (:data-store/tx actual))))))))
(deftest multi-user-chat?
(let [chat-id "1"]
@ -183,7 +175,7 @@
me (get-in test-db [:multiaccount :public-key])]
(is (= '(true true true)
(map (comp :seen second) (get-in fx [:db :chats "status" :messages]))))
(is (= 2 (count (:data-store/tx fx))))
(is (= 1 (count (:data-store/tx fx))))
;; for public chats, no confirmation is sent out
(is (= nil (:shh/post fx)))))

View File

@ -3,38 +3,140 @@
[status-im.utils.random :as utils.random]
[status-im.data-store.chats :as chats]))
(deftest ->to-rpc
(let [chat {:referenced-messages []
:public? false
:group-chat true
:message-groups {}
:color "color"
:contacts #{"a" "b" "c" "d"}
:last-clock-value 10
:admins #{"a" "b"}
:members-joined #{"a" "c"}
:name "name"
:membership-updates [{:chat-id "chat-id"
:from "a"
:signature "b"
:events [{:type "chat-created"
:name "test"
:clock-value 1}
{:type "members-added"
:clock-value 2
:members ["a" "b"]}]}]
:gaps-loaded? true
:unviewed-messages-count 2
:is-active true
:messages {}
:pagination-info {}
:last-message-content "content"
:last-message-content-type "type"
:group-chat-local-version 1
:chat-id "chat-id"
:loaded-unviewed-messages-ids []
:timestamp 2
:messages-initialized? true}
expected-chat {:id "chat-id"
:color "color"
:name "name"
:chatType 3
:lastMessageContent "content"
:lastMessageContentType "type"
:members #{{:id "a"
:admin true
:joined true}
{:id "b"
:admin true
:joined false}
{:id "c"
:admin false
:joined true}
{:id "d"
:admin false
:joined false}}
:lastClockValue 10
:membershipUpdates #{{:type "chat-created"
:name "test"
:clockValue 1
:id "0xcdf4a63e0c98d0018cf532b3a48350bb80e292cc46249e3f876aaa65eb97a231"
:signature "b"
:from "a"}
{:type "members-added"
:clockValue 2
:members ["a" "b"]
:id "0x1c34d6b4d022c432b7eb6b645e095791af0c6bdb626db7d705e6db0d7cd74b56"
:signature "b"
:from "a"}}
:unviewedMessagesCount 2
:active true
:timestamp 2}]
(testing "marshaling chat"
(is (= expected-chat (-> (chats/->rpc chat)
(update :members #(into #{} %))
(update :membershipUpdates #(into #{} %))))))))
(deftest normalize-chat-test
(testing "admins & contacts"
(is (= {:admins #{4}
:contacts #{2}
:tags #{}
:membership-updates []
:members-joined #{}
:last-message-content {:foo "bar"}
:last-clock-value nil}
(chats/normalize-chat
{:admins [4]
:contacts [2]
:last-message-content "{:foo \"bar\"}"}))))
(testing "membership-updates"
(let [raw-events {"1" {:id "1" :type "members-added" :clock-value 10 :members [1 2] :signature "a" :from "id-1"}
"2" {:id "2" :type "member-removed" :clock-value 11 :member 1 :signature "a" :from "id-1"}
"3" {:id "3" :type "chat-created" :clock-value 0 :name "blah" :signature "b" :from "id-2"}}
expected #{{:chat-id "chat-id"
:from "id-2"
:signature "b"
:events [{:type "chat-created" :clock-value 0 :name "blah"}]}
{:chat-id "chat-id"
:signature "a"
:from "id-1"
:events [{:type "members-added" :clock-value 10 :members [1 2]}
{:type "member-removed" :clock-value 11 :member 1}]}}
actual (->> (chats/normalize-chat {:chat-id "chat-id"
:membership-updates raw-events})
:membership-updates
(into #{}))]
(is (= expected
actual)))))
(let [chat {:id "chat-id"
:color "color"
:name "name"
:chatType 3
:members [{:id "a"
:admin true
:joined true}
{:id "b"
:admin true
:joined false}
{:id "c"
:admin false
:joined true}
{:id "d"
:admin false
:joined false}]
:lastClockValue 10
:lastMessageContent "\"content\"" ;; goes through edn/read-string
:lastMessageContentType "type"
:membershipUpdates [{:type "chat-created"
:name "test"
:clockValue 1
:id "0xcdf4a63e0c98d0018cf532b3a48350bb80e292cc46249e3f876aaa65eb97a231"
:signature "b"
:from "a"}
{:type "members-added"
:clockValue 2
:members ["a" "b"]
:id "0x1c34d6b4d022c432b7eb6b645e095791af0c6bdb626db7d705e6db0d7cd74b56"
:signature "b"
:from "a"}]
:unviewedMessagesCount 2
:active true
:timestamp 2}
expected-chat {:public? false
:group-chat true
:color "color"
:last-message-content "content"
:last-message-content-type "type"
:contacts #{"a" "b" "c" "d"}
:last-clock-value 10
:admins #{"a" "b"}
:members-joined #{"a" "c"}
:name "name"
:membership-updates [{:chat-id "chat-id"
:from "a"
:signature "b"
:events [{:type "chat-created"
:name "test"
:clock-value 1}
{:type "members-added"
:clock-value 2
:members ["a" "b"]}]}]
:unviewed-messages-count 2
:is-active true
:group-chat-local-version 1
:chat-id "chat-id"
:timestamp 2}]
(testing "from-rpc"
(is (= expected-chat (chats/<-rpc chat))))))
(deftest marshal-membership-updates-test
(let [raw-updates [{:chat-id "chat-id"
@ -46,8 +148,8 @@
:from "id-2"
:events [{:type "members-added" :clock-value 10 :members [1 2]}
{:type "member-removed" :clock-value 11 :member 1}]}]
expected #{{:type "members-added" :clock-value 10 :from "id-2" :members [1 2] :signature "a" :id "0xb7690375de21da4890d2d5acca8b56e327d9eb75fd3b4bcceca4bf1679c2f830"}
{:type "member-removed" :clock-value 11 :from "id-2" :member 1 :signature "a" :id "0x2a66f195abf6e6903c4245e372e1e2e6aea2b2c0a74ad03080a313e94197a64f"}
{:type "chat-created" :clock-value 0 :from "id-1" :name "blah" :signature "b" :id "0x7fad22accf1dec64daedf83e7af19b0dcde8c5facfb479874a48da5fb6967e07"}}
expected #{{:type "members-added" :clockValue 10 :from "id-2" :members [1 2] :signature "a" :id "0xb7690375de21da4890d2d5acca8b56e327d9eb75fd3b4bcceca4bf1679c2f830"}
{:type "member-removed" :clockValue 11 :from "id-2" :member 1 :signature "a" :id "0x2a66f195abf6e6903c4245e372e1e2e6aea2b2c0a74ad03080a313e94197a64f"}
{:type "chat-created" :clockValue 0 :from "id-1" :name "blah" :signature "b" :id "0x7fad22accf1dec64daedf83e7af19b0dcde8c5facfb479874a48da5fb6967e07"}}
actual (into #{} (chats/marshal-membership-updates raw-updates))]
(is (= expected actual))))

View File

@ -1,5 +1,6 @@
(ns status-im.test.group-chats.core
(:require [cljs.test :refer-macros [deftest is testing]]
[status-im.ethereum.json-rpc :as json-rpc]
[status-im.utils.clocks :as utils.clocks]
[status-im.utils.config :as config]
[status-im.group-chats.core :as group-chats]))
@ -492,7 +493,8 @@
:a "a-value"}]))))
(deftest remove-group-chat-test
(with-redefs [utils.clocks/send inc]
(with-redefs [json-rpc/call (constantly nil)
utils.clocks/send inc]
(let [cofx {:db {:chats {chat-id {:admins #{member-1 member-2}
:name "chat-name"
:chat-id chat-id

View File

@ -2,6 +2,7 @@
(:require [cljs.test :refer-macros [deftest is testing]]
[status-im.transport.message.pairing :as transport.pairing]
[status-im.utils.identicon :as identicon]
[status-im.utils.pairing :as pairing.utils]
[status-im.utils.config :as config]
[status-im.pairing.core :as pairing]))
@ -308,11 +309,18 @@
(deftest has-paired-installations-test
(testing "no paired devices"
(is (not (pairing/has-paired-installations? {:db {:pairing/installations {"1" {}
"2" {}}}}))))
(is (not (pairing.utils/has-paired-installations? {:db {:multiaccount {:installation-id "1"}
:pairing/installations {"1" {:installation-id "1"
:enabled? true}
"2" {:installation-id "2"}
"3" {:installation-id "3"}}}}))))
(testing "has paired devices"
(is (pairing/has-paired-installations? {:db {:pairing/installations {"1" {}
"2" {:enabled? true}}}}))))
(is (pairing.utils/has-paired-installations? {:db {:pairing/installations {:multiaccount {:instllation-id "1"}
"1" {:installation-id "1"
:enabled? true}
"2" {:installation-id "2"}
"3" {:installation-id "3"
:enabled? true}}}}))))
(deftest sort-installations
(let [id "0"

View File

@ -38,8 +38,7 @@
cofx {:db db
:web3 :web3
:all-contacts data/all-contacts
:all-installations []
:get-all-stored-chats data/get-chats}
:all-installations []}
efx (events/multiaccount-change-success cofx [nil "address"])
new-db (:db efx)]
(testing "Starting node."
@ -52,8 +51,6 @@
(is (= [:home nil] (efx :status-im.ui.screens.navigation/navigate-to))))
(testing "Multiaccount selected."
(is (contains? new-db :multiaccount)))
(testing "Chats initialized."
(is (= 3 (count (:chats new-db)))))
(testing "Contacts initialized."
(is (= 2 (count (:contacts/contacts new-db))))))))

View File

@ -14,8 +14,6 @@
:sym-key "sk3"}
"4" {:topic "topic-4"}}
:semaphores #{}}}]
(testing "it loads the filters"
(is (:filters/load-filters (transport/init-whisper cofx))))
(testing "custom mailservers"
(let [ms-1 {:id "1"
:fleet :eth.beta