Delete mailservers

Signed-off-by: Andrea Maria Piana <andrea.maria.piana@gmail.com>
This commit is contained in:
Andrea Maria Piana 2018-06-01 10:04:48 +02:00
parent af318822da
commit 7ef3a5a5da
No known key found for this signature in database
GPG Key ID: AA6CCA6DE0E06424
10 changed files with 233 additions and 119 deletions

View File

@ -9,7 +9,7 @@
(core/get-all :mailserver)
(core/all-clj :mailserver)))))
(defn save-mailserver-tx
(defn save-tx
"Returns tx function for saving a mailserver"
[{:keys [id] :as mailserver}]
(fn [realm]
@ -17,3 +17,10 @@
:mailserver
mailserver
(core/exists? realm :mailserver :id id))))
(defn delete-tx
"Returns tx function for deleting a mailserver"
[id]
(fn [realm]
(core/delete realm
(core/get-by-field realm :mailserver :id id))))

View File

@ -0,0 +1,86 @@
(ns status-im.models.mailserver
(:require
[clojure.string :as string]
[status-im.utils.handlers-macro :as handlers-macro]
[status-im.utils.ethereum.core :as ethereum]
[status-im.utils.inbox :as utils.inbox]
[status-im.data-store.mailservers :as data-store.mailservers]))
(defn- extract-address-components [address]
(rest (re-matches #"enode://(.*)@(.*)" address)))
(defn- get-chain [db]
(let [network (get (:networks (:account/account db)) (:network db))]
(ethereum/network->chain-keyword network)))
(defn- build [id mailserver-name address]
(assoc (utils.inbox/address->mailserver address)
:id (string/replace id "-" "")
:name mailserver-name))
(defn build-url [address password]
(let [[initial host] (extract-address-components address)]
(str "enode://" initial ":" password "@" host)))
(defn set-input [input-key value {:keys [db]}]
{:db (update
db
:mailservers/manage
assoc
input-key
{:value value
:error (case input-key
:id false
:name (string/blank? value)
:url (not (utils.inbox/valid-enode-address? value)))})})
(defn connected? [id {:keys [db]}]
(let [current-id (get-in db [:account/account :settings :wnode (get-chain db)])]
(= current-id id)))
(defn fetch [id {:keys [db]}]
(get-in db [:inbox/wnodes (get-chain db) id]))
(def default? (comp not :user-defined fetch))
(defn delete [id {:keys [db] :as cofx}]
(when-not (or
(default? id cofx)
(connected? id cofx))
{:db (update-in db [:inbox/wnodes (get-chain db)] dissoc id)
:data-store/tx [(data-store.mailservers/delete-tx id)]}))
(defn edit [id {:keys [db] :as cofx}]
(let [{:keys [id
address
password
name]} (fetch id cofx)
url (when address (build-url address password))
fxs (handlers-macro/merge-fx
cofx
(set-input :id id)
(set-input :url (str url))
(set-input :name (str name)))]
(assoc fxs :dispatch [:navigate-to :edit-mailserver])))
(defn upsert [{{:mailservers/keys [manage] :account/keys [account] :as db} :db :as cofx}]
(let [{:keys [name url id]} manage
network (get (:networks (:account/account db)) (:network db))
chain (ethereum/network->chain-keyword network)
mailserver (build
(or (:value id)
(string/replace (:random-id cofx) "-" ""))
(:value name)
(:value url))
current (connected? (:id mailserver) cofx)]
{:db (-> db
(dissoc :mailservers/manage)
(assoc-in [:inbox/wnodes chain (:id mailserver)] mailserver))
:data-store/tx [{:transaction
(data-store.mailservers/save-tx (assoc
mailserver
:chain
chain))
;; we naively logout if the user is connected to the edited mailserver
:success-event (when current [:logout])}]
:dispatch [:navigate-back]}))

View File

@ -1,22 +0,0 @@
(ns status-im.models.wnode
(:require
[clojure.string :as string]
[status-im.utils.ethereum.core :as ethereum]))
(defn- extract-address-components [address]
(rest (re-matches #"enode://(.*)@(.*)" address)))
(defn- get-chain [db]
(let [network (get (:networks (:account/account db)) (:network db))]
(ethereum/network->chain-keyword network)))
(defn get-wnode [wnode-id {:keys [db]}]
(get-in db [:inbox/wnodes (get-chain db) wnode-id]))
(defn current-wnode? [wnode-id {:keys [db]}]
(let [current-wnode-id (get-in db [:account/account :settings :wnode (get-chain db)])]
(= current-wnode-id wnode-id)))
(defn build-url [address password]
(let [[initial host] (extract-address-components address)]
(str "enode://" initial ":" password "@" host)))

View File

@ -597,6 +597,9 @@
;; TODO(dmitryn): come up with better description/naming. Suggested namings: Mailbox and Master Node
:existing-wnodes "Existing mailservers"
:add-mailserver "Add Mailserver"
:delete-mailserver-title "Delete mailserver"
:delete-mailserver-are-you-sure "Are you sure you want to delete this mailserver?"
:delete-mailserver "Delete mailserver"
:mailserver-address "Mailserver address"
:specify-mailserver-address "Specify a mailserver address"
:add-json-file "Add a JSON file"

View File

@ -1,79 +1,32 @@
(ns status-im.ui.screens.offline-messaging-settings.edit-mailserver.events
(:require [clojure.string :as string]
[re-frame.core :as re-frame]
[status-im.models.wnode :as models.wnode]
[status-im.utils.handlers :refer [register-handler] :as handlers]
[status-im.utils.handlers-macro :as handlers-macro]
[status-im.ui.screens.accounts.utils :as accounts.utils]
[status-im.utils.ethereum.core :as ethereum]
[status-im.utils.types :as types]
[status-im.utils.inbox :as utils.inbox]
[status-im.data-store.mailservers :as data-store.mailservers]))
(defn- build-mailserver [id mailserver-name address]
(assoc (utils.inbox/address->mailserver address)
:id (string/replace id "-" "")
:name mailserver-name))
(defn upsert-mailserver [{{:mailservers/keys [manage] :account/keys [account] :as db} :db :as cofx} _]
(let [{:keys [name url id]} manage
network (get (:networks (:account/account db)) (:network db))
chain (ethereum/network->chain-keyword network)
mailserver (build-mailserver
(or (:value id)
(string/replace (:random-id cofx) "-" ""))
(:value name)
(:value url))
connected-to-wnode? (models.wnode/current-wnode? (:id mailserver) cofx)]
{:db (-> db
(dissoc :mailservers/manage)
(assoc-in [:inbox/wnodes chain (:id mailserver)] mailserver))
:data-store/tx [{:transaction
(data-store.mailservers/save-mailserver-tx (assoc
mailserver
:chain
chain))
;; we naively logout if the user is connected to the edited mailserver
:success-event (when connected-to-wnode? [:logout])}]
:dispatch [:navigate-back]}))
(defn set-input [input-key value {:keys [db]}]
{:db (update db :mailservers/manage assoc input-key {:value value
:error (case input-key
:id false
:name (string/blank? value)
:url (not (utils.inbox/valid-enode-address? value)))})})
(defn edit-mailserver [wnode-id {:keys [db] :as cofx}]
(let [{:keys [id
address
password
name]} (models.wnode/get-wnode wnode-id cofx)
url (when address (models.wnode/build-url address password))
fxs (handlers-macro/merge-fx
cofx
(set-input :id id)
(set-input :url (str url))
(set-input :name (str name)))]
(assoc fxs :dispatch [:navigate-to :edit-mailserver])))
(:require [re-frame.core :as re-frame]
[status-im.models.mailserver :as models.mailserver]
[status-im.utils.handlers :refer [register-handler] :as handlers]))
(handlers/register-handler-fx
:upsert-mailserver
[(re-frame/inject-cofx :random-id)]
upsert-mailserver)
(fn [cofx _]
(models.mailserver/upsert cofx)))
(handlers/register-handler-fx
:mailserver-set-input
(fn [cofx [_ input-key value]]
(set-input input-key value cofx)))
(models.mailserver/set-input input-key value cofx)))
(handlers/register-handler-fx
:edit-mailserver
(fn [cofx [_ wnode-id]]
(edit-mailserver wnode-id cofx)))
(fn [cofx [_ mailserver-id]]
(models.mailserver/edit mailserver-id cofx)))
(handlers/register-handler-fx
:delete-mailserver
(fn [cofx [_ mailserver-id]]
(assoc (models.mailserver/delete mailserver-id cofx)
:dispatch [:navigate-back])))
(handlers/register-handler-fx
:set-mailserver-from-qr
(fn [cofx [_ _ contact-identity]]
(assoc (set-input :url contact-identity cofx)
(assoc (models.mailserver/set-input :url contact-identity cofx)
:dispatch [:navigate-back])))

View File

@ -30,30 +30,28 @@
:margin-horizontal 12
:margin-vertical 15})
(def connect-button-container
(def button-container
{:margin-top 8
:margin-bottom 16
:margin-horizontal 16})
(defstyle connect-button
(def button
{:height 52
:align-items :center
:justify-content :center
:background-color colors/blue
:border-radius 8
:ios {:opacity 0.9}})
(defstyle connect-button-label
(defstyle connect-button
(assoc button
:background-color colors/blue))
(defstyle delete-button
(assoc button
:background-color colors/red))
(defstyle button-label
{:color colors/white
:ios {:font-size 17
:letter-spacing -0.2}
:android {:font-size 14}})
(defstyle connect-button-description
{:color colors/gray
:ios {:margin-top 8
:height 20
:font-size 14
:letter-spacing -0.2}
:android {:margin-top 12
:font-size 12}})

View File

@ -1,5 +1,7 @@
(ns status-im.ui.screens.offline-messaging-settings.edit-mailserver.subs
(:require [re-frame.core :refer [reg-sub]]))
(:require
[re-frame.core :refer [reg-sub]]
[status-im.models.mailserver :as models.mailserver]))
(reg-sub
:get-manage-mailserver
@ -7,6 +9,12 @@
(fn [manage]
manage))
(reg-sub
:get-connected-mailserver
(fn [db]
(models.mailserver/connected? (get-in db [:mailservers/manage :id :value])
{:db db})))
(reg-sub
:manage-mailserver-valid?
:<- [:get-manage-mailserver]

View File

@ -4,6 +4,7 @@
[re-frame.core :as re-frame]
[status-im.ui.components.react :as react]
[status-im.i18n :as i18n]
[status-im.utils.utils :as utils]
[status-im.ui.components.colors :as colors]
[status-im.ui.components.icons.vector-icons :as vector-icons]
[status-im.ui.components.styles :as components.styles]
@ -14,15 +15,30 @@
[status-im.ui.components.text-input.view :as text-input]
[status-im.ui.screens.offline-messaging-settings.edit-mailserver.styles :as styles]))
(defn handle-delete [id]
(utils/show-confirmation (i18n/label :t/delete-mailserver-title)
(i18n/label :t/delete-mailserver-are-you-sure)
(i18n/label :t/delete-mailserver)
#(re-frame/dispatch [:delete-mailserver id])))
(defn connect-button [id]
[react/touchable-highlight {:on-press #(re-frame/dispatch [:connect-wnode id])}
[react/view styles/connect-button-container
[react/view styles/button-container
[react/view {:style styles/connect-button
:accessibility-label :mailserver-connect-button}
[react/text {:style styles/connect-button-label
[react/text {:style styles/button-label
:uppercase? true}
(i18n/label :t/connect)]]]])
(defn delete-button [id]
[react/touchable-highlight {:on-press #(handle-delete id)}
[react/view styles/button-container
[react/view {:style styles/delete-button
:accessibility-label :mailserver-delete-button}
[react/text {:style styles/button-label
:uppercase? true}
(i18n/label :t/delete)]]]])
(def qr-code
[react/touchable-highlight {:on-press #(re-frame/dispatch [:scan-qr-code
{:toolbar-title (i18n/label :t/add-mailserver)}
@ -33,6 +49,7 @@
(views/defview edit-mailserver []
(views/letsubs [manage-mailserver [:get-manage-mailserver]
connected? [:get-connected-mailserver]
is-valid? [:manage-mailserver-valid?]]
(let [url (get-in manage-mailserver [:url :value])
id (get-in manage-mailserver [:id :value])
@ -59,7 +76,11 @@
:container styles/input-container
:default-value url
:on-change-text #(re-frame/dispatch [:mailserver-set-input :url %])}]
(when id [connect-button id])]]
(when (and id
(not connected?))
[react/view
[connect-button id]
[delete-button id]])]]
[react/view styles/bottom-container
[react/view components.styles/flex]
[components.common/bottom-button

View File

@ -1,6 +1,6 @@
(ns status-im.test.offline-messaging-settings.events
(ns status-im.test.models.mailserver
(:require [cljs.test :refer-macros [deftest is testing]]
[status-im.ui.screens.offline-messaging-settings.edit-mailserver.events :as events]))
[status-im.models.mailserver :as model]))
(def enode-id "1da276e34126e93babf24ec88aac1a7602b4cbb2e11b0961d0ab5e989ca9c261aa7f7c1c85f15550a5f1e5a5ca2305b53b9280cf5894d5ecf7d257b173136d40")
(def password "password")
@ -14,20 +14,20 @@
(testing "correct name"
(is (= {:db {:mailservers/manage {:name {:value "value"
:error false}}}}
(events/set-input :name "value" {}))))
(model/set-input :name "value" {}))))
(testing "blank name"
(is (= {:db {:mailservers/manage {:name {:value ""
:error true}}}}
(events/set-input :name "" {})))))
(model/set-input :name "" {})))))
(testing "it validates enodes url"
(testing "correct url"
(is (= {:db {:mailservers/manage {:url {:value valid-enode-url
:error false}}}}
(events/set-input :url valid-enode-url {}))))
(model/set-input :url valid-enode-url {}))))
(testing "broken url"
(is (= {:db {:mailservers/manage {:url {:value "broken"
:error true}}}}
(events/set-input :url "broken" {}))))))
(model/set-input :url "broken" {}))))))
(deftest edit-mailserver
(let [db {:network "mainnet_rpc"
@ -40,7 +40,7 @@
:name "name"}}}}
cofx {:db db}]
(testing "when no id is given"
(let [actual (events/edit-mailserver nil cofx)]
(let [actual (model/edit nil cofx)]
(testing "it resets :mailserver/manage"
(is (= {:id {:value nil
:error false}
@ -54,7 +54,7 @@
(-> actual :dispatch))))))
(testing "when an id is given"
(testing "when the wnode is in the list"
(let [actual (events/edit-mailserver "a" cofx)]
(let [actual (model/edit "a" cofx)]
(testing "it populates the fields with the correct values"
(is (= {:id {:value "a"
:error false}
@ -67,7 +67,7 @@
(is (= [:navigate-to :edit-mailserver]
(-> actual :dispatch))))))
(testing "when the wnode is not in the list"
(let [actual (events/edit-mailserver "not-existing" cofx)]
(let [actual (model/edit "not-existing" cofx)]
(testing "it populates the fields with the correct values"
(is (= {:id {:value nil
:error false}
@ -80,6 +80,66 @@
(is (= [:navigate-to :edit-mailserver]
(-> actual :dispatch)))))))))
(deftest connected-mailserver
(testing "it returns true when set in settings"
(let [cofx {:db {:network "mainnet_rpc"
:account/account {:settings {:wnode {:mainnet "a"}}
:networks {"mainnet_rpc"
{:config {:NetworkId 1}}}}
:inbox/wnodes {:mainnet {"a" {:id "a"
:name "old-name"
:address "enode://old-id:old-password@url:port"}}}}}]
(is (model/connected? "a" cofx)))))
(deftest fetch-mailserver
(testing "it fetches the mailserver from the db"
(let [cofx {:db {:network "mainnet_rpc"
:account/account {:networks {"mainnet_rpc"
{:config {:NetworkId 1}}}}
:inbox/wnodes {:mainnet {"a" {:id "a"
:name "old-name"
:address "enode://old-id:old-password@url:port"}}}}}]
(is (model/fetch "a" cofx)))))
(deftest delete-mailserver
(testing "the user is not connected to the mailserver"
(let [cofx {:random-id "random-id"
:db {:network "mainnet_rpc"
:account/account {:networks {"mainnet_rpc"
{:config {:NetworkId 1}}}}
:inbox/wnodes {:mainnet {"a" {:id "a"
:name "old-name"
:user-defined true
:address "enode://old-id:old-password@url:port"}}}}}
actual (model/delete "a" cofx)]
(testing "it removes the mailserver from the list"
(is (not (model/fetch "a" actual))))
(testing "it stores it in the db"
(is (= 1 (count (:data-store/tx actual)))))))
(testing "the mailserver is not user-defined"
(let [cofx {:random-id "random-id"
:db {:network "mainnet_rpc"
:account/account {:networks {"mainnet_rpc"
{:config {:NetworkId 1}}}}
:inbox/wnodes {:mainnet {"a" {:id "a"
:name "old-name"
:address "enode://old-id:old-password@url:port"}}}}}
actual (model/delete "a" cofx)]
(testing "it does not delete the mailserver"
(is (nil? actual)))))
(testing "the user is connected to the mailserver"
(let [cofx {:random-id "random-id"
:db {:network "mainnet_rpc"
:account/account {:settings {:wnode {:mainnet "a"}}
:networks {"mainnet_rpc"
{:config {:NetworkId 1}}}}
:inbox/wnodes {:mainnet {"a" {:id "a"
:name "old-name"
:address "enode://old-id:old-password@url:port"}}}}}
actual (model/delete "a" cofx)]
(testing "it does not remove the mailserver from the list"
(is (nil? actual))))))
(deftest upsert-mailserver
(testing "new mailserver"
(let [cofx {:random-id "random-id"
@ -90,7 +150,7 @@
:url {:value "enode://test-id:test-password@url:port"}}
:inbox/wnodes {}}}
actual (events/upsert-mailserver cofx nil)]
actual (model/upsert cofx)]
(testing "it adds the enode to inbox/wnodes"
(is (= {:mainnet {"randomid" {:password "test-password"
@ -116,7 +176,7 @@
:inbox/wnodes {:mainnet {"a" {:id "a"
:name "old-name"
:address "enode://old-id:old-password@url:port"}}}}}
actual (events/upsert-mailserver cofx nil)]
actual (model/upsert cofx)]
(testing "it navigates back"
(is (= [:navigate-back]
(:dispatch actual))))
@ -130,9 +190,9 @@
(testing "it stores it in the db"
(is (= 1 (count (:data-store/tx actual)))))
(testing "it logs the user out if connected to the current mailserver"
(let [actual (events/upsert-mailserver (assoc-in cofx
[:db :account/account :settings]
{:wnode
{:mainnet "a"}}) nil)]
(let [actual (model/upsert (assoc-in cofx
[:db :account/account :settings]
{:wnode
{:mainnet "a"}}))]
(is (= [:logout]
(-> actual :data-store/tx first :success-event))))))))

View File

@ -10,7 +10,7 @@
[status-im.test.wallet.transactions.views]
[status-im.test.profile.events]
[status-im.test.bots.events]
[status-im.test.offline-messaging-settings.events]
[status-im.test.models.mailserver]
[status-im.test.transport.core]
[status-im.test.chat.models]
[status-im.test.chat.models.input]
@ -57,7 +57,7 @@
'status-im.test.contacts.subs
'status-im.test.profile.events
'status-im.test.data-store.realm.core
'status-im.test.offline-messaging-settings.events
'status-im.test.models.mailserver
'status-im.test.bots.events
'status-im.test.transport.core
'status-im.test.wallet.subs