Browse Source

storage layer made more BL independent

master
Christian Mueller 12 years ago
parent
commit
dfb3a1c934
  1. 66
      src/NoteHub/storage.clj
  2. 21
      src/NoteHub/views/pages.clj
  3. 34
      test/NoteHub/test/storage.clj
  4. 23
      test/NoteHub/test/views/pages.clj

66
src/NoteHub/storage.clj

@ -18,21 +18,13 @@
(def sessions "sessions") (def sessions "sessions")
(def short-url "short-url") (def short-url "short-url")
; Concatenates all fields to a string
(defn build-key
"Returns a storage-key for the given note coordinates"
[[year month day] title]
(print-str year month day title))
(defn create-session (defn create-session
"Creates a random session token"
[] []
(let [token (encrypt (str (rand-int Integer/MAX_VALUE)))] (let [token (encrypt (str (rand-int Integer/MAX_VALUE)))]
(do (redis/sadd db sessions token) (do (redis/sadd db sessions token)
token))) token)))
(defn invalidate-session (defn invalidate-session
"Invalidates given session"
[token] [token]
; Jedis is buggy & returns an NPE for token == nil ; Jedis is buggy & returns an NPE for token == nil
(when token (when token
@ -41,49 +33,43 @@
was-valid)))) was-valid))))
(defn update-note (defn update-note
"Updates a note with the given store key if the specified password is correct" [noteID text passwd]
[key text passwd] (let [stored-password (redis/hget db password noteID)]
(let [stored-password (redis/hget db password key)]
(when (and stored-password (= passwd stored-password)) (when (and stored-password (= passwd stored-password))
(redis/hset db note key text)))) (redis/hset db note noteID text))))
(defn set-note (defn add-note
"Creates a note with the given title and text in the given date namespace" ([noteID text] (add-note noteID text nil))
([date title text] (set-note date title text nil)) ([noteID text passwd]
([date title text passwd] (do
(let [key (build-key date title)] (redis/hset db note noteID text)
(do (when (not (blank? passwd))
(redis/hset db note key text) (redis/hset db password noteID passwd)))))
(when (not (blank? passwd))
(redis/hset db password key passwd))))))
(defn get-note (defn get-note
"Gets the note from the given date namespaces for the specified title" [noteID]
[date title] (let [text (redis/hget db note noteID)]
(let [key (build-key date title)
text (redis/hget db note key)]
(when text (when text
(do (do
(redis/hincrby db views key 1) (redis/hincrby db views noteID 1)
text)))) text))))
(defn get-note-views (defn get-note-views
"Returns the number of views for the specified date and note title" "Returns the number of views for the specified noteID"
[date title] [noteID]
(redis/hget db views (build-key date title))) (redis/hget db views noteID))
(defn note-exists? (defn note-exists?
"Returns true if the note with the specified title and date exists" "Returns true if the note with the specified noteID"
[date title] [noteID]
(redis/hexists db note (build-key date title))) (redis/hexists db note noteID))
(defn delete-note (defn delete-note
"Deletes the note with the specified coordinates" "Deletes the note with the specified coordinates"
[date title] [noteID]
(let [key (build-key date title)] (doseq [kw [password views note]]
(doseq [kw [password views note]] ; TODO: delete short url by looking for the title
; TODO: delete short url by looking for the title (redis/hdel db kw noteID)))
(redis/hdel db kw key))))
(defn short-url-exists? (defn short-url-exists?
"Checks whether the provided short url is taken (for testing only)" "Checks whether the provided short url is taken (for testing only)"
@ -99,10 +85,10 @@
(defn delete-short-url (defn delete-short-url
"Deletes a short url (for testing only)" "Deletes a short url (for testing only)"
[key] [noteID]
(let [value (redis/hget db short-url key)] (let [value (redis/hget db short-url noteID)]
(do (do
(redis/hdel db short-url key) (redis/hdel db short-url noteID)
(redis/hdel db short-url value)))) (redis/hdel db short-url value))))
(defn create-short-url (defn create-short-url

21
src/NoteHub/views/pages.clj

@ -16,6 +16,12 @@
(:import (:import
[java.util Calendar])) [java.util Calendar]))
; Concatenates all fields to a string
(defn build-key
"Returns a storage-key for the given note coordinates"
[[year month day] title]
(print-str year month day title))
(defn get-hash (defn get-hash
"A simple hash-function, which computes a hash from the text field "A simple hash-function, which computes a hash from the text field
content and given session number. It is intended to be used as a spam content and given session number. It is intended to be used as a spam
@ -103,8 +109,9 @@
; Update Note Page ; Update Note Page
(defpage "/:year/:month/:day/:title/edit" {:keys [year month day title]} (defpage "/:year/:month/:day/:title/edit" {:keys [year month day title]}
(input-form "/update-note" :update (input-form "/update-note" :update
(html (hidden-field :key (build-key [year month day] title))) (let [noteID (build-key [year month day] title)]
(get-note [year month day] title) :enter-passwd)) (html (hidden-field :key noteID))
(get-note noteID) :enter-passwd)))
; New Note Page ; New Note Page
(defpage "/new" {} (defpage "/new" {}
@ -118,16 +125,16 @@
(wrap (wrap
(create-short-url params) (create-short-url params)
(select-keys params [:title :theme :header-font :text-font]) (select-keys params [:title :theme :header-font :text-font])
(get-note [year month day] title))) (get-note (build-key [year month day] title))))
; Provides Markdown of the specified note ; Provides Markdown of the specified note
(defpage "/:year/:month/:day/:title/export" {:keys [year month day title]} (defpage "/:year/:month/:day/:title/export" {:keys [year month day title]}
(when-let [md-text (get-note [year month day] title)] (when-let [md-text (get-note (build-key [year month day] title))]
(content-type "text/plain; charset=utf-8" md-text))) (content-type "text/plain; charset=utf-8" md-text)))
; Provides the number of views of the specified note ; Provides the number of views of the specified note
(defpage "/:year/:month/:day/:title/stats" {:keys [year month day title]} (defpage "/:year/:month/:day/:title/stats" {:keys [year month day title]}
(when-let [views (get-note-views [year month day] title)] (when-let [views (get-note-views (build-key [year month day] title))]
(layout (get-message :statistics) (layout (get-message :statistics)
[:table#stats.helvetica.central-element [:table#stats.helvetica.central-element
[:tr [:tr
@ -167,11 +174,11 @@
; TODO: replace to ccs/take when it gets fixed ; TODO: replace to ccs/take when it gets fixed
proposed-title (apply str (take max-length title-uncut)) proposed-title (apply str (take max-length title-uncut))
date [year month day] date [year month day]
title (first (drop-while #(note-exists? date %) title (first (drop-while #(note-exists? (build-key date %))
(cons proposed-title (cons proposed-title
(map #(str proposed-title "-" (+ 2 %)) (range)))))] (map #(str proposed-title "-" (+ 2 %)) (range)))))]
(do (do
(set-note date title draft password) (add-note (build-key date title) draft password)
(redirect (url year month day title)))) (redirect (url year month day title))))
(response 400)))) (response 400))))

34
test/NoteHub/test/storage.clj

@ -1,5 +1,7 @@
(ns NoteHub.test.storage (ns NoteHub.test.storage
(:use [NoteHub.storage] [clojure.test])) (:use [NoteHub.storage]
[NoteHub.views.pages]
[clojure.test]))
(def date [2012 06 03]) (def date [2012 06 03])
(def test-title "Some title.") (def test-title "Some title.")
@ -25,29 +27,29 @@
(short-url-exists? url)))))) (short-url-exists? url))))))
(testing "of correct note creation" (testing "of correct note creation"
(is (= (do (is (= (do
(set-note date test-title test-note) (add-note (build-key date test-title) test-note)
(get-note date test-title)) (get-note (build-key date test-title)))
test-note)) test-note))
(is (= "1" (get-note-views date test-title))) (is (= "1" (get-note-views (build-key date test-title))))
(is (= (do (is (= (do
(get-note date test-title) (get-note (build-key date test-title))
(get-note-views date test-title)) (get-note-views (build-key date test-title)))
"2"))) "2")))
(testing "of note update" (testing "of note update"
(is (= (do (is (= (do
(set-note date test-title test-note "12345qwert") (add-note (build-key date test-title) test-note "12345qwert")
(get-note date test-title)) (get-note (build-key date test-title)))
test-note)) test-note))
(is (= (do (is (= (do
(update-note (build-key date test-title) "update" "12345qwert") (update-note (build-key date test-title) "update" "12345qwert")
(get-note date test-title)) (get-note (build-key date test-title)))
"update")) "update"))
(is (= (do (is (= (do
(update-note (build-key date test-title) "not authorized" "44444") (update-note (build-key date test-title) "not authorized" "44444")
(get-note date test-title)) (get-note (build-key date test-title)))
"update"))) "update")))
(testing "of the note access" (testing "of the note access"
(is (not= (get-note date test-title) "any text"))) (is (not= (get-note (build-key date test-title)) "any text")))
(testing "session management" (testing "session management"
(let [s1 (create-session) (let [s1 (create-session)
s2 (create-session) s2 (create-session)
@ -58,9 +60,9 @@
(is (not (invalidate-session "wrongtoken"))) (is (not (invalidate-session "wrongtoken")))
(is (invalidate-session s3)))) (is (invalidate-session s3))))
(testing "of note existence" (testing "of note existence"
(is (note-exists? date test-title)) (is (note-exists? (build-key date test-title)))
(is (not (do (is (not (do
(delete-note date test-title) (delete-note (build-key date test-title))
(note-exists? date test-title)))) (note-exists? (build-key date test-title)))))
(is (not (note-exists? [2013 06 03] test-title))) (is (not (note-exists? (build-key [2013 06 03] test-title))))
(is (not (note-exists? date "some title")))))) (is (not (note-exists? (build-key date "some title")))))))

