<commit_before>(ns ctia.test-helpers.core
  (:refer-clojure :exclude [get])
  (:require [ctia.auth :as auth]
            [ctia.auth.allow-all :as aa]
            [ctia.properties :as props]
            [ctia.store :as store]
            [ctia.stores.atom.store :as as]
            [cheshire.core :as json]
            [clj-http.client :as http]
            [clojure.data :as cd]
            [clojure.edn :as edn]
            [clojure.test :as ct]
            [ring.adapter.jetty :as jetty]
            [schema.core :as schema]))

(defmethod ct/assert-expr 'deep= [msg form]
  (let [a (second form)
        b (nth form 2)]
    `(let [[only-a# only-b# _] (cd/diff ~a ~b)]
       (if (or only-a# only-b#)
         (let [only-msg# (str (when only-a# (str "Only in A: " only-a#))
                              (when (and only-a# only-b#) ", ")
                              (when only-b# (str "Only in B: " only-b#)))]
           (ct/do-report {:type :fail, :message ~msg,
                          :expected '~form, :actual only-msg#}))
         (ct/do-report {:type :pass, :message ~msg,
                        :expected '~form, :actual nil})))))

(defn fixture-properties [f]
  (with-redefs [props/files ["ctia-test.properties"]]
    (props/init!))
  (f))


(defn fixture-schema-validation [f]
  (schema/with-fn-validation
    (f)))

(defn fixture-allow-all-auth [f]
  (let [orig-auth-srvc @auth/auth-service]
    (reset! auth/auth-service (aa/->AuthService))
    (f)
    (reset! auth/auth-service orig-auth-srvc)))

(defn init-atom [f]
  (fn []
    (f (atom {}))))

(def atom-stores
  {store/actor-store          (init-atom as/->ActorStore)
   store/judgement-store      (init-atom as/->JudgementStore)
   store/feedback-store       (init-atom as/->FeedbackStore)
   store/campaign-store       (init-atom as/->CampaignStore)
   store/coa-store            (init-atom as/->COAStore)
   store/exploit-target-store (init-atom as/->ExploitTargetStore)
   store/incident-store       (init-atom as/->IncidentStore)
   store/indicator-store      (init-atom as/->IndicatorStore)
   store/sighting-store       (init-atom as/->SightingStore)
   store/ttp-store            (init-atom as/->TTPStore)
   store/identity-store       (init-atom as/->IdentityStore)})

(defn fixture-store [store-map]
  (fn [f]
    (doseq [[store impl-fn] store-map]
      (reset! store (impl-fn)))
    (f)
    (doseq  [store (keys store-map)]
      (reset! store nil))))

(def fixture-atom-store (fixture-store atom-stores))

(def http-port 3000)

(defn fixture-server [app & {:keys [port]
                             :or {port http-port}}]
  (fn [f]
    (let [server (jetty/run-jetty app
                                  {:host "localhost"
                                   :port port
                                   :join? false
                                   :max-threads 10
                                   :min-threads 9})]
      (f)
      (.stop server))))

(defn set-capabilities! [login role caps]
  (store/create-identity @store/identity-store
                         {:login login
                          :role role
                          :capabilities caps}))

(defn url
  ([path]
   (url path http-port))
  ([path port]
   (format "http://localhost:%d/%s" port path)))

;; Replace this with clojure.string/includes? once we are at Clojure 1.8
(defn includes?
  [^CharSequence s ^CharSequence substr]
  (.contains (.toString s) substr))

(defn content-type? [expected-str]
  (fn [test-str]
    (if (some? test-str)
      (includes? (name test-str) expected-str)
      false)))

(def json? (content-type? "json"))

(def edn? (content-type? "edn"))

(defn parse-body
  ([http-response]
   (parse-body http-response nil))
  ([{{content-type "Content-Type"} :headers
     body :body}
    default]
   (cond
     (edn? content-type) (edn/read-string body)
     (json? content-type) (json/parse-string body)
     :else default)))

(defn encode-body
  [body content-type]
  (cond
    (edn? content-type) (pr-str body)
    (json? content-type) (json/generate-string body)
    :else body))

(defn get [path & {:as options}]
  (let [options
        (merge {:accept :edn
                :throw-exceptions false}
               options)

        response
        (http/get (url path)
                  options)]
    (assoc response :parsed-body (parse-body response))))

(defn post [path & {:as options}]
  (let [{:keys [body content-type]
         :as options}
        (merge {:content-type :edn
                :accept :edn
                :throw-exceptions false
                :socket-timeout 2000
                :conn-timeout 2000}
               options)

        response
        (http/post (url path)
                   (-> options
                       (cond-> body (assoc :body (encode-body body content-type)))))]
    (assoc response :parsed-body (parse-body response))))

(defn delete [path & {:as options}]
  (http/delete (url path)
               (merge {:throw-exceptions false}
                      options)))

(defn put [path & {:as options}]
  (let [{:keys [body content-type]
         :as options}
        (merge {:content-type :edn
                :accept :edn
                :throw-exceptions false
                :socket-timeout 2000
                :conn-timeout 2000}
               options)

        response
        (http/put (url path)
                  (-> options
                      (cond-> body (assoc :body (encode-body body content-type)))))]
    (assoc response :parsed-body (parse-body response))))
<commit_msg>Increasing socket timeouts in tests<commit_after>(ns ctia.test-helpers.core
  (:refer-clojure :exclude [get])
  (:require [ctia.auth :as auth]
            [ctia.auth.allow-all :as aa]
            [ctia.properties :as props]
            [ctia.store :as store]
            [ctia.stores.atom.store :as as]
            [cheshire.core :as json]
            [clj-http.client :as http]
            [clojure.data :as cd]
            [clojure.edn :as edn]
            [clojure.test :as ct]
            [ring.adapter.jetty :as jetty]
            [schema.core :as schema]))

(defmethod ct/assert-expr 'deep= [msg form]
  (let [a (second form)
        b (nth form 2)]
    `(let [[only-a# only-b# _] (cd/diff ~a ~b)]
       (if (or only-a# only-b#)
         (let [only-msg# (str (when only-a# (str "Only in A: " only-a#))
                              (when (and only-a# only-b#) ", ")
                              (when only-b# (str "Only in B: " only-b#)))]
           (ct/do-report {:type :fail, :message ~msg,
                          :expected '~form, :actual only-msg#}))
         (ct/do-report {:type :pass, :message ~msg,
                        :expected '~form, :actual nil})))))

(defn fixture-properties [f]
  (with-redefs [props/files ["ctia-test.properties"]]
    (props/init!))
  (f))


(defn fixture-schema-validation [f]
  (schema/with-fn-validation
    (f)))

(defn fixture-allow-all-auth [f]
  (let [orig-auth-srvc @auth/auth-service]
    (reset! auth/auth-service (aa/->AuthService))
    (f)
    (reset! auth/auth-service orig-auth-srvc)))

(defn init-atom [f]
  (fn []
    (f (atom {}))))

(def atom-stores
  {store/actor-store          (init-atom as/->ActorStore)
   store/judgement-store      (init-atom as/->JudgementStore)
   store/feedback-store       (init-atom as/->FeedbackStore)
   store/campaign-store       (init-atom as/->CampaignStore)
   store/coa-store            (init-atom as/->COAStore)
   store/exploit-target-store (init-atom as/->ExploitTargetStore)
   store/incident-store       (init-atom as/->IncidentStore)
   store/indicator-store      (init-atom as/->IndicatorStore)
   store/sighting-store       (init-atom as/->SightingStore)
   store/ttp-store            (init-atom as/->TTPStore)
   store/identity-store       (init-atom as/->IdentityStore)})

(defn fixture-store [store-map]
  (fn [f]
    (doseq [[store impl-fn] store-map]
      (reset! store (impl-fn)))
    (f)
    (doseq  [store (keys store-map)]
      (reset! store nil))))

(def fixture-atom-store (fixture-store atom-stores))

(def http-port 3000)

(defn fixture-server [app & {:keys [port]
                             :or {port http-port}}]
  (fn [f]
    (let [server (jetty/run-jetty app
                                  {:host "localhost"
                                   :port port
                                   :join? false
                                   :max-threads 10
                                   :min-threads 9})]
      (f)
      (.stop server))))

(defn set-capabilities! [login role caps]
  (store/create-identity @store/identity-store
                         {:login login
                          :role role
                          :capabilities caps}))

(defn url
  ([path]
   (url path http-port))
  ([path port]
   (format "http://localhost:%d/%s" port path)))

;; Replace this with clojure.string/includes? once we are at Clojure 1.8
(defn includes?
  [^CharSequence s ^CharSequence substr]
  (.contains (.toString s) substr))

(defn content-type? [expected-str]
  (fn [test-str]
    (if (some? test-str)
      (includes? (name test-str) expected-str)
      false)))

(def json? (content-type? "json"))

(def edn? (content-type? "edn"))

(defn parse-body
  ([http-response]
   (parse-body http-response nil))
  ([{{content-type "Content-Type"} :headers
     body :body}
    default]
   (cond
     (edn? content-type) (edn/read-string body)
     (json? content-type) (json/parse-string body)
     :else default)))

(defn encode-body
  [body content-type]
  (cond
    (edn? content-type) (pr-str body)
    (json? content-type) (json/generate-string body)
    :else body))

(defn get [path & {:as options}]
  (let [options
        (merge {:accept :edn
                :throw-exceptions false
                :socket-timeout 10000
                :conn-timeout 10000}
               options)

        response
        (http/get (url path)
                  options)]
    (assoc response :parsed-body (parse-body response))))

(defn post [path & {:as options}]
  (let [{:keys [body content-type]
         :as options}
        (merge {:content-type :edn
                :accept :edn
                :throw-exceptions false
                :socket-timeout 10000
                :conn-timeout 10000}
               options)

        response
        (http/post (url path)
                   (-> options
                       (cond-> body (assoc :body (encode-body body content-type)))))]
    (assoc response :parsed-body (parse-body response))))

(defn delete [path & {:as options}]
  (http/delete (url path)
               (merge {:throw-exceptions false}
                      options)))

(defn put [path & {:as options}]
  (let [{:keys [body content-type]
         :as options}
        (merge {:content-type :edn
                :accept :edn
                :throw-exceptions false
                :socket-timeout 10000
                :conn-timeout 10000}
               options)

        response
        (http/put (url path)
                  (-> options
                      (cond-> body (assoc :body (encode-body body content-type)))))]
    (assoc response :parsed-body (parse-body response))))

{'fraction_non_alphanumeric': 0.14464733261725743, 'fraction_numerical': 0.005907626208378088, 'mean_word_length': 1.7953465098824117, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2740174', 'n_tokens_mistral': 3712, 'n_tokens_neox': 3516, 'n_words': 896}