Skip to content

Instantly share code, notes, and snippets.

@alpox
Last active April 26, 2024 16:12
Show Gist options
  • Save alpox/96f88f08aed677c1ecddfa35ce94b179 to your computer and use it in GitHub Desktop.
Save alpox/96f88f08aed677c1ecddfa35ce94b179 to your computer and use it in GitHub Desktop.
(ns c20
(:require
[next.jdbc :as jdbc]
[honey.sql :as sql]
[tick.core :as t]
[next.jdbc.date-time]
[clojure.test :refer [is use-fixtures deftest]]))
(def db-spec
{:dbtype "postgres"
:dbname "fcc"
:user "postgres"
:password "fcc"})
(def db (jdbc/get-datasource db-spec))
(jdbc/execute! db ["CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\";"])
(jdbc/execute! db ["CREATE TABLE IF NOT EXISTS infractions (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
username varchar(255)
)"])
(defn user-infractions-since [username days]
{:select [:%count.id]
:from :infractions
:where [:and
[:= :username username]
[:<
[:- [:now] [:interval [:inline (str days " days")]]]
:created_at]]})
(defn is-naughty [username]
(let [{:keys [all latest]}
(jdbc/execute-one!
db
(sql/format {:select [[(user-infractions-since username 30) :all]
[(user-infractions-since username 7) :latest]]}))
naughty? (or (>= latest 3) (>= all 5))]
(when-not naughty?
(jdbc/execute! db
(sql/format {:insert-into :infractions
:values [{:username username}]})))
naughty?))
; ---------------- TESTS ----------------
; alice -> naughty (5 infractions past 30 days)
; bob -> naughty (3 infractions past 7 days)
; mona -> not naughty (4 infractions past 30 days but 1 more than 30)
; pierce -> not naughty (too less infractions)
(def fixture-data
[{:username "alice"
:created_at (-> 20 t/of-days t/ago)}
{:username "alice"
:created_at (-> 15 t/of-days t/ago)}
{:username "alice"
:created_at (-> 3 t/of-days t/ago)}
{:username "alice"
:created_at (-> 10 t/of-days t/ago)}
{:username "alice"
:created_at (-> 8 t/of-days t/ago)}
{:username "bob"
:created_at (-> 3 t/of-days t/ago)}
{:username "bob"
:created_at (-> 5 t/of-days t/ago)}
{:username "bob"
:created_at (-> 6 t/of-days t/ago)}
{:username "bob"
:created_at (-> 40 t/of-days t/ago)}
{:username "mona"
:created_at (-> 31 t/of-days t/ago)}
{:username "mona"
:created_at (-> 15 t/of-days t/ago)}
{:username "mona"
:created_at (-> 3 t/of-days t/ago)}
{:username "mona"
:created_at (-> 10 t/of-days t/ago)}
{:username "mona"
:created_at (-> 8 t/of-days t/ago)}
{:username "pierce"
:created_at (-> 4 t/of-days t/ago)}])
(defn fixtures [f]
(jdbc/execute! db
(sql/format {:insert-into :infractions
:values fixture-data}))
(f)
(jdbc/execute! db
(sql/format {:delete-from :infractions})))
(use-fixtures :once fixtures)
(deftest test-is-naughty
(is (is-naughty "alice"))
(is (is-naughty "bob"))
(is (not (is-naughty "mona")))
(is (not (is-naughty "pierce"))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment