From fee9793934855470a552e263654f1da521798d24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arne=20Schl=C3=BCter?= Date: Mon, 11 Jun 2018 23:02:21 +0200 Subject: [PATCH] Implement logout (closes #9) --- src/cljs/airsonic_ui/events.cljs | 47 ++++++++++++++++---------- src/cljs/airsonic_ui/views.cljs | 3 +- test/cljs/airsonic_ui/events_test.cljs | 13 +++++++ 3 files changed, 43 insertions(+), 20 deletions(-) diff --git a/src/cljs/airsonic_ui/events.cljs b/src/cljs/airsonic_ui/events.cljs index 791439a..85493d8 100644 --- a/src/cljs/airsonic_ui/events.cljs +++ b/src/cljs/airsonic_ui/events.cljs @@ -24,7 +24,9 @@ (fn [_] db/default-db)) +;; --- ;; auth logic +;; --- (defn authenticate "Tries to authenticate a user by pinging the server with credentials, saving @@ -50,8 +52,7 @@ [::credentials-verified user pass])}) (re-frame/reg-event-fx - ::verify-auth-response - verify-auth-response) + ::verify-auth-response verify-auth-response) (defn try-remember-user "Enables skipping the auth request when credentials are saved in the @@ -97,9 +98,20 @@ {:routes/navigate [::routes/main] :show-nav-bar nil})) -;; TODO: Test that credentials are actually taken -;; TODO: Move these in the future? events.cljs should just do wiring. We could -;; implement api.cljs as a completely independent module. +(defn logout + "Clears all credentials and redirects the user to the login page" + [_ _] + {:routes/navigate [::routes/login] + :routes/unset-credentials nil + :store nil + :db db/default-db}) + +(re-frame/reg-event-fx + ::logout logout) + +;; --- +;; api interaction +;; --- (defn- api-url [db endpoint params] (let [creds (:credentials db)] @@ -113,8 +125,7 @@ :on-failure [:api/bad-response]}}) (re-frame/reg-event-fx - :api/request - api-request) + :api/request api-request) (defn good-api-response [fx [_ response]] (try @@ -123,8 +134,7 @@ {:dispatch [:notification/show :error (api/error-msg e)]}))) (re-frame/reg-event-fx - :api/good-response - good-api-response) + :api/good-response good-api-response) (re-frame/reg-event-fx :api/bad-response @@ -132,7 +142,9 @@ {:log ["API call gone bad; are CORS headers missing? check for :status 0" event] :dispatch [:notification/show :error "Communication with server failed. Check browser logs for details."]})) +;; --- ;; musique +;; --- ; TODO: Make play, next and previous a bit prettier and more DRY @@ -180,7 +192,9 @@ ; we receive this from the player once it's playing (assoc-in db [:currently-playing :status] status))) +;; --- ;; routing +;; --- (re-frame/reg-event-fx :routes/navigation @@ -192,13 +206,12 @@ (re-frame/reg-event-fx :routes/unauthorized - (fn [fx _] - ;; log out on 403 - {:routes/navigate [routes/default-route] - :routes/unset-credentials nil - :db db/default-db})) + (fn [_ _] + {:dispatch [::logout]})) +;; --- ;; user messages +;; --- (def notification-duration {:info 2500 @@ -222,13 +235,11 @@ (assoc :dispatch-later (hide-later level)))))) (re-frame/reg-event-fx - :notification/show - show-notification) + :notification/show show-notification) (defn hide-notification [db [_ notification-id]] (update db :notifications dissoc notification-id)) (re-frame/reg-event-db - :notification/hide - hide-notification) + :notification/hide hide-notification) diff --git a/src/cljs/airsonic_ui/views.cljs b/src/cljs/airsonic_ui/views.cljs index ef0df93..9ed8af6 100644 --- a/src/cljs/airsonic_ui/views.cljs +++ b/src/cljs/airsonic_ui/views.cljs @@ -42,9 +42,8 @@ [:p.menu-label "User area"] [:ul.menu-list [:li [:a "Settings"]] - ;; FIXME: Create proper logout event [:li [:a - {:on-click #(dispatch [::events/initialize-db]) :href "#"} + {:on-click #(dispatch [::events/logout]) :href "#"} (str "Logout (" (:name user) ")")]]]]) ;; putting everything together diff --git a/test/cljs/airsonic_ui/events_test.cljs b/test/cljs/airsonic_ui/events_test.cljs index adf1f4d..53b0c67 100644 --- a/test/cljs/airsonic_ui/events_test.cljs +++ b/test/cljs/airsonic_ui/events_test.cljs @@ -2,6 +2,8 @@ (:require [cljs.test :refer [deftest testing is]] [clojure.string :as str] [airsonic-ui.fixtures :refer [responses]] + [airsonic-ui.db :as db] + [airsonic-ui.routes :as routes] [airsonic-ui.events :as events])) (enable-console-print!) @@ -51,6 +53,17 @@ (testing "remembering has no effect" (is (nil? (events/try-remember-user {} [:_])))))) +(deftest logout + (let [fx (events/logout {} [:_])] + (testing "Should clear all stored data" + (is (nil? (:store fx)))) + (testing "Should redirect to the login screen" + (is (= [::routes/login] (:routes/navigate fx)))) + (testing "Should unset authentication in the router" + (is (contains? fx :routes/unset-credentials))) + (testing "Should reset the app-db" + (is (= db/default-db (:db fx)))))) + (defn- first-notification [fx] (-> (get-in fx [:db :notifications]) vals first))