From 70aedbf12c82ab4da8c358823169e8b28298293c Mon Sep 17 00:00:00 2001 From: Marcin Kulik Date: Sat, 11 Feb 2017 17:50:57 +0100 Subject: [PATCH] AsciicastDatabase component --- src/asciinema/boundary/asciicast_database.clj | 36 +++++++++++++ .../boundary/asciicast_database_test.clj | 53 +++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 src/asciinema/boundary/asciicast_database.clj create mode 100644 test/asciinema/boundary/asciicast_database_test.clj diff --git a/src/asciinema/boundary/asciicast_database.clj b/src/asciinema/boundary/asciicast_database.clj new file mode 100644 index 0000000..8fb904d --- /dev/null +++ b/src/asciinema/boundary/asciicast_database.clj @@ -0,0 +1,36 @@ +(ns asciinema.boundary.asciicast-database + (:require [clojure.java.jdbc :as jdbc] + [clj-time.coerce :as timec] + [duct.component.hikaricp :as hikaricp])) + +(defprotocol AsciicastDatabase + (get-asciicast-by-id [this id]) + (get-asciicast-by-token [this token])) + +(extend-protocol clojure.java.jdbc/ISQLValue + org.joda.time.DateTime + (sql-value [val] + (timec/to-sql-time val))) + +(extend-protocol clojure.java.jdbc/IResultSetReadColumn + java.sql.Timestamp + (result-set-read-column [x _ _] + (timec/from-sql-time x))) + +(def q-get-asciicast-by-id "SELECT * FROM asciicasts WHERE id=?") +(def q-get-asciicast-by-secret-token "SELECT * FROM asciicasts WHERE secret_token=?") +(def q-get-public-asciicast-by-id "SELECT * FROM asciicasts WHERE id=? AND private=FALSE") + +(extend-protocol AsciicastDatabase + duct.component.hikaricp.HikariCP + + (get-asciicast-by-id [{db :spec} id] + (first (jdbc/query db [q-get-asciicast-by-id id]))) + + (get-asciicast-by-token [{db :spec} token] + (when-let [query (cond + (re-matches #"\d+" token) + [q-get-public-asciicast-by-id (Long/parseLong token)] + (= (count token) 25) + [q-get-asciicast-by-secret-token token])] + (first (jdbc/query db query))))) diff --git a/test/asciinema/boundary/asciicast_database_test.clj b/test/asciinema/boundary/asciicast_database_test.clj new file mode 100644 index 0000000..5860bad --- /dev/null +++ b/test/asciinema/boundary/asciicast_database_test.clj @@ -0,0 +1,53 @@ +(ns asciinema.boundary.asciicast-database-test + (:require [clojure.test :refer :all] + [clojure.java.jdbc :as jdbc] + [clj-time.local :as timel] + [com.stuartsierra.component :as component] + [asciinema.boundary.asciicast-database :as db])) + +(defmacro with-db-component [component-var & body] + `(let [component# (-> (duct.component.hikaricp/hikaricp {:uri "jdbc:postgresql://localhost:15432/asciinema_test?user=vagrant"}) + component/start)] + (try + (jdbc/with-db-transaction [db# (:spec component#)] + (let [~component-var (assoc component# :spec db#)] + (jdbc/db-set-rollback-only! db#) + ~@body)) + (finally + (component/stop component#))))) + +(defn insert-asciicast + ([db] (insert-asciicast db {})) + ([db attrs] + (first (jdbc/insert! db :asciicasts (merge {:duration 10.0 + :terminal_columns 80 + :terminal_lines 24 + :created_at (timel/local-now) + :updated_at (timel/local-now) + :version 1 + :secret_token "abcdeabcdeabcdeabcdeabcde"} + attrs))))) + +(deftest get-asciicast-by-id-test + (testing "for existing asciicast" + (with-db-component db + (let [asciicast (insert-asciicast (:spec db))] + (is (map? (db/get-asciicast-by-id db (:id asciicast))))))) + (testing "for non-existing asciicast" + (with-db-component db + (is (nil? (db/get-asciicast-by-id db 1)))))) + +(deftest get-asciicast-by-token-test + (testing "for existing public asciicast" + (with-db-component db + (let [asciicast (insert-asciicast (:spec db) {:private false})] + (is (map? (db/get-asciicast-by-token db (:secret_token asciicast)))) + (is (map? (db/get-asciicast-by-token db (-> asciicast :id str))))))) + (testing "for existing private asciicast" + (with-db-component db + (let [asciicast (insert-asciicast (:spec db) {:private true})] + (is (map? (db/get-asciicast-by-token db (:secret_token asciicast)))) + (is (nil? (db/get-asciicast-by-token db (-> asciicast :id str))))))) + (testing "for non-existing asciicast" + (with-db-component db + (is (nil? (db/get-asciicast-by-token db "1"))))))