Merge pull request #117 from status-im/appium-setup

Appium setup & unit tests
This commit is contained in:
Jarrad 2016-06-02 11:52:39 +02:00
commit ba1d5d1c4e
33 changed files with 330 additions and 183 deletions

9
.gitignore vendored
View File

@ -50,3 +50,12 @@ target/
# #
figwheel_server.log figwheel_server.log
.nrepl-port .nrepl-port
# Lein
#
.lein-failures
## Doo
#
out
doo-index.html

View File

@ -10,7 +10,7 @@
(def root-el (r/as-element [reloader])) (def root-el (r/as-element [reloader]))
(figwheel/watch-and-reload (figwheel/watch-and-reload
:websocket-url "ws://10.0.3.2:3449/figwheel-ws" :websocket-url "ws://localhost:3449/figwheel-ws"
:heads-up-display false :heads-up-display false
:jsload-callback #(swap! cnt inc)) :jsload-callback #(swap! cnt inc))

View File

@ -8,7 +8,7 @@
[reagent "0.5.1" :exclusions [cljsjs/react]] [reagent "0.5.1" :exclusions [cljsjs/react]]
[re-frame "0.6.0"] [re-frame "0.6.0"]
[prismatic/schema "1.0.4"] [prismatic/schema "1.0.4"]
^{:voom {:repo "https://github.com/status-im/status-lib.git" ^{:voom {:repo "git@github.com:status-im/status-lib.git"
:branch "master"}} :branch "master"}}
[status-im/protocol "0.1.1-20160525_083359-g53ab2c2"] [status-im/protocol "0.1.1-20160525_083359-g53ab2c2"]
[natal-shell "0.1.6"] [natal-shell "0.1.6"]
@ -20,9 +20,12 @@
["do" "clean" ["do" "clean"
["with-profile" "prod" "cljsbuild" "once" "ios"] ["with-profile" "prod" "cljsbuild" "once" "ios"]
["with-profile" "prod" "cljsbuild" "once" "android"]]} ["with-profile" "prod" "cljsbuild" "once" "android"]]}
:test-paths ["test/clj"]
:figwheel {:nrepl-port 7888} :figwheel {:nrepl-port 7888}
:profiles {:dev {:dependencies [[figwheel-sidecar "0.5.0-2"] :profiles {:dev {:dependencies [[figwheel-sidecar "0.5.0-2"]
[com.cemerick/piggieback "0.2.1"]] [com.cemerick/piggieback "0.2.1"]
[io.appium/java-client "3.4.1"]]
:plugins [[lein-doo "0.1.6"]]
:source-paths ["src" "env/dev"] :source-paths ["src" "env/dev"]
:cljsbuild {:builds {:ios {:source-paths ["src" "env/dev"] :cljsbuild {:builds {:ios {:source-paths ["src" "env/dev"]
:figwheel true :figwheel true
@ -35,7 +38,13 @@
:compiler {:output-to "target/android/not-used.js" :compiler {:output-to "target/android/not-used.js"
:main "env.android.main" :main "env.android.main"
:output-dir "target/android" :output-dir "target/android"
:optimizations :none}}}} :optimizations :none}}
:test {:source-paths ["src" "test/cljs"]
:compiler
{:main status-im.test.runner
:output-to "target/test/test.js"
:optimizations :none
:target :nodejs}}}}
:repl-options {:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}} :repl-options {:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}}
:prod {:cljsbuild {:builds {:ios {:source-paths ["src" "env/prod"] :prod {:cljsbuild {:builds {:ios {:source-paths ["src" "env/prod"]
:compiler {:output-to "index.ios.js" :compiler {:output-to "index.ios.js"
@ -46,5 +55,4 @@
:compiler {:output-to "index.android.js" :compiler {:output-to "index.android.js"
:main "env.android.main" :main "env.android.main"
:output-dir "target/android" :output-dir "target/android"
:optimizations :simple}}}} :optimizations :simple}}}}}})
}})

View File

