Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for coercing valid URLs #2

Merged
merged 2 commits into from Apr 14, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 15 additions & 2 deletions src/constraint/validations/url.clj
@@ -1,5 +1,6 @@
(ns constraint.validations.url
(:import [org.apache.commons.validator.routines UrlValidator])
(:import [java.net URL]
[org.apache.commons.validator.routines UrlValidator])
(:require [clojure.string :as str]
[constraint.core :refer [Transform]]))

Expand All @@ -19,7 +20,8 @@
(deftype Url [schemes]
Transform
(transform* [_ value]
(if-not (valid? schemes value)
(if (valid? schemes value)
{:value (URL. value)}
{:errors #{(invalid-url schemes value)}})))

(defn url
Expand All @@ -30,3 +32,14 @@
(url [\"https\"])"
[schemes]
(Url. schemes))

(defn- string->url [schemes value]
(if (valid? schemes value)
{:value (URL. value)}
{:errors (set (invalid-url schemes value))}))

(defn url-coercions
"Defines coercion from a java.lang.String to a java.net.URL given the allowed
schemes."
[schemes]
{[String URL] (partial string->url schemes)})
32 changes: 22 additions & 10 deletions test/constraint/validations/url_test.clj
@@ -1,4 +1,5 @@
(ns constraint.validations.url-test
(:import [java.net URL])
(:require [clojure.test :refer :all]
[constraint.core :refer :all]
[constraint.validations.url :refer :all]))
Expand All @@ -13,25 +14,36 @@
"example.com")

(deftest test-with-scheme
(let [schemes ["http"]]
(is (valid? (url schemes) valid-http))
(let [validator (url ["http"])]
(is (valid? validator valid-http))

(is (not (valid? (url schemes) valid-https)))
(is (not (valid? (url schemes) domain-only)))
(is (instance? java.net.URL (coerce validator valid-http))
"transforms the URL string into a java.net.URL")

(is (= (validate (url schemes) domain-only)
(is (not (valid? validator valid-https)))
(is (not (valid? validator domain-only)))

(is (= (validate validator domain-only)
[{:error :invalid-url
:message "Expected URL with scheme \"http\""
:found domain-only}]))))

(deftest test-with-schemes
(let [schemes ["http" "https"]]
(is (valid? (url schemes) valid-http))
(is (valid? (url schemes) valid-https))
(let [validator (url ["http" "https"])]
(doseq [url [valid-http valid-https]]
(is (valid? validator url))
(is (instance? java.net.URL (coerce validator url))
"transforms the http URL string into a java.net.URL"))

(is (not (valid? (url schemes) domain-only)))
(is (not (valid? validator domain-only)))

(is (= (validate (url schemes) domain-only)
(is (= (validate validator domain-only)
[{:error :invalid-url
:message "Expected URL with scheme \"http\", or \"https\""
:found domain-only}]))))

(deftest test-coercions
(let [url (URL. "http://example.com")
coercions (url-coercions ["http"])]
(is (valid? URL (str url) coercions))
(is (= (coerce URL (str url) coercions) url))))