I want to update a session key on /callback upon logging in. Here's the handler:
(defn callback [{session :session :as request}]
(let [id (:id (get-current-users-profile))
updated-session (assoc session :identity id)]
{:status 200
:headers {"Content-Type" "text/html"}
:body (loading-page)
:session updated-session}))
As long as the session key-value pair is present in the response map, I get a 500 "Response map is nil" response.
Is there something I'm doing wrongly here?
By the way, I can still update the session map (with no errors) on my /logout route by doing the following:
(defn logout [{session :session}]
(-> (resp/redirect "/")
(assoc :session {})))
And here's what calls both callback and logout:
(defroutes main-routes
(GET "/" [] index)
(GET "/login" [] login)
(GET "/callback" [] callback)
(GET "/logout" [] logout))
I'm trying to use the ring.mock.requests library to test an http service. I have this bit of code
(auth-routes
(->
(mock/request :post "/auth/user")
(mock/body {:username "user" :password "pass"})
(mock/content-type "application/json")))
The inner part with the thread-first macro seems to work correctly, but it fails when I try to make the mock request to auth-routes
And this is my route:
(def auth-routes
(context "/auth" []
:tags ["Authentication"]
(POST "/user" []
:return s/Uuid
:body [request m/User]
:summary "Create new user"
(ok (auth/create-user request)))) ...)
This is my schema:
(def User {:username s/Str
:password s/Str})
The exception I'm seeing is
clojure.lang.ExceptionInfo
Request validation failed
{:error (not (map? nil)), :type :compojure.api.exception/request-validation}
It looks like my route is getting nil as the body, and I expect {:username "user" :password "pass"} to be there.
What am I doing wrong and how do I pass a body to this route?
I think you should serialize your data as a json string in your test. Using cheshire:
(cheshire.core/generate-string {:username "user" :password "pass"})
Take a look here or here.
I have created a login page login.cljs and handler.clj.here is my code
login.cljs:-
(defn handler [response]
(let[status (aget (clj->js response) "status")
msg (str (aget (clj->js response) "greeting"))]
(if (= status 200)
(home/home-root)
(js/alert "Invalid username or password"))
))
(defn handle-submit [e app owner]
(let [[user user-node] (value-from-node owner "username")
[pass pass-node] (value-from-node owner "password")]
(POST "/hello"
{:params {:username user :password pass}
:handler handler
:error-handler error-handler
:format :json
:response-format :json})
))
(defn login-view [app owner]
(reify
om/IRender(render [this]
(dom/div nil
(dom/h1 nil "Login")
(dom/input #js {:type "text" :placeholder "Your Name" :ref "username"})
(dom/input #js {:type "password" :placeholder "Your Password" :ref "password"})
(dom/button
#js { :onClick (fn [event] (handle-submit event app owner))}
"submit")
))))
(defn say-hello []
(om/root
{} login-view (.getElementById js/document "content")))
home.cljs:-
(defn home-view [app owner]
(reify
om/IRender
(render [this]
(dom/div nil "Welcome"
))))
(defn home-root []
(om/root
{}
home-view
(.getElementById js/document "content"))
handler.clj:-
(defn login-check! [request]
(let [user (get-in request [:params :username])
pass (get-in request [:params :password])]
(cond
(and(= user "admin")(= pass "admin")) (response/response {:greeting user
:status 200})
:else (response/response {:greeting "Invalid username or password"
:status 403}))
))
(defroutes app-routes
(GET "/" [] (response/resource-response "index.html" {:root "public"}))
(route/resources "/")
(POST "/hello" request (login-check! request))
(GET "/home" request (response/response {:body "home"}))
(route/not-found "Not Found"))
I need to load home page view when its a valid login.
here i have called another cljs method 'home/home-root' but its not working.
Here i got one solution..I don't know how much its correct but its working good
I have created a new defn page using reagent as follows:-
(defn page [page-component]
(reagent/render-component [page-component]
(.getElementById js/document "content")))
and called this function from login.cljs handler method:
(defn handler [response]
(page home-root))
now the page method will be called and home-root cljs will be passed to it.
I am creating a toy Pedestal service intended to have the following resources:
/
/movies
/movies/today
/movies/:iso-date where :iso-date matches ####-##-##
The constraint for the last route is defined with the following snippet:
^:constraints {:iso-date #"\d{4}-\d{2}-\d{2}"}
Whenever the route containing this constraint is present in the route table I am unable to GET its sibling route /movies/today; instead I am getting a "Not Found" response instead. When the constraint-having route is removed, however, a GET of /movies/today succeeds.
The Pedestal routes I have defined using terse format look like so:
(defroutes routes
[[["/" {:get root-page}
["/movies" ^:interceptors [fetch-movies]
{:get movies-page}
["/today" {:get movies-for-today-page}]
["/:iso-date" ^:constraints {:iso-date #"\d{4}-\d{2}-\d{2}"}
{:get movies-for-date-page}]]]]])
Have I constructed this route table correctly in order to achieve the routing behaviour that I want?
NB: Printing the compiled routes gives me the result that I would expect in that all of the routes are present the generated :path-re regexes match as expected at the REPL:
({:path-parts [""],
:path-params [],
:interceptors
[{:name :foobar.service/root-page,
:enter
#object[io.pedestal.interceptor.helpers$before$fn__7359 0x14501070 "io.pedestal.interceptor.helpers$before$fn__7359#14501070"],
:leave nil,
:error nil}],
:path "/",
:method :get,
:path-re #"/\Q\E",
:route-name :foobar.service/root-page}
{:path-parts ["" "movies"],
:path-params [],
:interceptors
[{:name :foobar.service/fetch-movies,
:enter
#object[io.pedestal.interceptor.helpers$on_request$fn__7401 0x2aa85cc4 "io.pedestal.interceptor.helpers$on_request$fn__7401#2aa85cc4"],
:leave nil,
:error nil}
{:name :foobar.service/movies-page,
:enter
#object[io.pedestal.interceptor.helpers$before$fn__7359 0x30ffc3c0 "io.pedestal.interceptor.helpers$before$fn__7359#30ffc3c0"],
:leave nil,
:error nil}],
:path "/movies",
:method :get,
:path-re #"/\Qmovies\E",
:route-name :foobar.service/movies-page}
{:path-parts ["" "movies" "today"],
:path-params [],
:interceptors
[{:name :foobar.service/fetch-movies,
:enter
#object[io.pedestal.interceptor.helpers$on_request$fn__7401 0x2aa85cc4 "io.pedestal.interceptor.helpers$on_request$fn__7401#2aa85cc4"],
:leave nil,
:error nil}
{:name :foobar.service/movies-for-today-page,
:enter
#object[io.pedestal.interceptor.helpers$before$fn__7359 0x3726fc3b "io.pedestal.interceptor.helpers$before$fn__7359#3726fc3b"],
:leave nil,
:error nil}],
:path "/movies/today",
:method :get,
:path-re #"/\Qmovies\E/\Qtoday\E",
:route-name :foobar.service/movies-for-today-page}
{:path-parts ["" "movies" :iso-date],
:path-params [:iso-date],
:interceptors
[{:name :foobar.service/fetch-movies,
:enter
#object[io.pedestal.interceptor.helpers$on_request$fn__7401 0x2aa85cc4 "io.pedestal.interceptor.helpers$on_request$fn__7401#2aa85cc4"],
:leave nil,
:error nil}
{:name :foobar.service/movies-for-date-page,
:enter
#object[io.pedestal.interceptor.helpers$before$fn__7359 0x93fb20b "io.pedestal.interceptor.helpers$before$fn__7359#93fb20b"],
:leave nil,
:error nil}],
:path "/movies/:iso-date",
:path-constraints {:iso-date "(\\d{4}-\\d{2}-\\d{2})"},
:query-constraints {},
:method :get,
:path-re #"/\Qmovies\E/(\d{4}-\d{2}-\d{2})",
:route-name :foobar.service/movies-for-date-page})
I solved this problem in pedestal version 0.4.1-SNAPSHOT.
(io.pedestal.http.route/router my-routes :linear-search)
Use :linear-search, instead of :prefix-tree.
My code:
(defn json-response [data & [status]]
{:status (or status 200)
:headers {"Content-Type" "application/json"}
:body (json/generate-string data)})
(defroutes checkin-app-handler
(GET "/:code" [code & more] (json-response {"code" code "params" more})))
When I load the file to the repl and run this command, the params seems to be blank:
$ (checkin-app-handler {:server-port 8080 :server-name "127.0.0.1" :remote-addr "127.0.0.1" :uri "/123" :query-string "foo=1&bar=2" :scheme :http :headers {} :request-method :get})
> {:status 200, :headers {"Content-Type" "application/json"}, :body "{\"code\":\"123\",\"params\":{}}"}
What am I doing wrong? I need to get at the query-string, but the params map is always empty..
In order to get the query string parsed into the params map, you need to use the params middleware:
(ns n
(:require [ring.middleware.params :as rmp]))
(defroutes checkin-app-routes
(GET "" [] ...))
(def checkin-app-handler
(-> #'checkin-app-routes
rmp/wrap-params
; .. other middlewares
))
Note, that the usage of the var (#'checkin-app-routes) is not strictly necessary, but it makes the routes closure, wrapped inside the middlewares, pick up the changes, when you redefine the routes.
IOW you can also write
(def checkin-app-handler
(-> checkin-app-routes
rmp/wrap-params
; .. other middlewares
))
but then, you need to redefine the handler too, when interactively redefining the routes.