Browse Source

moving to compojure; api done

master
Christian Mueller 12 years ago
parent
commit
5a1626a2f4
  1. 2
      Makefile
  2. 21
      project.clj
  3. 19
      src/NoteHub/api.clj
  4. 137
      src/NoteHub/handler.clj
  5. 10
      src/NoteHub/server.clj
  6. 14
      src/NoteHub/settings.clj
  7. 20
      src/NoteHub/storage.clj
  8. 53
      test/NoteHub/test/api.clj
  9. 24
      test/NoteHub/test/handler.clj
  10. 7
      test/NoteHub/test/storage.clj

2
Makefile

@ -1,6 +1,6 @@
# starts the app in :dev mode # starts the app in :dev mode
run: run:
@DEVMODE=1 lein run @DEVMODE=1 lein ring server
server: server:
redis-server & redis-server &

21
project.clj

@ -1,10 +1,13 @@
(defproject NoteHub "2.0.0" (defproject NoteHub "2.0.0"
:description "A free and anonymous hosting for markdown pages." :description "A free and anonymous hosting for markdown pages."
:dependencies [[org.clojure/clojure "1.5.1"] :dependencies [[org.clojure/clojure "1.5.1"]
[hiccup "1.0.0"] [hiccup "1.0.0"]
[cheshire "5.3.1"] [cheshire "5.3.1"]
[ring/ring-core "1.1.0"] [ring/ring-core "1.1.0"]
[com.taoensso/carmine "2.4.4"] [com.taoensso/carmine "2.4.4"]
[noir "1.3.0-beta1"]] [compojure "1.1.6"]]
:jvm-opts ["-Dfile.encoding=utf-8"] :plugins [[lein-ring "0.8.10"]]
:main NoteHub.server) :ring {:handler notehub.handler/app}
:profiles {:dev {:dependencies [[javax.servlet/servlet-api "2.5"]
[ring-mock "0.1.5"]]}}
:jvm-opts ["-Dfile.encoding=utf-8"])

19
src/NoteHub/api.clj

