diff --git a/backend/src/beherbergung/config/state.clj b/backend/src/beherbergung/config/state.clj index caaaddc..d842b4f 100644 --- a/backend/src/beherbergung/config/state.clj +++ b/backend/src/beherbergung/config/state.clj @@ -5,10 +5,13 @@ [config.core] [clojure.string])) -(s/def ::verbose boolean?) +(s/def ::frontend-base-url string?) +(s/def ::frontend-backend-base-url string?) (s/def ::port number?) ;; the webserver port +(s/def ::verbose boolean?) + (s/def ::validate-output boolean?) ;; should specialist ensure type correctness (s/def ::db-inmemory boolean?) ;; we run unit tests in an in-memory instance, otherwise the default db would be looked @@ -17,29 +20,30 @@ (s/def ::db-export-prefix (s/nilable string?)) ;; path where during startup an export should be written (s/def ::db-validate boolean?) +(s/def ::admin-passphrase (s/nilable string?)) ;; allows setting up ngo logins and encrypted downloads of db exports +(s/def ::admin-gpg-id string?) + +(s/def ::import-file string?) + (s/def ::mail-host string?) (s/def ::mail-user string?) (s/def ::mail-pass string?) (s/def ::mail-port number?) (s/def ::mail-from (s/nilable string?)) -(s/def ::admin-passphrase (s/nilable string?)) ;; allows setting up ngo logins and encrypted downloads of db exports -(s/def ::admin-gpg-id string?) - -(s/def ::frontend-base-url string?) -(s/def ::frontend-backend-base-url string?) - -(s/def ::env (s/keys :req-un [::verbose +(s/def ::env (s/keys :req-un [::frontend-base-url + ::frontend-backend-base-url ::port + ::verbose ::validate-output ::db-inmemory ::db-dir ::db-seed ::db-export-prefix ::db-validate - ;::mail-host ::mail-user ::mail-pass ::mail-port ::mail-from ::admin-passphrase ::admin-gpg-id - ::frontend-base-url - ::frontend-backend-base-url])) + ::import-file + ;::mail-host ::mail-user ::mail-pass ::mail-port ::mail-from + ])) (defn strip-secrets [env] (assoc env :mail-pass "*" diff --git a/backend/src/beherbergung/resolver/core.clj b/backend/src/beherbergung/resolver/core.clj index 8b2da8b..ab439de 100644 --- a/backend/src/beherbergung/resolver/core.clj +++ b/backend/src/beherbergung/resolver/core.clj @@ -7,12 +7,12 @@ ;; any login [beherbergung.resolver.root.login :refer [login]] ;; ngo login - [beherbergung.resolver.root.ngo.ngo-example :refer [ngo_example]] + [beherbergung.resolver.root.ngo.get-offers :refer [get_offers]] ;; admin passphrase [beherbergung.resolver.root.admin.export :refer [export]])) (def graphql* (executor {:query {:login #'login - :ngo_example #'ngo_example + :get_offers #'get_offers :export #'export} :mutation {}})) diff --git a/backend/src/beherbergung/resolver/root/ngo/get_offers.clj b/backend/src/beherbergung/resolver/root/ngo/get_offers.clj new file mode 100644 index 0000000..2edd238 --- /dev/null +++ b/backend/src/beherbergung/resolver/root/ngo/get_offers.clj @@ -0,0 +1,45 @@ +(ns beherbergung.resolver.root.ngo.get-offers + (:require [clojure.spec.alpha :as s] + [specialist-server.type :as t] + [beherbergung.auth.core :refer [auth+role->entity]] + [beherbergung.config.state :refer [env]] + [beherbergung.model.auth :as auth] + [beherbergung.model.ngo :as ngo] + [clojure.edn])) + +(defn JaNein->bool [JaNein] + ({"Ja" true "Nein" false} JaNein)) + +(def mapping {:accessible #(JaNein->bool (get % "Ist die Unterkunft rollstuhlgerecht?")) + :note "Nachricht"}) + +(defn unify + [offers] + (let [mapping->fn (fn [mapping] + (fn [dataset] (->> mapping + (map (fn [[k v]] + [k (cond (fn? v) + (v dataset) + :else + (get dataset v))])) + (into {}))))] + (map (mapping->fn mapping) offers))) + +(s/def ::accessible (s/nilable t/boolean)) +(s/def ::note (s/nilable t/string)) +(s/def ::offer (s/keys :opt-un [::accessible ::note])) + +(s/fdef get_offers + :args (s/tuple map? (s/keys :req-un [::auth/auth]) map? map?) + :ret (s/nilable (s/* ::offer))) + +(defn get_offers + "The offers that are visible for the ngo, belonging to the login" + [_node opt ctx _info] + (let [{:keys [_TODO]} (:db_ctx ctx) + [ngo:id] (auth+role->entity ctx (:auth opt) ::ngo/record)] + (when ngo:id + ;; TODO: take it from the db and filter it by visibility to the ngo + (unify (clojure.edn/read-string (slurp (:import-file env))))))) + +(s/def ::get_offers (t/resolver #'get_offers)) diff --git a/backend/src/beherbergung/resolver/root/ngo/ngo_example.clj b/backend/src/beherbergung/resolver/root/ngo/ngo_example.clj deleted file mode 100644 index 3a7ced5..0000000 --- a/backend/src/beherbergung/resolver/root/ngo/ngo_example.clj +++ /dev/null @@ -1,22 +0,0 @@ -(ns beherbergung.resolver.root.ngo.ngo-example - (:require [clojure.spec.alpha :as s] - [specialist-server.type :as t] - [beherbergung.auth.core :refer [auth+role->entity]] - [beherbergung.model.auth :as auth] - [beherbergung.model.ngo :as ngo])) - -(s/def ::my_result_type t/string) - -(s/fdef ngo_example - :args (s/tuple map? (s/keys :req-un [::auth/auth]) map? map?) - :ret (s/nilable ::my_result_type)) - -(defn ngo_example - "For an ngo login, we get a greeting" - [_node opt ctx _info] - (let [{:keys [_TODO]} (:db_ctx ctx) - [ngo:id] (auth+role->entity ctx (:auth opt) ::ngo/record)] - (when ngo:id - "hallo welt :)"))) - -(s/def ::ngo_example (t/resolver #'ngo_example)) diff --git a/backend/test/beherbergung/introspection_test.clj b/backend/test/beherbergung/introspection_test.clj index 6a31978..3f491dd 100644 --- a/backend/test/beherbergung/introspection_test.clj +++ b/backend/test/beherbergung/introspection_test.clj @@ -10,4 +10,4 @@ (get-in [:data :__schema :types])) (map :name) sort) - '("Auth" "Boolean" "Float" "ID" "Int" "Long" "QueryType" "String" "export" "login")))) + '("Auth" "Boolean" "Float" "ID" "Int" "Long" "QueryType" "String" "export" "get_offers" "login")))) diff --git a/backend/test/beherbergung/resolver/login.clj b/backend/test/beherbergung/resolver/login_test.clj similarity index 96% rename from backend/test/beherbergung/resolver/login.clj rename to backend/test/beherbergung/resolver/login_test.clj index 570ac5d..a2299df 100644 --- a/backend/test/beherbergung/resolver/login.clj +++ b/backend/test/beherbergung/resolver/login_test.clj @@ -1,4 +1,4 @@ -(ns beherbergung.resolver.login +(ns beherbergung.resolver.login-test (:require [clojure.test :refer [use-fixtures deftest is]] [mount.core :as mount] [beherbergung.resolver.core :refer [graphql]] diff --git a/backend/test/beherbergung/resolver/ngo/get_offers_test.clj b/backend/test/beherbergung/resolver/ngo/get_offers_test.clj new file mode 100644 index 0000000..3a2fd7c --- /dev/null +++ b/backend/test/beherbergung/resolver/ngo/get_offers_test.clj @@ -0,0 +1,26 @@ +(ns beherbergung.resolver.ngo.get-offers-test + (:require [clojure.test :refer [use-fixtures deftest is]] + [mount.core :as mount] + [beherbergung.resolver.core :refer [graphql]])) + +(def mail "praxis@max.mueller.de") +(def password "i!A;z\\\"'^G3Q)w])%83)") + +(defn get_offers [variables] + (let [response (graphql {:query "query x($auth: Auth) { get_offers(auth: $auth){ accessible note } }" + :variables variables})] + (get-in response [:data :get_offers]))) + + +(use-fixtures :once (fn [testcases] (mount/stop) (mount/start) (testcases) (mount/stop))) + +(deftest correct-login + (let [offers (get_offers {:auth {:mail mail :password password}})] + (is (= 110 (count offers))) ;; TODO: we need a test dataset that can be published (generated) + (is (= {:accessible true + :note "füg"} + (first offers))))) + +(deftest wrong-login + (let [offers (get_offers {:auth {:mail mail :password "wrong"}})] + (is (nil? offers))))