@ -17,11 +17,13 @@ function tab () {
fi fi
osascript &>/dev/null <<EOF osascript &>/dev/null <<EOF
tell application "iTerm" tell application "iTerm2"
tell current terminal tell current window
launch session "Default Session" set newTab to (create tab with default profile)
tell the last session tell newTab
write text "cd \"$cdto\"$cmd" tell current session
write text "cd \"$cdto\"$cmd"
end tell
end tell end tell
end tell end tell
end tell end tell
@ -59,3 +61,10 @@ sleep 10s
adb reverse tcp:8081 tcp:8081 && adb reverse tcp:3449 tcp:3449 adb reverse tcp:8081 tcp:8081 && adb reverse tcp:3449 tcp:3449
react-native run-android react-native run-android
if [ ! -z $2 ]
then
tab "appium"
lein test
lein doo node test once
fi

View File

@ -1 +1,4 @@
(ns cljsjs.react) (ns cljsjs.react)
(when (exists? js/window)
(set! js/window.React (js/require "react-native")))

View File

@ -38,11 +38,13 @@
:onChangeText set-input-message :onChangeText set-input-message
:onSubmitEditing (fn [] :onSubmitEditing (fn []
(when (valid? message validator) (when (valid? message validator)
(send-command)))} (send-command)))
:accessibility-label :command-input}
input-options) input-options)
message] message]
(if (valid? message validator) (if (valid? message validator)
[touchable-highlight {:on-press send-command} [touchable-highlight {:on-press send-command
:accessibility-label :stage-command}
[view st/send-container [icon :send st/send-icon]]] [view st/send-container [icon :send st/send-icon]]]
[touchable-highlight {:on-press cancel-command-input} [touchable-highlight {:on-press cancel-command-input}
[view st/cancel-container [view st/cancel-container

View File

@ -72,13 +72,18 @@
(defn set-chat-command [msg-id command] (defn set-chat-command [msg-id command]
(dispatch [:set-response-chat-command msg-id (:command command)])) (dispatch [:set-response-chat-command msg-id (:command command)]))
(defn label [{:keys [command]}]
(->> (name command)
(str "request-")))
(defn message-content-command-request (defn message-content-command-request
[{:keys [msg-id content from incoming-group]}] [{:keys [msg-id content from incoming-group]}]
(let [commands-atom (subscribe [:get-commands])] (let [commands-atom (subscribe [:get-commands])]
(fn [{:keys [msg-id content from incoming-group]}] (fn [{:keys [msg-id content from incoming-group]}]
(let [commands @commands-atom (let [commands @commands-atom
{:keys [command content]} (parse-command-request commands content)] {:keys [command content]} (parse-command-request commands content)]
[touchable-highlight {:onPress #(set-chat-command msg-id command)} [touchable-highlight {:onPress #(set-chat-command msg-id command)
:accessibility-label (label command)}
[view st/comand-request-view [view st/comand-request-view
[view st/command-request-message-view [view st/command-request-message-view
(when incoming-group (when incoming-group

View File

@ -1,9 +1,9 @@
(ns status-im.chat.views.plain-input (ns status-im.chat.views.plain-input
(:require [re-frame.core :refer [subscribe dispatch]] (:require [re-frame.core :refer [subscribe dispatch]]
[status-im.components.react :refer [view [status-im.components.react :refer [view
icon icon
touchable-highlight touchable-highlight
text-input]] text-input]]
[status-im.chat.views.suggestions :refer [suggestions-view]] [status-im.chat.views.suggestions :refer [suggestions-view]]
[status-im.chat.styles.plain-input :as st])) [status-im.chat.styles.plain-input :as st]))
@ -39,15 +39,16 @@
(if @typing-command? (if @typing-command?
[icon :close-gray st/close-icon] [icon :close-gray st/close-icon]
[icon :list st/list-icon])]] [icon :list st/list-icon])]]
[text-input {:style st/message-input [text-input {:style st/message-input
:autoFocus (pos? (count @staged-commands-atom)) :autoFocus (pos? (count @staged-commands-atom))
:onChangeText set-input-message :onChangeText set-input-message
:onSubmitEditing #(try-send @chat @staged-commands-atom :onSubmitEditing #(try-send @chat @staged-commands-atom
input-message)} input-message)}
input-message] input-message]
;; TODO emoticons: not implemented ;; TODO emoticons: not implemented
[icon :smile st/smile-icon] [icon :smile st/smile-icon]
(when (message-valid? @staged-commands-atom input-message) (when (message-valid? @staged-commands-atom input-message)
[touchable-highlight {:on-press #(send @chat input-message)} [touchable-highlight {:on-press #(send @chat input-message)
:accessibility-label :send-message}
[view st/send-container [view st/send-container
[icon :send st/send-icon]]])]])))) [icon :send st/send-icon]]])]]))))

View File

@ -1,7 +1,7 @@
(ns status-im.components.action-button (ns status-im.components.action-button
(:require [reagent.core :as r])) (:require [reagent.core :as r]))
(set! js/window.ActionButton (js/require "react-native-action-button")) (def class (js/require "react-native-action-button"))
(def action-button (r/adapt-react-class (.-default js/ActionButton))) (def action-button (r/adapt-react-class (.-default class)))
(def action-button-item (r/adapt-react-class (.. js/ActionButton -default -Item))) (def action-button-item (r/adapt-react-class (.. class -default -Item)))

View File

@ -5,11 +5,12 @@
touchable-without-feedback touchable-without-feedback
text]] text]]
[status-im.components.carousel.styles :as st] [status-im.components.carousel.styles :as st]
[status-im.utils.logging :as log])) [status-im.utils.logging :as log]
[status-im.components.react :as r]))
(defn window-page-width [] (defn window-page-width []
(.-width (.get (.. js/React -Dimensions) "window"))) (.-width (.get (.. r/react -Dimensions) "window")))
(def defaults {:gap 10 (def defaults {:gap 10
:sneak 10 :sneak 10

View File

@ -2,14 +2,14 @@
(:require [clojure.string :as s] (:require [clojure.string :as s]
[re-frame.core :refer [subscribe dispatch dispatch-sync]] [re-frame.core :refer [subscribe dispatch dispatch-sync]]
[reagent.core :as r] [reagent.core :as r]
[status-im.components.react :refer [android? [status-im.components.react :refer [react
view view
text text
image image
navigator navigator
toolbar-android toolbar-android
drawer-layout-android drawer-layout-android
touchable-opacity]] touchable-opacity]]
[status-im.resources :as res] [status-im.resources :as res]
[status-im.components.drawer.styles :as st] [status-im.components.drawer.styles :as st]
[status-im.i18n :refer [label]])) [status-im.i18n :refer [label]]))
@ -29,7 +29,7 @@
:style st/user-photo}]) :style st/user-photo}])
(defn menu-item [{:keys [name handler]}] (defn menu-item [{:keys [name handler]}]
[touchable-opacity {:style st/menu-item-touchable [touchable-opacity {:style st/menu-item-touchable
:onPress (fn [] :onPress (fn []
(close-drawer) (close-drawer)
(handler))} (handler))}
@ -40,40 +40,40 @@
(let [username (subscribe [:get :username])] (let [username (subscribe [:get :username])]
(fn [] (fn []
[view st/drawer-menu [view st/drawer-menu
[view st/user-photo-container [view st/user-photo-container
[user-photo {}]] [user-photo {}]]
[view st/name-container [view st/name-container
[text {:style st/name-text} [text {:style st/name-text}
@username]] @username]]
[view st/menu-items-container [view st/menu-items-container
[menu-item {:name (label :t/profile) [menu-item {:name (label :t/profile)
:handler #(dispatch [:navigate-to :my-profile])}] :handler #(dispatch [:navigate-to :my-profile])}]
[menu-item {:name (label :t/settings) [menu-item {:name (label :t/settings)
:handler (fn [] :handler (fn []
;; TODO not implemented ;; TODO not implemented
)}] )}]
[menu-item {:name (label :t/discovery) [menu-item {:name (label :t/discovery)
:handler #(dispatch [:navigate-to :discovery])}] :handler #(dispatch [:navigate-to :discovery])}]
[menu-item {:name (label :t/contacts) [menu-item {:name (label :t/contacts)
:handler #(dispatch [:show-contacts navigator])}] :handler #(dispatch [:show-contacts navigator])}]
[menu-item {:name (label :t/invite-friends) [menu-item {:name (label :t/invite-friends)
:handler (fn [] :handler (fn []
;; TODO not implemented ;; TODO not implemented
)}] )}]
[menu-item {:name (label :t/faq) [menu-item {:name (label :t/faq)
:handler (fn [])}]] :handler (fn [])}]]
[view st/switch-users-container [view st/switch-users-container
[touchable-opacity {:onPress (fn [] [touchable-opacity {:onPress (fn []
(close-drawer) (close-drawer)
;; TODO not implemented ;; TODO not implemented
)} )}
[text {:style st/switch-users-text} [text {:style st/switch-users-text}
(label :t/switch-users)]]]]))) (label :t/switch-users)]]]])))
(defn drawer-view [items] (defn drawer-view [items]
[drawer-layout-android {:drawerWidth 260 [drawer-layout-android {:drawerWidth 260
:drawerPosition js/React.DrawerLayoutAndroid.positions.Left :drawerPosition js/React.DrawerLayoutAndroid.positions.Left
:render-navigation-view #(r/as-element [drawer-menu]) :render-navigation-view #(r/as-element [drawer-menu])
:ref (fn [drawer] :ref (fn [drawer]
(reset! drawer-atom drawer))} (reset! drawer-atom drawer))}
items]) items])

View File

@ -1,6 +1,4 @@
(ns status-im.components.icons.ionicons (ns status-im.components.icons.ionicons
(:require [reagent.core :as r])) (:require [reagent.core :as r]))
(set! js/window.Ionicons (js/require "react-native-vector-icons/Ionicons")) (def icon (r/adapt-react-class (js/require "react-native-vector-icons/Ionicons")))
(def icon (r/adapt-react-class js/Ionicons))

View File

@ -1,8 +1,8 @@
(ns status-im.components.invertible-scroll-view) (ns status-im.components.invertible-scroll-view
(:require [reagent.core :as r]))
(set! js/window.InvertibleScrollView (js/require "react-native-invertible-scroll-view")) (def class (js/require "react-native-invertible-scroll-view"))
(defn invertible-scroll-view [props] (defn invertible-scroll-view [props]
(js/React.createElement js/InvertibleScrollView (r/create-element class (clj->js (merge {:inverted true} props))))
(clj->js (merge {:inverted true} props))))

View File

@ -1,7 +1,5 @@
(ns status-im.components.item-checkbox (ns status-im.components.item-checkbox
(:require [reagent.core :as r])) (:require [reagent.core :as r]))
(set! js/window.ItemCheckbox (js/require "react-native-circle-checkbox")) (def item-checkbox (r/adapt-react-class (js/require "react-native-circle-checkbox")))
(def item-checkbox (r/adapt-react-class js/ItemCheckbox))

View File

@ -1,26 +1,36 @@
(ns status-im.components.react (ns status-im.components.react
(:require [reagent.core :as r] (:require [reagent.core :as r]
[status-im.components.styles :as st])) [status-im.components.styles :as st]
[status-im.utils.utils :as u]))
(set! js/window.React (js/require "react-native")) (def react (u/require "react-native"))
(def app-registry (.-AppRegistry js/React)) (defn get-react-property [name]
(def navigator (r/adapt-react-class (.-Navigator js/React))) (aget react name))
(def text (r/adapt-react-class (.-Text js/React)))
(def view (r/adapt-react-class (.-View js/React))) (defn adapt-class [class]
(def image (r/adapt-react-class (.-Image js/React))) (when class (r/adapt-react-class class)))
(def touchable-highlight-class (r/adapt-react-class (.-TouchableHighlight js/React)))
(defn get-class [name]
(adapt-class (get-react-property name)))
(def app-registry (get-react-property "AppRegistry"))
(def navigator (get-class "Navigator"))
(def text (get-class "Text"))
(def view (get-class "View"))
(def image (get-class "Image"))
(def touchable-highlight-class (get-class "TouchableHighlight"))
(defn touchable-highlight [props content] (defn touchable-highlight [props content]
[touchable-highlight-class [touchable-highlight-class
(merge {:underlay-color :transparent} props) (merge {:underlay-color :transparent} props)
content]) content])
(def toolbar-android (r/adapt-react-class (.-ToolbarAndroid js/React))) (def toolbar-android (get-class "ToolbarAndroid"))
(def list-view-class (r/adapt-react-class (.-ListView js/React))) (def list-view-class (get-class "ListView"))
(defn list-view [props] (defn list-view [props]
[list-view-class (merge {:enableEmptySections true} props)]) [list-view-class (merge {:enableEmptySections true} props)])
(def scroll-view (r/adapt-react-class (.-ScrollView js/React))) (def scroll-view (get-class "ScrollView"))
(def touchable-without-feedback (r/adapt-react-class (.-TouchableWithoutFeedback js/React))) (def touchable-without-feedback (get-class "TouchableWithoutFeedback"))
(def text-input-class (r/adapt-react-class (.-TextInput js/React))) (def text-input-class (get-class "TextInput"))
(defn text-input [props text] (defn text-input [props text]
[text-input-class (merge [text-input-class (merge
{:underlineColorAndroid :transparent {:underlineColorAndroid :transparent
@ -28,11 +38,13 @@
:placeholder "Type"} :placeholder "Type"}
props) props)
text]) text])
(def drawer-layout-android (r/adapt-react-class (.-DrawerLayoutAndroid js/React))) (def drawer-layout-android (get-class "DrawerLayoutAndroid"))
(def touchable-opacity (r/adapt-react-class (.-TouchableOpacity js/React))) (def touchable-opacity (get-class "TouchableOpacity"))
(def modal (r/adapt-react-class (.-Modal js/React))) (def modal (get-class "Modal"))
(def picker (r/adapt-react-class (.-Picker js/React))) (def picker (get-class "Picker"))
(def picker-item (r/adapt-react-class (.-Item (.-Picker js/React)))) (def picker-item
(when-let [picker (get-react-property "Picker")]
(adapt-class (.-Item picker))))
(defn icon (defn icon
@ -41,20 +53,18 @@
[image {:source {:uri (keyword (str "icon_" (name n)))} [image {:source {:uri (keyword (str "icon_" (name n)))}
:style style}])) :style style}]))
;(def react-linear-gradient (.-default (js/require "react-native-linear-gradient"))) (def linear-gradient-class (u/require "react-native-linear-gradient"))
;(def linear-gradient (r/adapt-react-class react-linear-gradient))
(set! js/window.LinearGradient (js/require "react-native-linear-gradient"))
(defn linear-gradient [props] (defn linear-gradient [props]
(js/React.createElement js/LinearGradient (r/create-element linear-gradient-class
(clj->js (merge {:inverted true} props)))) (clj->js (merge {:inverted true} props))))
(def platform (.. js/React -Platform -OS)) (def platform
(when-let [pl (.-Platform react)] (.-OS pl)))
(def android? (= platform "android")) (def android? (= platform "android"))
(defn list-item [component] (defn list-item [component]
(r/as-element component)) (r/as-element component))
(def dismiss-keyboard! (js/require "dismissKeyboard")) (def dismiss-keyboard! (u/require "dismissKeyboard"))

View File

@ -1,9 +0,0 @@
(ns status-im.components.realm
(:require [reagent.core :as r]))
(set! js/window.RealmReactNative (js/require "realm/react-native"))
(def list-view-class (r/adapt-react-class (.-ListView js/RealmReactNative)))
(defn list-view [props]
[list-view-class (merge {:enableEmptySections true} props)])

View File

@ -12,9 +12,7 @@
color-purple color-purple
text1-color text1-color
text2-color text2-color
toolbar-background1]] toolbar-background1]]))
[status-im.components.realm :refer [list-view]]
[reagent.core :as r]))
(defn toolbar [{:keys [title nav-action hide-nav? action custom-action (defn toolbar [{:keys [title nav-action hide-nav? action custom-action
background-color custom-content style]}] background-color custom-content style]}]

View File

@ -5,7 +5,8 @@
[clojure.string :as s] [clojure.string :as s]
[status-im.utils.utils :refer [http-post]] [status-im.utils.utils :refer [http-post]]
[status-im.utils.phone-number :refer [format-phone-number]] [status-im.utils.phone-number :refer [format-phone-number]]
[status-im.utils.handlers :as u])) [status-im.utils.handlers :as u]
[status-im.utils.utils :refer [require]]))
(defn save-contact (defn save-contact
[_ [_ contact]] [_ [_ contact]]
@ -26,7 +27,7 @@
(register-handler :load-contacts load-contacts!) (register-handler :load-contacts load-contacts!)
;; TODO see https://github.com/rt2zz/react-native-contacts/issues/45 ;; TODO see https://github.com/rt2zz/react-native-contacts/issues/45
(def react-native-contacts (js/require "react-native-contacts")) (def react-native-contacts (require "react-native-contacts"))
(defn contact-name [contact] (defn contact-name [contact]
(->> contact (->> contact

View File

@ -2,16 +2,16 @@
(:require-macros [status-im.utils.views :refer [defview]]) (:require-macros [status-im.utils.views :refer [defview]])
(:require (:require
[re-frame.core :refer [subscribe]] [re-frame.core :refer [subscribe]]
[status-im.utils.logging :as log]
[status-im.components.react :refer [android? [status-im.components.react :refer [android?
text]] text]]
[status-im.components.carousel.carousel :refer [carousel]] [status-im.components.carousel.carousel :refer [carousel]]
[status-im.discovery.styles :as st] [status-im.discovery.styles :as st]
[status-im.discovery.views.popular-list :refer [discovery-popular-list]] [status-im.discovery.views.popular-list :refer [discovery-popular-list]]
[status-im.i18n :refer [label]])) [status-im.i18n :refer [label]]
[status-im.components.react :as r]))
(defn page-width [] (defn page-width []
(.-width (.get (.. js/React -Dimensions) "window"))) (.-width (.get (.. r/react -Dimensions) "window")))
(defview popular [] (defview popular []
[popular-tags [:get-popular-tags 3]] [popular-tags [:get-popular-tags 3]]

View File

@ -35,15 +35,19 @@
;; -- Common -------------------------------------------------------------- ;; -- Common --------------------------------------------------------------
(defn set-el [db [_ k v]]
(assoc db k v))
(register-handler :set (register-handler :set
(debug debug
(fn [db [_ k v]] set-el)
(assoc db k v))))
(defn set-in [db [_ path v]]
(assoc-in db path v))
(register-handler :set-in (register-handler :set-in
(debug debug
(fn [db [_ path v]] set-in)
(assoc-in db path v))))
(register-handler :initialize-db (register-handler :initialize-db
(fn [_ _] (fn [_ _]

View File

@ -1,26 +1,21 @@
(ns status-im.i18n (ns status-im.i18n
(:require (:require
[status-im.translations.en :as en])) [status-im.translations.en :as en]
[status-im.utils.utils :as u]))
(set! js/window.I18n (js/require "react-native-i18n")) (def i18n (u/require "react-native-i18n"))
(set! (.-fallbacks js/I18n) true) (set! (.-fallbacks i18n) true)
(set! (.-defaultSeparator js/I18n) "/") (set! (.-defaultSeparator i18n) "/")
(set! (.-translations js.I18n) (clj->js {:en en/translations})) (set! (.-translations i18n) (clj->js {:en en/translations}))
(defn label [path & options] (defn label [path & options]
(.t js/I18n (name path) (clj->js options))) (if (exists? i18n.t)
(.t i18n (name path) (clj->js options))
(name path)))
(defn label-pluralize [count path & options] (defn label-pluralize [count path & options]
(.p js/I18n count (name path) (clj->js options))) (if (exists? i18n.t)
(.p i18n count (name path) (clj->js options))
(name path)))
(comment
(defn deep-merge [& maps]
(if (every? map? maps)
(apply merge-with deep-merge maps)
(last maps)))
(defn add-translations [new-translations]
(let [translations (.-translations js/I18n)]
(set! (.-translations js/I18n) (clj->js (deep-merge (js->clj translations) new-translations)))))
)

View File

@ -2,11 +2,10 @@
(:require [cljs.reader :refer [read-string]] (:require [cljs.reader :refer [read-string]]
[status-im.components.styles :refer [default-chat-color]] [status-im.components.styles :refer [default-chat-color]]
[status-im.utils.logging :as log] [status-im.utils.logging :as log]
[status-im.utils.types :refer [to-string]]) [status-im.utils.types :refer [to-string]]
[status-im.utils.utils :as u])
(:refer-clojure :exclude [exists?])) (:refer-clojure :exclude [exists?]))
(set! js/window.Realm (js/require "realm"))
(def opts {:schema [{:name :contacts (def opts {:schema [{:name :contacts
:primaryKey :whisper-identity :primaryKey :whisper-identity
:properties {:phone-number {:type "string" :properties {:phone-number {:type "string"
@ -70,7 +69,10 @@
:objectType "tag"} :objectType "tag"}
:last-updated "date"}}]}) :last-updated "date"}}]})
(def realm (js/Realm. (clj->js opts))) (def realm-class (u/require "realm"))
(def realm (when (cljs.core/exists? js/window)
(realm-class. (clj->js opts))))
(def schema-by-name (->> (:schema opts) (def schema-by-name (->> (:schema opts)
(mapv (fn [{:keys [name] :as schema}] (mapv (fn [{:keys [name] :as schema}]

View File

@ -2,14 +2,14 @@
(:require-macros [status-im.utils.views :refer [defview]]) (:require-macros [status-im.utils.views :refer [defview]])
(:require [re-frame.core :refer [subscribe dispatch]] (:require [re-frame.core :refer [subscribe dispatch]]
[status-im.components.react :refer [view [status-im.components.react :refer [view
text text
image image
icon icon
scroll-view scroll-view
touchable-highlight touchable-highlight
touchable-opacity]] touchable-opacity]]
[status-im.components.chat-icon.screen :refer [profile-icon [status-im.components.chat-icon.screen :refer [profile-icon
my-profile-icon]] my-profile-icon]]
[status-im.profile.styles :as st] [status-im.profile.styles :as st]
[status-im.i18n :refer [label]])) [status-im.i18n :refer [label]]))
@ -60,11 +60,11 @@
[text {:style st/report-user-text} (label :t/report-user)]]]]]) [text {:style st/report-user-text} (label :t/report-user)]]]]])
(defview my-profile [] (defview my-profile []
[username [:get :username] [username [:get :username]
photo-path [:get :photo-path] photo-path [:get :photo-path]
phone-number [:get :phone-number] phone-number [:get :phone-number]
email [:get :email] email [:get :email]
status [:get :status]] status [:get :status]]
[scroll-view {:style st/profile} [scroll-view {:style st/profile}
[touchable-highlight {:style st/back-btn-touchable [touchable-highlight {:style st/back-btn-touchable
:on-press #(dispatch [:navigate-back])} :on-press #(dispatch [:navigate-back])}

View File

@ -1,9 +1,10 @@
(ns status-im.utils.crypt (ns status-im.utils.crypt
(:require [goog.crypt :refer [byteArrayToHex]] (:require [goog.crypt :refer [byteArrayToHex]]
[clojure.string :as s]) [clojure.string :as s]
[status-im.utils.utils :as u])
(:import goog.crypt.Sha256)) (:import goog.crypt.Sha256))
(set! js/window.RnRandomBytes (js/require "react-native-randombytes")) (def random-bytes (u/require "react-native-randombytes"))
(def sha-256 (Sha256.)) (def sha-256 (Sha256.))
@ -19,7 +20,7 @@
(byteArrayToHex (.digest sha-256))) (byteArrayToHex (.digest sha-256)))
(defn gen-random-bytes [length cb] (defn gen-random-bytes [length cb]
(.randomBytes js/window.RnRandomBytes length (fn [& [err buf]] #_(.randomBytes random-bytes length (fn [& [err buf]]
(if err (if err
(cb {:error err}) (cb {:error err})
(cb {:buffer buf}))))) (cb {:buffer buf})))))

View File

@ -1,6 +1,5 @@
(ns status-im.utils.listview (ns status-im.utils.listview
(:require-macros [natal-shell.data-source :refer [data-source]]) (:require-macros [natal-shell.data-source :refer [data-source]]))
(:require [status-im.components.realm]))
(defn clone-with-rows [ds rows] (defn clone-with-rows [ds rows]
(.cloneWithRows ds (reduce (fn [ac el] (.push ac el) ac) (.cloneWithRows ds (reduce (fn [ac el] (.push ac el) ac)

View File

@ -1,16 +1,17 @@
(ns status-im.utils.phone-number) (ns status-im.utils.phone-number
(:require [status-im.utils.utils :as u]))
(def i18n (js/require "react-native-i18n")) (def i18n (u/require "react-native-i18n"))
(def locale (.-locale i18n)) (def locale (or (.-locale i18n) "___en"))
(def country-code (subs locale 3 5)) (def country-code (subs locale 3 5))
(set! js/PhoneNumber (js/require "awesome-phonenumber")) (def awesome-phonenumber (u/require "awesome-phonenumber"))
;; todo check wrong numbers, .getNumber returns empty string ;; todo check wrong numbers, .getNumber returns empty string
(defn format-phone-number [number] (defn format-phone-number [number]
(str (.getNumber (js/PhoneNumber. number country-code "international")))) (str (.getNumber (awesome-phonenumber. number country-code "international"))))
(defn valid-mobile-number? [number] (defn valid-mobile-number? [number]
(when (string? number) (when (string? number)
(let [number-obj (js/PhoneNumber. number country-code "international")] (let [number-obj (awesome-phonenumber. number country-code "international")]
(and (.isValid number-obj) (and (.isValid number-obj)
(.isMobile number-obj))))) (.isMobile number-obj)))))

View File

@ -1,7 +1,8 @@
(ns status-im.utils.sms-listener (ns status-im.utils.sms-listener
(:require [status-im.components.react :refer [android?]])) (:require [status-im.components.react :refer [android?]]
[status-im.utils.utils :as u]))
(def sms-listener (.-default (js/require "react-native-android-sms-listener"))) (def sms-listener (.-default (u/require "react-native-android-sms-listener")))
;; Only android is supported! ;; Only android is supported!

View File

@ -5,6 +5,11 @@
[natal-shell.toast-android :as toast]) [natal-shell.toast-android :as toast])
(:require [status-im.constants :as const])) (:require [status-im.constants :as const]))
(defn require [module]
(if (exists? js/window)
(js/require module)
#js {}))
(defn log [obj] (defn log [obj]
(.log js/console obj)) (.log js/console obj))

View File

@ -0,0 +1,86 @@
(ns status-im.appium
(:require [clojure.java.io :as io]
[clojure.test :refer :all])
(:import (org.openqa.selenium.remote DesiredCapabilities)
(org.openqa.selenium By)
(io.appium.java_client.android AndroidDriver)
(java.net URL)
(java.util.concurrent TimeUnit)))
(defn init []
(let [dir (io/file (str (System/getProperty "user.dir")
"/android/app/build/outputs/apk"))
app (io/file dir "app-debug.apk")
capabilities (doto (DesiredCapabilities.)
(.setCapability "deviceName" "device")
(.setCapability "platformVersion" "6.0.0")
(.setCapability "app" (.getAbsolutePath app))
(.setCapability "appPackage" "com.statusim")
(.setCapability "appActivity" ".MainActivity"))
driver (AndroidDriver. (URL. "http://127.0.0.1:4723/wd/hub") capabilities)]
(-> driver
.manage
.timeouts
(.implicitlyWait 25 TimeUnit/SECONDS))
driver))
(defn by-xpath [driver xpath]
(.findElement driver (By/xpath xpath)))
(defn elements-by-xpath [driver xpath]
(.findElements driver (By/xpath xpath)))
(defn by-id [driver id]
(.findElementByAccessibilityId driver (name id)))
(defn get-element [driver id]
(if (keyword? id)
(by-id driver id)
(by-xpath driver id)))
(defn click [driver id]
(.click (get-element driver id)))
(defn write [driver input-xpath text]
(.sendKeys (get-element driver input-xpath) (into-array [text])))
(defn get-text [driver xpath]
(.getText (by-xpath driver xpath)))
(defn xpath-by-text [text]
(str ".//*[@text='" text "']"))
(defn contains-text [driver text]
(is (= 1 (->> (xpath-by-text text)
(elements-by-xpath driver)
(.size)))))
(defn quit [driver]
(.quit driver))
(defmacro appium-test
"Defines test which will create new appium session and will pass that
session as first argument to each command inside it's body. After execution
of all commands session will be closed.
For instance,
(appium-test my-test
(click :button)
(write :input \"oops\"))
will be expanded to
(deftest my-test
(let [session (init)]
(click session :button)
(write session :input \"oops\")
(quit session)))"
[name & body]
(let [sym (gensym)]
`(deftest ~name
(let [~sym (init)]
~@(for [[f & rest] body]
`(~f ~sym ~@rest))
(quit ~sym)))))

View File

@ -0,0 +1,15 @@
(ns status-im.console
(:require [clojure.test :refer :all]
[status-im.appium :refer :all]))
(def message-text
(str "Your phone number is also required to use the app. Type"
" the exclamation mark or hit the icon to open the command "
"list and choose the !phone command"))
(appium-test console-test
(click :request-keypair-password)
(write :command-input "123")
(click :stage-command)
(click :send-message)
(contains-text message-text))

View File

@ -0,0 +1,6 @@
(ns status-im.test.handlers
(:require [cljs.test :refer-macros [deftest is]]
[status-im.handlers :as h]))
(deftest test-set-val
(is (= {:key :val} (h/set-el {} [nil :key :val]))))

View File

@ -0,0 +1,5 @@
(ns status-im.test.runner
(:require [doo.runner :refer-macros [doo-tests]]
[status-im.test.handlers]))
(doo-tests 'status-im.test.handlers)

View File

@ -1,7 +0,0 @@
(ns status-im.core-test
(:require [clojure.test :refer :all]
[status-im.core :refer :all]))
(deftest a-test
(testing "FIXME, I fail."
(is (= 0 1))))