spec-based form validation

integration-tests
Josha von Gizycki 7 years ago
parent 254ac47edc
commit d67290b4af

@ -1,4 +1,5 @@
@ci-color: #ccc;
@error-color: #e00;
@accent-color: #efefef;
@border-stack: 1px solid @ci-color;
@text-padding-v: .2rem;
@ -32,7 +33,8 @@ a:active {
"nav main sidebar"
"footer footer footer";
margin: auto;
max-width: 900px;
min-width: 900px;
width: 80%;
border-top: ;
nav {
@ -106,11 +108,33 @@ form {
grid-column: 2;
}
.flash--error {
.flash;
border-color: @error-color;
.flash__heading--error {
margin: 0;
background-color: @error-color;
color: white;
margin-top: -.7rem;
margin-left: -.7rem;
margin-right: -.7rem;
}
}
.flash {
grid-column: 1/3;
grid-column: 1 e("/") 3;
.thin-border;
border-left-width: @accent-border-width;
padding: .7rem;
.flash__field {
font-style: italic;
}
.flash__pred {
font-family: monospace;
}
}
}

@ -14,8 +14,7 @@
(hashers/check pw hash))]
(if pwmatch
(-> (redirect "/")
(assoc-in [:session :ident] uname)
(assoc-in [:session :unode] unode))
(assoc-in [:session :ident] uname))
(-> (redirect "/login")
(assoc :flash :invalid-credentials)))))

@ -4,6 +4,7 @@
[compojure.route :as route]
[ring.middleware.defaults :refer [wrap-defaults site-defaults]]
[ring.util.response :as rur]
[ring.middleware.session.cookie :as session-cookie]
[wanijo.auth.routes :refer [auth-routes]]
[wanijo.home.routes :refer [home-routes]]
[wanijo.schema.routes :refer [schema-routes]]))
@ -23,4 +24,6 @@
(def app
(-> app-routes
(wrap-defaults site-defaults)))
(wrap-defaults (assoc-in site-defaults
[:session :store]
(session-cookie/cookie-store {:key "1234567890123456"})))))

@ -1,5 +1,9 @@
(ns wanijo.schema.routes
(:require [compojure.core :refer [defroutes GET]]
(:require [compojure.core :refer [defroutes GET POST]]
[ring.util.anti-forgery :refer [anti-forgery-field]]
[ring.util.response :as resp]
[hiccup.form :as hform]
[clojure.spec.alpha :as spec]
[wanijo.domain.schema :as domain-schemas]
[wanijo.view :as view]))
@ -10,7 +14,8 @@
(view/layout!
:session session
:content
[[:table
[[:h1 "Ali jaki ijo"]
[:table
[:thead
[:tr
[:th "Nimi"]
@ -19,7 +24,29 @@
(for [schema schemas]
[:tr
[:td (:name schema)]
[:td (:created_at schema)]])]]])))
[:td (:created_at schema)]])]]
[:h1 "Pali sin e jaki ijo"]
(hform/form-to
[:post "/schema/new"]
(view/spec-to-errmsg ::new-schema req)
(hform/label "name" "Nimi")
(hform/text-field {:required "required"}
"schema-name"
(get-in req [:params :schema-name]))
(hform/submit-button "Kama")
(anti-forgery-field))])))
(spec/def ::schema-name
(spec/and some? string? not-empty))
(spec/def ::new-schema
(spec/keys :req-un [::schema-name]))
(defn- new! [req]
(if (spec/valid? ::new-schema (:params req))
(resp/redirect "/schema")
(overview! req)))
(defroutes schema-routes
(GET "/schema" [] overview!))
(GET "/schema" [] overview!)
(POST "/schema/new" [] new!))

@ -1,6 +1,7 @@
(ns wanijo.view
(:require [hiccup.page :refer [html5
include-css]]))
include-css]]
[clojure.spec.alpha :as spec]))
(defn btnlink
([target caption]
@ -34,10 +35,28 @@
(str "O, " ident)])]
(when authed?
[:section.header-content
(btnlink "/schema" "Jaki Ijo" "header-content__link")
(btnlink "/schema" "Jaki ijo" "header-content__link")
(btnlink "/logout" "Lape" "header-content__link")])]
[:nav (when authed? "nav")]
(vec (concat [:main] content))
[:aside (when authed? "aside")]
[:footer
[:small "Ilo pali e ijo"]]]])))
(defn flash-error [content]
[:section.flash--error
[:h2.flash__heading--error "Pakala"]
content])
(defn spec-to-errmsg [spec-key req]
(when-let [spec-data (and (not-empty (:params req))
(spec/explain-data spec-key (:params req)))]
(flash-error
(->> (:clojure.spec.alpha/problems spec-data)
(map
(fn [prob]
[:p
"Field \""
[:span.flash__field (first (:path prob))]
"\" must comply to "
[:span.flash__pred (:pred prob)]]))))))

Loading…
Cancel
Save