23
test/NoteHub/test/views/pages.clj

@ -6,16 +6,15 @@
[clojure.test])) [clojure.test]))
(defn substring? [a b] (defn substring? [a b]
(not (= nil (not (= nil (re-matches (re-pattern (str "(?s).*" a ".*")) b))))
(re-matches (re-pattern (str "(?s).*" a ".*")) b))))
(def date [2012 6 3]) (def date [2012 6 3])
(def test-title "some-title") (def test-title "some-title")
(def test-note "# This is a test note.\nHello _world_. Motörhead, тест.") (def test-note "# This is a test note.\nHello _world_. Motörhead, тест.")
(defn create-testnote-fixture [f] (defn create-testnote-fixture [f]
(set-note date test-title test-note) (add-note (build-key date test-title) test-note)
(f) (f)
(delete-note date test-title)) (delete-note (build-key date test-title)))
(use-fixtures :each create-testnote-fixture) (use-fixtures :each create-testnote-fixture)
@ -23,8 +22,8 @@
(deftest testing-fixture (deftest testing-fixture
(testing "Was a not created?" (testing "Was a not created?"
(is (= (get-note date test-title) test-note)) (is (= (get-note (build-key date test-title)) test-note))
(is (note-exists? date test-title)))) (is (note-exists? (build-key date test-title)))))
(deftest export-test (deftest export-test
(testing "Markdown export" (testing "Markdown export"
@ -42,12 +41,12 @@
{:session-key session-key {:session-key session-key
:draft test-note :draft test-note
:session-value (str (get-hash (str test-note session-key)))}) 302)) :session-value (str (get-hash (str test-note session-key)))}) 302))
(is (note-exists? date title)) (is (note-exists? (build-key date title)))
(is (substring? "Hello _world_" (is (substring? "Hello _world_"
((send-request (url year month day title)) :body))) ((send-request (url year month day title)) :body)))
(is (do (is (do
(delete-note date title) (delete-note (build-key date title))
(not (note-exists? date title))))))) (not (note-exists? (build-key date title))))))))
(deftest note-update (deftest note-update
(let [session-key (create-session) (let [session-key (create-session)
@ -62,7 +61,7 @@
:draft "test note" :draft "test note"
:password "qwerty" :password "qwerty"
:session-value (str (get-hash (str "test note" session-key)))}) 302)) :session-value (str (get-hash (str "test note" session-key)))}) 302))
(is (note-exists? date title)) (is (note-exists? (build-key date title)))
(is (substring? "test note" (is (substring? "test note"
((send-request (url year month day title)) :body))) ((send-request (url year month day title)) :body)))
(is (has-status (is (has-status
@ -82,8 +81,8 @@
(is (substring? "UPDATED CONTENT" (is (substring? "UPDATED CONTENT"
((send-request (url year month day title)) :body))) ((send-request (url year month day title)) :body)))
(is (do (is (do
(delete-note date title) (delete-note (build-key date title))
(not (note-exists? date title))))))) (not (note-exists? (build-key date title))))))))
(deftest requests (deftest requests
(testing "HTTP Status" (testing "HTTP Status"

Loading…
Cancel
Save