From a91a945bfa91aa47c81b213bbd716305c014dbc2 Mon Sep 17 00:00:00 2001 From: Andrey Shovkoplyas Date: Wed, 9 Aug 2017 17:42:56 +0300 Subject: [PATCH] tests for group module --- src/status_im/chat/handlers.cljs | 109 +++++++++++++ src/status_im/contacts/events.cljs | 11 -- src/status_im/group/events.cljs | 122 ++------------ src/status_im/handlers.cljs | 3 +- .../status_im/test/contacts/handlers.cljs | 149 +++++++++++++++++- 5 files changed, 266 insertions(+), 128 deletions(-) diff --git a/src/status_im/chat/handlers.cljs b/src/status_im/chat/handlers.cljs index ee3cfb81d1..6644b418aa 100644 --- a/src/status_im/chat/handlers.cljs +++ b/src/status_im/chat/handlers.cljs @@ -535,3 +535,112 @@ (select-keys db [:web3 :current-public-key]))}) {:dispatch-n [[:navigate-to-clean :chat-list] [:navigate-to :chat topic]]})))) + +(reg-fx + ::save-chat + (fn [new-chat] + (chats/save new-chat))) + +(reg-fx + ::start-listen-group + (fn [{:keys [new-chat web3 current-public-key]}] + (let [{:keys [chat-id public-key private-key contacts name]} new-chat + identities (mapv :identity contacts)] + (protocol/invite-to-group! + {:web3 web3 + :group {:id chat-id + :name name + :contacts (conj identities current-public-key) + :admin current-public-key + :keypair {:public public-key + :private private-key}} + :identities identities + :message {:from current-public-key + :message-id (random/id)}}) + (protocol/start-watching-group! + {:web3 web3 + :group-id chat-id + :identity current-public-key + :keypair {:public public-key + :private private-key} + :callback #(dispatch [:incoming-message %1 %2])})))) + +(reg-fx + ::start-watching-group + (fn [{:keys [group-id web3 current-public-key keypair]}] + (protocol/start-watching-group! + {:web3 web3 + :group-id group-id + :identity current-public-key + :keypair keypair + :callback #(dispatch [:incoming-message %1 %2])}))) + +(defn group-name-from-contacts [contacts selected-contacts username] + (->> (select-keys contacts selected-contacts) + vals + (map :name) + (cons username) + (string/join ", "))) + +(defn prepare-group-chat + [{:keys [current-public-key username] + :group/keys [selected-contacts] + :contacts/keys [contacts]} group-name] + (let [selected-contacts' (mapv #(hash-map :identity %) selected-contacts) + chat-name (if-not (string/blank? group-name) + group-name + (group-name-from-contacts contacts selected-contacts username)) + {:keys [public private]} (protocol/new-keypair!)] + {:chat-id (random/id) + :public-key public + :private-key private + :name chat-name + :color default-chat-color + :group-chat true + :group-admin current-public-key + :is-active true + :timestamp (random/timestamp) + :contacts selected-contacts'})) + +(register-handler-fx + :create-new-group-chat-and-open + (fn [{:keys [db]} [_ group-name]] + (let [new-chat (prepare-group-chat (select-keys db [:group/selected-contacts :current-public-key :username + :contacts/contacts]) + group-name)] + {:db (-> db + (assoc-in [:chats (:chat-id new-chat)] new-chat) + (assoc :group/selected-contacts #{})) + ::save-chat new-chat + ::start-listen-group (merge {:new-chat new-chat} + (select-keys db [:web3 :current-public-key])) + :dispatch-n [[:navigate-to-clean :chat-list] + [:navigate-to :chat (:chat-id new-chat)]]}))) + +(register-handler-fx + :group-chat-invite-received + (fn [{{:keys [current-public-key] :as db} :db} + [_ {:keys [from] + {:keys [group-id group-name contacts keypair timestamp]} :payload}]] + (let [{:keys [private public]} keypair] + (let [contacts' (keep (fn [ident] + (when (not= ident current-public-key) + {:identity ident})) contacts) + chat {:chat-id group-id + :name group-name + :group-chat true + :group-admin from + :public-key public + :private-key private + :contacts contacts' + :added-to-at timestamp + :timestamp timestamp + :is-active true} + exists? (chats/exists? group-id)] + (when (or (not exists?) (chats/new-update? timestamp group-id)) + {::start-watching-group (merge {:group-id group-id + :keypair keypair} + (select-keys db [:web3 :current-public-key])) + :dispatch (if exists? + [:update-chat! chat] + [:add-chat group-id chat])}))))) \ No newline at end of file diff --git a/src/status_im/contacts/events.cljs b/src/status_im/contacts/events.cljs index 7f445a708a..7d4bc6d60d 100644 --- a/src/status_im/contacts/events.cljs +++ b/src/status_im/contacts/events.cljs @@ -405,17 +405,6 @@ :pending? true}] [:account-update-keys]]})) -(defn remove-contact-from-group [whisper-identity] - (fn [contacts] - (remove #(= whisper-identity (:identity %)) contacts))) - -(register-handler-fx - :remove-contact-from-group - (fn [{:keys [db]} [_ whisper-identity group-id]] - (let [{:group/keys [contact-groups]} db - group' (update (contact-groups group-id) :contacts (remove-contact-from-group whisper-identity))] - {:dispatch [:update-contact-group group']}))) - ;;used only by status-dev-cli (register-handler-fx :remove-contact diff --git a/src/status_im/group/events.cljs b/src/status_im/group/events.cljs index 6fbf8822cc..a67373d90a 100644 --- a/src/status_im/group/events.cljs +++ b/src/status_im/group/events.cljs @@ -3,7 +3,6 @@ [re-frame.core :refer [dispatch reg-fx reg-cofx inject-cofx]] [status-im.utils.handlers :refer [register-handler-db register-handler-fx]] [status-im.components.styles :refer [default-chat-color]] - [status-im.data-store.chats :as chats] [status-im.data-store.contact-groups :as groups] [clojure.string :as string] [status-im.utils.random :as random] @@ -22,11 +21,6 @@ ;;;; FX -(reg-fx - ::save-chat - (fn [new-chat] - (chats/save new-chat))) - (reg-fx ::save-contact-group (fn [new-group] @@ -47,40 +41,6 @@ (fn [[contact-group-id selected-contacts]] (groups/add-contacts contact-group-id selected-contacts))) -(reg-fx - ::start-listen-group - (fn [{:keys [new-chat web3 current-public-key]}] - (let [{:keys [chat-id public-key private-key contacts name]} new-chat - identities (mapv :identity contacts)] - (protocol/invite-to-group! - {:web3 web3 - :group {:id chat-id - :name name - :contacts (conj identities current-public-key) - :admin current-public-key - :keypair {:public public-key - :private private-key}} - :identities identities - :message {:from current-public-key - :message-id (random/id)}}) - (protocol/start-watching-group! - {:web3 web3 - :group-id chat-id - :identity current-public-key - :keypair {:public public-key - :private private-key} - :callback #(dispatch [:incoming-message %1 %2])})))) - -(reg-fx - ::start-watching-group - (fn [{:keys [group-id web3 current-public-key keypair]}] - (protocol/start-watching-group! - {:web3 web3 - :group-id group-id - :identity current-public-key - :keypair keypair - :callback #(dispatch [:incoming-message %1 %2])}))) - ;;;; Handlers (register-handler-db @@ -103,75 +63,6 @@ (fn [db [_ id]] (update db :selected-participants conj id))) -(defn group-name-from-contacts [contacts selected-contacts username] - (->> (select-keys contacts selected-contacts) - vals - (map :name) - (cons username) - (string/join ", "))) - -(defn prepare-chat [{:keys [current-public-key username] - :group/keys [selected-contacts] - :contacts/keys [contacts]} group-name] - (let [selected-contacts' (mapv #(hash-map :identity %) selected-contacts) - chat-name (if-not (string/blank? group-name) - group-name - (group-name-from-contacts contacts selected-contacts username)) - {:keys [public private]} (protocol/new-keypair!)] - {:chat-id (random/id) - :public-key public - :private-key private - :name chat-name - :color default-chat-color - :group-chat true - :group-admin current-public-key - :is-active true - :timestamp (random/timestamp) - :contacts selected-contacts'})) - -(register-handler-fx - :create-new-group-chat-and-open - (fn [{:keys [db]} [_ group-name]] - (let [new-chat (prepare-chat (select-keys db [:group/selected-contacts :current-public-key :username - :contacts/contacts]) - group-name)] - {:db (-> db - (assoc-in [:chats (:chat-id new-chat)] new-chat) - (assoc :group/selected-contacts #{})) - ::save-chat new-chat - ::start-listen-group (merge {:new-chat new-chat} - (select-keys db [:web3 :current-public-key])) - :dispatch-n [[:navigate-to-clean :chat-list] - [:navigate-to :chat (:chat-id new-chat)]]}))) - -(register-handler-fx - :group-chat-invite-received - (fn [{{:keys [current-public-key] :as db} :db} - [_ {:keys [from] - {:keys [group-id group-name contacts keypair timestamp]} :payload}]] - (let [{:keys [private public]} keypair] - (let [contacts' (keep (fn [ident] - (when (not= ident current-public-key) - {:identity ident})) contacts) - chat {:chat-id group-id - :name group-name - :group-chat true - :group-admin from - :public-key public - :private-key private - :contacts contacts' - :added-to-at timestamp - :timestamp timestamp - :is-active true} - exists? (chats/exists? group-id)] - (when (or (not exists?) (chats/new-update? timestamp group-id)) - {::start-watching-group (merge {:group-id group-id - :keypair keypair} - (select-keys db [:web3 :current-public-key])) - :dispatch (if exists? - [:update-chat! chat] - [:add-chat group-id chat])}))))) - (register-handler-fx :create-new-contact-group (fn [{{:group/keys [contact-groups selected-contacts] :as db} :db} [_ group-name]] @@ -185,7 +76,7 @@ ::save-contact-group new-group}))) (register-handler-fx - :update-contact-group + ::update-contact-group (fn [{:keys [db]} [_ new-group]] {:db (update db :group/contact-groups merge {(:group-id new-group) new-group}) ::save-contact-group new-group})) @@ -262,6 +153,17 @@ {:db (update-in db [:group/contact-groups group-id :contacts] #(into [] (set (concat % new-identities)))) ::add-contacts-to-contact-group [group-id contacts]})))) +(defn remove-contact-from-group [whisper-identity] + (fn [contacts] + (remove #(= whisper-identity (:identity %)) contacts))) + +(register-handler-fx + :remove-contact-from-group + (fn [{:keys [db]} [_ whisper-identity group-id]] + (let [{:group/keys [contact-groups]} db + group' (update (contact-groups group-id) :contacts (remove-contact-from-group whisper-identity))] + {:dispatch [::update-contact-group group']}))) + (register-handler-fx :delete-contact-group (fn [{{:group/keys [contact-group-id] :as db} :db} _] diff --git a/src/status_im/handlers.cljs b/src/status_im/handlers.cljs index 73727755af..f2f17793e9 100644 --- a/src/status_im/handlers.cljs +++ b/src/status_im/handlers.cljs @@ -221,8 +221,7 @@ (.clearWatch navigator.geolocation @watch-id) - (dispatch [:update-geolocation (js->clj % :keywordize-keys true)])))) - (dispatch [:set-in [:debug :watch-id] @watch-id]))))])))) + (dispatch [:update-geolocation (js->clj % :keywordize-keys true)])))))))])))) (register-handler :update-geolocation (fn [db [_ geolocation]] diff --git a/test/cljs/status_im/test/contacts/handlers.cljs b/test/cljs/status_im/test/contacts/handlers.cljs index 1c57e9016c..644200aab2 100644 --- a/test/cljs/status_im/test/contacts/handlers.cljs +++ b/test/cljs/status_im/test/contacts/handlers.cljs @@ -94,10 +94,21 @@ :fullscreen true :suggestions-trigger "on-change"}}) +(def test-contact-group + {:group-id "1501682106404-685e041e-38e7-593e-b42c-fb4cabd7faa4" + :name "Test" + :timestamp 0 + :order 0 + :pending? false + :contacts (list + {:identity "bchat"} + {:identity "Commiteth"} + {:identity "demo-bot"})}) + (def dapps-contact-group {:group-id "dapps" :name "ÐApps" - :order 0 + :order 1 :timestamp 0 :contacts [{:identity "wallet"} {:identity "oaken-water-meter"} @@ -127,6 +138,7 @@ {"browse" browse-contact-from-realm-db "wallet" wallet-contact}) + (defn test-fixtures [] (rf/reg-fx ::handlers/init-store #()) @@ -136,14 +148,22 @@ (rf/reg-fx ::contacts-events/stop-watching-contact #()) (rf/reg-fx ::contacts-events/send-contact-request-fx #()) + (rf/reg-fx ::group-events/save-contact-group #()) (rf/reg-fx ::group-events/save-contact-groups #()) (rf/reg-fx ::group-events/add-contacts-to-contact-group #()) + (rf/reg-fx ::group-events/save-contact-group-property #()) + (rf/reg-fx ::group-events/add-contacts-to-contact-group #()) (rf/reg-cofx ::contacts-events/get-all-contacts (fn [coeffects _] (assoc coeffects :all-contacts [browse-contact-from-realm-db]))) + (rf/reg-cofx + ::group-events/get-all-contact-groups + (fn [coeffects _] + (assoc coeffects :all-groups {(:group-id test-contact-group) test-contact-group}))) + ;;TODO implement tests later for :add-chat? and :bot-url (rf/reg-cofx ::contacts-events/get-default-contacts-and-groups @@ -155,6 +175,7 @@ (deftest contacts-events "load-contacts + load-contact-groups load-default-contacts (add-contact-groups, add-contacts, add-contacts-to-group ;TODO add-chat, load-commands!) add-contact-handler (add-new-contact-and-open-chat, status-im.contacts.events/add-new-contact, status-im.contacts.events/send-contact-request ;TODO start-chat) @@ -162,7 +183,10 @@ contact-update-received (update-contact ;TODO :update-chat!) hide-contact (update-contact ;TODO :account-update-keys) add-contact-handler (add-pending-contact, status-im.contacts.events/add-new-contact - status-im.contacts.events/send-contact-request ;TODO :discoveries-send-portions)" + status-im.contacts.events/send-contact-request ;TODO :discoveries-send-portions) + create-new-contact-group + set-contact-group-name + save-contact-group-order" (run-test-sync @@ -185,11 +209,18 @@ (is (= {"browse" browse-contact-from-realm-db} @contacts)) (is (= browse-global-commands @global-commands))) - (testing ":load-default-contacts! event" + (testing ":load-contact-groups event" ;;Assert the initial state (is (and (map? @contact-groups) (empty? @contact-groups))) + (rf/dispatch [:load-contact-groups]) + + (is (= {(:group-id test-contact-group) test-contact-group} + @contact-groups))) + + (testing ":load-default-contacts! event" + ;; :load-default-contacts! event dispatches next 5 events ;; ;; :add-contact-groups @@ -199,11 +230,17 @@ ;;TODO :load-commands! (rf/dispatch [:load-default-contacts!]) - (is (= {"dapps" dapps-contact-group} (update @contact-groups "dapps" assoc :timestamp 0))) + (rf/dispatch [:set-in [:group/contact-groups "dapps" :timestamp] 0]) + + (is (= {"dapps" dapps-contact-group + (:group-id test-contact-group) test-contact-group} + @contact-groups)) (is (= contacts-browse-wallet @contacts))) + + (let [new-contact-public-key "0x048f7d5d4bda298447bbb5b021a34832509bd1a8dbe4e06f9b7223d00a59b6dc14f6e142b21d3220ceb3155a6d8f40ec115cd96394d3cc7c55055b433a1758dc74" new-contact-address "5392ccb49f2e9fef8b8068b3e3b5ba6c020a9aca" new-contact {:name "" @@ -302,4 +339,106 @@ (is (= (assoc contacts-browse-wallet new-contact-public-key (assoc recieved-contact'' :pending? false)) - @contacts))))))))))) \ No newline at end of file + @contacts))) + + (testing ":create-new-contact-group event" + + (let [new-group-name "new group"] + + (rf/dispatch [:select-contact new-contact-public-key]) + (rf/dispatch [:select-contact "wallet"]) + (rf/dispatch [:select-contact "browse"]) + (rf/dispatch [:deselect-contact "browse"]) + + (rf/dispatch [:create-new-contact-group new-group-name]) + + (rf/dispatch [:deselect-contact "wallet"]) + (rf/dispatch [:deselect-contact new-contact-public-key]) + + (let [new-group-id (->> @contact-groups + (vals) + (filter #(= (:name %) new-group-name)) + (first) + (:group-id)) + new-group {:group-id new-group-id + :name new-group-name + :order 2 + :timestamp 0 + :contacts [{:identity new-contact-public-key} + {:identity "wallet"}]} + groups-with-new-group {new-group-id new-group + "dapps" dapps-contact-group + (:group-id test-contact-group) test-contact-group}] + + (rf/dispatch [:set-in [:group/contact-groups new-group-id :timestamp] 0]) + + (is (= groups-with-new-group @contact-groups)) + + (let [groups-with-new-group' (update groups-with-new-group new-group-id assoc :name "new group name")] + + (testing ":set-contact-group-name event" + + (rf/reg-event-db ::prepare-group-name + (fn [db _] (assoc db :new-chat-name "new group name" + :group/contact-group-id new-group-id))) + + (rf/dispatch [::prepare-group-name]) + (rf/dispatch [:set-contact-group-name]) + + (is (= groups-with-new-group' @contact-groups))) + + (let [groups-with-new-group'' (-> groups-with-new-group' + (update new-group-id assoc :order 1) + (update "dapps" assoc :order 2))] + + (testing ":save-contact-group-order event" + + (rf/reg-event-db ::prepare-groups-order + (fn [db _] + (assoc db :group/groups-order + (->> (vals (:group/contact-groups db)) + (remove :pending?) + (sort-by :order >) + (map :group-id))))) + + (rf/dispatch [::prepare-groups-order]) + (rf/dispatch [:change-contact-group-order 1 0]) + (rf/dispatch [:save-contact-group-order]) + + (is (= groups-with-new-group'' @contact-groups))) + + (testing ":add-selected-contacts-to-group event" + + (rf/dispatch [:select-contact "browse"]) + (rf/dispatch [:add-selected-contacts-to-group]) + (rf/dispatch [:deselect-contact "browse"]) + + (is (= (update groups-with-new-group'' new-group-id assoc :contacts [{:identity new-contact-public-key} + {:identity "wallet"} + {:identity "browse"}]) + @contact-groups))) + + (testing ":remove-contact-from-group event" + + (rf/dispatch [:remove-contact-from-group "browse" new-group-id]) + + (is (= groups-with-new-group'' @contact-groups))) + + + (testing ":add-contacts-to-group event" + + (rf/dispatch [:add-contacts-to-group new-group-id ["browse"]]) + + (is (= (update groups-with-new-group'' new-group-id assoc :contacts [{:identity new-contact-public-key} + {:identity "wallet"} + {:identity "browse"}]) + @contact-groups)) + + (rf/dispatch [:remove-contact-from-group "browse" new-group-id])) + + (testing ":delete-contact-group event" + + (rf/dispatch [:delete-contact-group]) + + (is (= (update groups-with-new-group'' new-group-id assoc :pending? true) + @contact-groups)))))))))))))))) \ No newline at end of file