@ -1,15 +1,15 @@
(ns NoteHub.api (ns notehub.api
(:import (:import
[java.util Calendar]) [java.util Calendar])
(:use (:use
[NoteHub.settings] [notehub.settings]
[ring.util.codec :only [url-encode]] [ring.util.codec :only [url-encode]]
[clojure.string :rename {replace sreplace} [clojure.string :rename {replace sreplace}
:only [replace blank? lower-case split-lines split]]) :only [replace blank? lower-case split-lines split]])
(:require (:require
[ring.util.codec] [ring.util.codec]
[hiccup.util :as util] [hiccup.util :as util]
[NoteHub.storage :as storage])) [notehub.storage :as storage]))
(def version "1.1") (def version "1.1")
@ -60,15 +60,6 @@
(str domain "/" (storage/create-short-url token {:year year :month month :day day :title title})) (str domain "/" (storage/create-short-url token {:year year :month month :day day :title title}))
(str domain (url year month day title)))))) (str domain (url year month day title))))))
(let [md5Instance (java.security.MessageDigest/getInstance "MD5")]
(defn get-signature
"Returns the MD5 hash for the concatenation of all passed parameters"
[& args]
(let [input (sreplace (apply str args) #"[\r\n]" "")]
(do (.reset md5Instance)
(.update md5Instance (.getBytes input))
(.toString (new java.math.BigInteger 1 (.digest md5Instance)) 16)))))
(defn get-note [noteID] (defn get-note [noteID]
(if (storage/note-exists? noteID) (if (storage/note-exists? noteID)
(let [note (storage/get-note noteID)] (let [note (storage/get-note noteID)]
@ -87,7 +78,7 @@
;(log "post-note: %s" {:pid pid :signature signature :password password :note note}) ;(log "post-note: %s" {:pid pid :signature signature :password password :note note})
(let [errors (filter identity (let [errors (filter identity
[(when-not (storage/valid-publisher? pid) "pid invalid") [(when-not (storage/valid-publisher? pid) "pid invalid")
(when-not (= signature (get-signature pid (storage/get-psk pid) note)) (when-not (= signature (storage/sign pid (storage/get-psk pid) note))
"signature invalid") "signature invalid")
(when (blank? note) "note is empty")])] (when (blank? note) "note is empty")])]
(if (empty? errors) (if (empty? errors)
@ -121,7 +112,7 @@
;(log "update-note: %s" {:pid pid :noteID noteID :signature signature :password password :note note}) ;(log "update-note: %s" {:pid pid :noteID noteID :signature signature :password password :note note})
(let [errors (filter identity (let [errors (filter identity
[(when-not (storage/valid-publisher? pid) "pid invalid") [(when-not (storage/valid-publisher? pid) "pid invalid")
(when-not (= signature (get-signature pid (storage/get-psk pid) noteID note password)) (when-not (= signature (storage/sign pid (storage/get-psk pid) noteID note password))
"signature invalid") "signature invalid")
(when (blank? note) "note is empty") (when (blank? note) "note is empty")
(when-not (storage/valid-password? noteID password) "password invalid")])] (when-not (storage/valid-password? noteID password) "password invalid")])]

137
src/NoteHub/views/pages.clj → src/NoteHub/handler.clj

@ -1,28 +1,24 @@
(ns NoteHub.views.pages (ns notehub.handler
(:require [hiccup.util :as util] (:use compojure.core
[NoteHub.api :as api] [notehub.settings]
[NoteHub.storage :as storage] [clojure.string :rename {replace sreplace}
[cheshire.core :refer :all]) :only [escape split replace blank? split-lines lower-case]]
(:use [clojure.core.incubator :only [-?>]]
[NoteHub.settings] [hiccup.form]
[clojure.string :rename {replace sreplace} [hiccup.core]
:only [escape split replace blank? split-lines lower-case]] [hiccup.element]
[clojure.core.incubator :only [-?>]] [hiccup.util :only [escape-html]]
[noir.util.crypt :only [encrypt]] [hiccup.page :only [include-js html5]])
[hiccup.form] (:require [compojure.handler :as handler]
[hiccup.core] [compojure.route :as route]
[hiccup.element] [hiccup.util :as util]
[hiccup.util :only [escape-html]] [notehub.api :as api]
[hiccup.page :only [include-js html5]] [notehub.storage :as storage]
[noir.response :only [redirect status content-type]] [cheshire.core :refer :all]))
[noir.core :only [defpage defpartial]]
[noir.statuses]))
(when-not (storage/valid-publisher? "NoteHub")
(storage/register-publisher "NoteHub"))
; Creates the main html layout ; Creates the main html layout
(defpartial layout (defn layout
[title & content] [title & content]
(html5 (html5
[:head [:head
@ -40,6 +36,32 @@
(if-not (get-setting :dev-mode) (include-js "/js/google-analytics.js"))] (if-not (get-setting :dev-mode) (include-js "/js/google-analytics.js"))]
[:body {:onload "onLoad()"} content])) [:body {:onload "onLoad()"} content]))
(defn md-node
"Returns an HTML element with a textarea inside
containing the markdown text (to keep all chars unescaped)"
([cls input] (md-node cls {} input))
([cls opts input]
[(keyword (str (name cls) ".markdown")) opts
[:textarea input]]))
#_ (
; ######## OLD CODE START
(ns NoteHub.views.pages
(:require )
(:use
[noir.response :only [redirect status content-type]]
[noir.core :only [defpage defpartial]]
[noir.statuses]
[noir.util.crypt :only [encrypt]]))
(when-not (storage/valid-publisher? "NoteHub")
(storage/register-publisher "NoteHub"))
(defn sanitize (defn sanitize
"Breakes all usages of <script> & <iframe>" "Breakes all usages of <script> & <iframe>"
[input] [input]
@ -80,13 +102,6 @@
(defn generate-session [] (defn generate-session []
(encrypt (str (rand-int Integer/MAX_VALUE)))) (encrypt (str (rand-int Integer/MAX_VALUE))))
(defn md-node
"Returns an HTML element with a textarea inside
containing the markdown text (to keep all chars unescaped)"
([cls input] (md-node cls {} input))
([cls opts input]
[(keyword (str (name cls) ".markdown")) opts
[:textarea input]]))
; Routes ; Routes
; ====== ; ======
@ -135,13 +150,6 @@
[:tr [:td (str (get-message %) ":")] [:td (% stats)]]) [:tr [:td (str (get-message %) ":")] [:td (% stats)]])
[:published :edited :publisher :views])]))) [:published :edited :publisher :views])])))
(defpage "/:short-url" {:keys [short-url]}
(when-let [params (storage/resolve-url short-url)]
(let [{:keys [year month day title]} params
rest-params (dissoc params :year :month :day :title)
core-url (api/url year month day title)
long-url (if (empty? rest-params) core-url (util/url core-url rest-params))]
(redirect long-url))))
(defpage "/:year/:month/:day/:title/edit" {:keys [year month day title]} (defpage "/:year/:month/:day/:title/edit" {:keys [year month day title]}
(let [noteID (api/build-key [year month day] title)] (let [noteID (api/build-key [year month day] title)]
@ -181,23 +189,48 @@
(response 403))) (response 403)))
(response 500)))) (response 500))))
; Here lives the API ; ###### END OLD CODE
)
(defn redirect [url]
{:status 302
:headers {"Location" (str url)}
:body ""})
(defroutes api-routes
(GET "/" [] (layout (get-message :api-title)
(md-node :article (slurp "API.md"))))
(GET "/note" [version noteID]
(generate-string (api/get-note noteID)))
(POST "/note" {params :params}
(generate-string
(api/post-note
(:note params)
(:pid params)
(:signature params)
{:params (dissoc params :version :note :pid :signature :password)
:password (:password params)})))
(PUT "/note" [version noteID note pid signature password]
(generate-string (api/update-note noteID note pid signature password))))
(defpage "/api" args (defroutes app-routes
(layout (get-message :api-title) (context "/api" [] api-routes)
(md-node :article (slurp "API.md")))) (GET "/" [] "Hello World")
(defpage [:get "/api/note"] {:keys [version noteID]} (GET "/:short-url" [short-url]
(generate-string (api/get-note noteID))) (when-let [params (storage/resolve-url short-url)]
(let [{:keys [year month day title]} params
rest-params (dissoc params :year :month :day :title)
core-url (api/url year month day title)
long-url (if (empty? rest-params) core-url (util/url core-url rest-params))]
(redirect long-url))))
(defpage [:post "/api/note"] {:keys [version note pid signature password] :as params} (route/resources "/resources")
(generate-string (route/not-found "Not Found"))
(api/post-note
note
pid
signature
{:params (dissoc params :version :note :pid :signature :password)
:password password})))
(defpage [:put "/api/note"] {:keys [version noteID note pid signature password]} (def app
(generate-string (api/update-note noteID note pid signature password))) (handler/site app-routes))

10
src/NoteHub/server.clj

@ -1,10 +0,0 @@
(ns NoteHub.server
(:require [noir.server :as server]))
(server/load-views "src/NoteHub/views/")
(defn -main [& m]
(let [mode (keyword (or (first m) :prod))
port (Integer. (get (System/getenv) "PORT" "8080"))]
(server/start port {:mode mode :ns 'NoteHub})))

14
src/NoteHub/settings.clj

@ -1,14 +1,14 @@
(ns NoteHub.settings (ns notehub.settings
(:refer-clojure :exclude [replace reverse]) (:refer-clojure :exclude [replace reverse])
(:use [clojure.string])) (:use [clojure.string]))
; Loads and parses any file with each line consisting a key and ; Loads and parses any file with each line consisting a key and
; a value separated by a "=", and returns a corresponding key-value map. ; a value separated by a "=", and returns a corresponding key-value map.
(defn- get-pairs-map [file] (defn- get-pairs-map [file]
(let [file-content (slurp file) (let [file-content (slurp file)
pairs (map #(map trim (split % #"=" 2)) pairs (map #(map trim (split % #"=" 2))
(remove blank? (split-lines file-content)))] (remove blank? (split-lines file-content)))]
(apply hash-map (apply hash-map
(mapcat #(list (keyword (first %)) (second %)) pairs)))) (mapcat #(list (keyword (first %)) (second %)) pairs))))
; Loads the setting file to a map ; Loads the setting file to a map
@ -24,7 +24,7 @@
(messages-map key)) (messages-map key))
(defn get-setting (defn get-setting
"Takes a settings key, a converter function and a default value, and returns a corresponding "Takes a settings key, a converter function and a default value, and returns a corresponding
setting value. The default value is returned back when no setting value was found. setting value. The default value is returned back when no setting value was found.
The converter function can be provided to convert the setting from string to a needed type. The converter function can be provided to convert the setting from string to a needed type.
This function is not applied to the specified default value! This function is not applied to the specified default value!
@ -33,10 +33,10 @@
(let [converter (first more) (let [converter (first more)
default (second more) default (second more)
value (settings-map key) value (settings-map key)
; Through this hack we can read security-critical settings from (previously ; Through this hack we can read security-critical settings from (previously
; set) shell variables without commiting their content to CVS ; set) shell variables without commiting their content to CVS
value (if value value value (if value value
(System/getenv (System/getenv
(upper-case (upper-case
(replace (name key) #"-" ""))))] (replace (name key) #"-" ""))))]
(if value (if value

20
src/NoteHub/storage.clj

@ -1,11 +1,19 @@
(ns NoteHub.storage (ns notehub.storage
(:use [NoteHub.settings] (:use [notehub.settings]
[clojure.string :only (blank?)] [clojure.string :only (blank? replace) :rename {replace sreplace}])
[noir.util.crypt :only [encrypt]])
(:require [taoensso.carmine :as car :refer (wcar)])) (:require [taoensso.carmine :as car :refer (wcar)]))
(def conn {:pool {} :spec {:uri (get-setting :db-url)}}) (def conn {:pool {} :spec {:uri (get-setting :db-url)}})
(let [md5Instance (java.security.MessageDigest/getInstance "MD5")]
(defn sign
"Returns the MD5 hash for the concatenation of all passed parameters"
[& args]
(let [input (sreplace (apply str args) #"[\r\n]" "")]
(do (.reset md5Instance)
(.update md5Instance (.getBytes input))
(.toString (new java.math.BigInteger 1 (.digest md5Instance)) 16)))))
(defmacro redis [cmd & body] (defmacro redis [cmd & body]
`(car/wcar conn `(car/wcar conn
(~(symbol "car" (name cmd)) (~(symbol "car" (name cmd))
@ -20,7 +28,7 @@
(defn register-publisher [pid] (defn register-publisher [pid]
"Returns nil if given PID exists or a PSK otherwise" "Returns nil if given PID exists or a PSK otherwise"
(when (not (valid-publisher? pid)) (when (not (valid-publisher? pid))
(let [psk (encrypt (str (rand-int Integer/MAX_VALUE) pid))] (let [psk (sign (str (rand-int Integer/MAX_VALUE) pid))]
(redis :hset :publisher-key pid psk) (redis :hset :publisher-key pid psk)
psk))) psk)))
@ -31,7 +39,7 @@
(redis :hget :publisher-key pid)) (redis :hget :publisher-key pid))
(defn create-session [] (defn create-session []
(let [token (encrypt (str (rand-int Integer/MAX_VALUE)))] (let [token (sign (str (rand-int Integer/MAX_VALUE)))]
(redis :sadd :sessions token) (redis :sadd :sessions token)
token)) token))

53
test/NoteHub/test/api.clj

@ -1,9 +1,9 @@
(ns NoteHub.test.api (ns notehub.test.api
(:require (:require
[cheshire.core :refer :all] [cheshire.core :refer :all]
[NoteHub.storage :as storage]) [notehub.storage :as storage])
(:use [NoteHub.api] (:use [notehub.api]
[noir.util.test] [notehub.handler]
[clojure.test])) [clojure.test]))
(def note "hello world!\nThis is a _test_ note!") (def note "hello world!\nThis is a _test_ note!")
@ -15,6 +15,15 @@
(defmacro isnt [arg] `(is (not ~arg))) (defmacro isnt [arg] `(is (not ~arg)))
(defn send-request
([resource] (send-request resource {}))
([resource params]
(let [[method url] (if (vector? resource) resource [:get resource])]
(app-routes {:request-method method :uri url :params params}))))
(defn has-status [input status]
(= status (:status input)))
(defn register-publisher-fixture [f] (defn register-publisher-fixture [f]
(def psk (storage/register-publisher pid)) (def psk (storage/register-publisher pid))
(f) (f)
@ -37,8 +46,8 @@
(isnt (storage/valid-publisher? pid2)))) (isnt (storage/valid-publisher? pid2))))
(testing "note publishing & retrieval" (testing "note publishing & retrieval"
(isnt (:success (:status (get-note "some note id")))) (isnt (:success (:status (get-note "some note id"))))
(is (= "note is empty" (:message (:status (post-note "" pid (get-signature pid psk "")))))) (is (= "note is empty" (:message (:status (post-note "" pid (storage/sign pid psk ""))))))
(let [post-response (post-note note pid (get-signature pid psk note)) (let [post-response (post-note note pid (storage/sign pid psk note))
get-response (get-note (:noteID post-response))] get-response (get-note (:noteID post-response))]
(is (:success (:status post-response))) (is (:success (:status post-response)))
(is (:success (:status get-response))) (is (:success (:status get-response)))
@ -48,8 +57,10 @@
(is (storage/note-exists? (:noteID post-response))) (is (storage/note-exists? (:noteID post-response)))
(let [su (last (clojure.string/split (:shortURL get-response) #"/"))] (let [su (last (clojure.string/split (:shortURL get-response) #"/"))]
(is (= su (storage/create-short-url (:noteID post-response) (storage/resolve-url su))))) (is (= su (storage/create-short-url (:noteID post-response) (storage/resolve-url su)))))
(let [resp (send-request (let [_ (println "DEBUG I" (clojure.string/replace (:shortURL get-response) domain ""))
resp (send-request
(clojure.string/replace (:shortURL get-response) domain "")) (clojure.string/replace (:shortURL get-response) domain ""))
_ (println "DEBUG II" ((:headers resp) "Location"))
resp (send-request ((:headers resp) "Location"))] resp (send-request ((:headers resp) "Location"))]
(is (substring? "hello world"(:body resp)))) (is (substring? "hello world"(:body resp))))
(is (= (:publisher get-response) pid)) (is (= (:publisher get-response) pid))
@ -58,38 +69,38 @@
(isnt (get-in get-response [:statistics :edited])) (isnt (get-in get-response [:statistics :edited]))
(is (= "3" (get-in (get-note (:noteID post-response)) [:statistics :views]))))) (is (= "3" (get-in (get-note (:noteID post-response)) [:statistics :views])))))
(testing "creation with wrong signature" (testing "creation with wrong signature"
(let [response (post-note note pid (get-signature pid2 psk note))] (let [response (post-note note pid (storage/sign pid2 psk note))]
(isnt (:success (:status response))) (isnt (:success (:status response)))
(is (= "signature invalid" (:message (:status response))))) (is (= "signature invalid" (:message (:status response)))))
(let [response (post-note note pid (get-signature pid2 psk "any note"))] (let [response (post-note note pid (storage/sign pid2 psk "any note"))]
(isnt (:success (:status response))) (isnt (:success (:status response)))
(is (= "signature invalid" (:message (:status response))))) (is (= "signature invalid" (:message (:status response)))))
(isnt (:success (:status (post-note note pid (get-signature pid "random_psk" note))))) (isnt (:success (:status (post-note note pid (storage/sign pid "random_psk" note)))))
(is (:success (:status (post-note note pid (get-signature pid psk note))))) (is (:success (:status (post-note note pid (storage/sign pid psk note)))))
(let [randomPID "randomPID" (let [randomPID "randomPID"
psk2 (storage/register-publisher randomPID) psk2 (storage/register-publisher randomPID)
_ (storage/revoke-publisher randomPID) _ (storage/revoke-publisher randomPID)
response (post-note note randomPID (get-signature randomPID psk2 note))] response (post-note note randomPID (storage/sign randomPID psk2 note))]
(isnt (:success (:status response))) (isnt (:success (:status response)))
(is (= (:message (:status response)) "pid invalid")))) (is (= (:message (:status response)) "pid invalid"))))
(testing "note update" (testing "note update"
(let [post-response (post-note note pid (get-signature pid psk note) {:password "passwd"}) (let [post-response (post-note note pid (storage/sign pid psk note) {:password "passwd"})
note-id (:noteID post-response) note-id (:noteID post-response)
new-note "a new note!"] new-note "a new note!"]
(is (:success (:status post-response))) (is (:success (:status post-response)))
(is (:success (:status (get-note note-id)))) (is (:success (:status (get-note note-id))))
(is (= note (:note (get-note note-id)))) (is (= note (:note (get-note note-id))))
(let [update-response (update-note note-id new-note pid (get-signature pid psk new-note) "passwd")] (let [update-response (update-note note-id new-note pid (storage/sign pid psk new-note) "passwd")]
(isnt (:success (:status update-response))) (isnt (:success (:status update-response)))
(is (= "signature invalid" (:message (:status update-response))))) (is (= "signature invalid" (:message (:status update-response)))))
(is (= note (:note (get-note note-id)))) (is (= note (:note (get-note note-id))))
(let [update-response (update-note note-id new-note pid (let [update-response (update-note note-id new-note pid
(get-signature pid psk note-id new-note "passwd") "passwd")] (storage/sign pid psk note-id new-note "passwd") "passwd")]
(is (= { :success true } (:status update-response))) (is (= { :success true } (:status update-response)))
(isnt (= nil (get-in (get-note note-id) [:statistics :edited]))) (isnt (= nil (get-in (get-note note-id) [:statistics :edited])))
(is (= new-note (:note (get-note note-id))))) (is (= new-note (:note (get-note note-id)))))
(let [update-response (update-note note-id "aaa" pid (let [update-response (update-note note-id "aaa" pid
(get-signature pid psk note-id "aaa" "pass") "pass")] (storage/sign pid psk note-id "aaa" "pass") "pass")]
(isnt (:success (:status update-response))) (isnt (:success (:status update-response)))
(is (= "password invalid" (:message (:status update-response))))) (is (= "password invalid" (:message (:status update-response)))))
(is (= new-note (:note (get-note note-id)))) (is (= new-note (:note (get-note note-id))))
@ -100,7 +111,7 @@
(let [response (send-request [:post "/api/note"] (let [response (send-request [:post "/api/note"]
{:note note {:note note
:pid pid :pid pid
:signature (get-signature pid psk note) :signature (storage/sign pid psk note)
:version "1.0"}) :version "1.0"})
body (parse-string (:body response)) body (parse-string (:body response))
noteID (body "noteID")] noteID (body "noteID")]
@ -118,7 +129,7 @@
(let [response (send-request [:post "/api/note"] (let [response (send-request [:post "/api/note"]
{:note note {:note note
:pid pid :pid pid
:signature (get-signature pid psk note) :signature (storage/sign pid psk note)
:version "1.0" :version "1.0"
:theme "dark" :theme "dark"
:text-font "Helvetica"}) :text-font "Helvetica"})
@ -140,7 +151,7 @@
(let [response (send-request [:post "/api/note"] (let [response (send-request [:post "/api/note"]
{:note note {:note note
:pid pid :pid pid
:signature (get-signature pid psk note) :signature (storage/sign pid psk note)
:version "1.0" :version "1.0"
:password "qwerty"}) :password "qwerty"})
body (parse-string (:body response)) body (parse-string (:body response))
@ -156,7 +167,7 @@
{:noteID noteID {:noteID noteID
:note "WRONG pass" :note "WRONG pass"
:pid pid :pid pid
:signature (get-signature pid psk noteID "WRONG pass" "qwerty1") :signature (storage/sign pid psk noteID "WRONG pass" "qwerty1")
:password "qwerty1" :password "qwerty1"
:version "1.0"}) :version "1.0"})
body (parse-string (:body response))] body (parse-string (:body response))]
@ -172,7 +183,7 @@
{:noteID noteID {:noteID noteID
:note "UPDATED CONTENT" :note "UPDATED CONTENT"
:pid pid :pid pid
:signature (get-signature pid psk noteID "UPDATED CONTENT" "qwerty") :signature (storage/sign pid psk noteID "UPDATED CONTENT" "qwerty")
:password "qwerty" :password "qwerty"
:version "1.0"}))) ["status" "success"])) :version "1.0"}))) ["status" "success"]))
(isnt (= nil (((parse-string (isnt (= nil (((parse-string

24
test/NoteHub/test/views/pages.clj → test/NoteHub/test/handler.clj

@ -1,4 +1,11 @@
(ns NoteHub.test.views.pages (ns notehub.test.handler
(:use clojure.test
ring.mock.request
notehub.handler))
#_(
(ns NoteHub.test.views.pages
(:use [NoteHub.views.pages] (:use [NoteHub.views.pages]
[NoteHub.api :only [build-key get-signature get-date url]] [NoteHub.api :only [build-key get-signature get-date url]]
[noir.util.test] [noir.util.test]
@ -112,7 +119,22 @@
(is (has-status (send-request [:post "/post-note"]) 400))) (is (has-status (send-request [:post "/post-note"]) 400)))
(testing "valid accesses" (testing "valid accesses"
;(is (has-status (send-request "/new") 200) "accessing /new") ;(is (has-status (send-request "/new") 200) "accessing /new")
(is (has-status (send-request "/api") 200) "accessing API")
(is (has-status (send-request (url 2012 6 3 "some-title")) 200) "accessing test note") (is (has-status (send-request (url 2012 6 3 "some-title")) 200) "accessing test note")
(is (has-status (send-request (url 2012 6 3 "some-title" "export")) 200) "accessing test note's export") (is (has-status (send-request (url 2012 6 3 "some-title" "export")) 200) "accessing test note's export")
(is (has-status (send-request (url 2012 6 3 "some-title" "stats")) 200) "accessing test note's stats") (is (has-status (send-request (url 2012 6 3 "some-title" "stats")) 200) "accessing test note's stats")
(is (has-status (send-request "/") 200) "accessing landing page")))) (is (has-status (send-request "/") 200) "accessing landing page"))))
)
(deftest test-app
(testing "main route"
(let [response (app (request :get "/"))]
(is (= (:status response) 200))
(is (= (:body response) "Hello World"))))
(testing "not-found route"
(let [response (app (request :get "/invalid"))]
(is (= (:status response) 404)))))

7
test/NoteHub/test/storage.clj

@ -1,7 +1,6 @@
(ns NoteHub.test.storage (ns notehub.test.storage
(:use [NoteHub.storage] (:use [notehub.storage]
[NoteHub.api :only [build-key]] [notehub.api :only [build-key]]
[NoteHub.views.pages]
[clojure.test]) [clojure.test])
(:require [taoensso.carmine :as car :refer (wcar)])) (:require [taoensso.carmine :as car :refer (wcar)]))

Loading…
Cancel
Save