;; This Source Code Form is subject to the terms of the Mozilla Public ;; License, v. 2.0. If a copy of the MPL was not distributed with this ;; file, You can obtain one at http://mozilla.org/MPL/2.0/. ;; ;; Copyright (c) KALEIDOS INC Sucursal en EspaƱa SL (ns common-tests.schema-test (:require [app.common.data :as d] [app.common.schema :as sm] [app.common.schema.generators :as sg] [clojure.test :as t])) (t/deftest test-set-of-email (t/testing "decoding" (let [candidate1 "a@b.com a@c.net" schema [::sm/set ::sm/email] result1 (sm/decode schema candidate1 sm/string-transformer) result2 (sm/decode schema candidate1 sm/json-transformer)] (t/is (= result1 #{"a@b.com" "a@c.net"})) (t/is (= result2 #{"a@b.com" "a@c.net"})))) (t/testing "encoding" (let [candidate #{"a@b.com" "a@c.net"} schema [::sm/set ::sm/email] result1 (sm/encode schema candidate sm/string-transformer) result2 (sm/decode schema candidate sm/json-transformer)] (t/is (= result1 "a@b.com, a@c.net")) (t/is (= result2 candidate)))) (t/testing "validate" (let [candidate #{"a@b.com" "a@c.net"} schema [::sm/set ::sm/email]] (t/is (true? (sm/validate schema candidate))) (t/is (true? (sm/validate schema #{}))) (t/is (false? (sm/validate schema #{"a"}))))) (t/testing "validate 2" (let [candidate-1 ["a@b.com" "a@c.net"] candidate-2 (into #{} candidate-1) candidate-3 (into (d/ordered-set) candidate-1) candidate-4 #{"a@b.com"} candidate-5 (d/ordered-set "a@b.com") schema-1 [::sm/set ::sm/email] schema-2 [::sm/set {:ordered true} ::sm/email] schema-3 [::sm/set {:ordered true :min 1} ::sm/email] schema-4 [::sm/set {:min 1} ::sm/email] schema-5 [::sm/set {:ordered true :max 1} ::sm/email] schema-6 [::sm/set {:ordered true :min 1 :max 2} ::sm/email] schema-7 [::sm/set {:min 1 :max 2} ::sm/email]] (t/is (false? (sm/validate schema-1 []))) (t/is (false? (sm/validate schema-1 candidate-1))) (t/is (true? (sm/validate schema-1 candidate-2))) (t/is (true? (sm/validate schema-1 candidate-3))) (t/is (false? (sm/validate schema-2 []))) (t/is (false? (sm/validate schema-2 candidate-1))) (t/is (false? (sm/validate schema-2 candidate-2))) (t/is (true? (sm/validate schema-2 candidate-3))) (t/is (false? (sm/validate schema-3 []))) (t/is (false? (sm/validate schema-3 candidate-1))) (t/is (false? (sm/validate schema-3 candidate-2))) (t/is (true? (sm/validate schema-3 candidate-3))) (t/is (false? (sm/validate schema-3 candidate-4))) (t/is (true? (sm/validate schema-3 candidate-5))) (t/is (false? (sm/validate schema-3 (d/ordered-set)))) (t/is (false? (sm/validate schema-4 []))) (t/is (false? (sm/validate schema-4 candidate-1))) (t/is (true? (sm/validate schema-4 candidate-2))) (t/is (true? (sm/validate schema-4 candidate-3))) (t/is (true? (sm/validate schema-4 candidate-4))) (t/is (true? (sm/validate schema-4 candidate-5))) (t/is (false? (sm/validate schema-4 (d/ordered-set)))) (t/is (false? (sm/validate schema-4 #{}))) (t/is (false? (sm/validate schema-5 []))) (t/is (false? (sm/validate schema-5 candidate-1))) (t/is (false? (sm/validate schema-5 candidate-2))) (t/is (false? (sm/validate schema-5 candidate-3))) (t/is (false? (sm/validate schema-5 candidate-4))) (t/is (true? (sm/validate schema-5 candidate-5))) (t/is (true? (sm/validate schema-5 (d/ordered-set)))) (t/is (false? (sm/validate schema-5 #{}))) (t/is (false? (sm/validate schema-6 []))) (t/is (false? (sm/validate schema-6 candidate-1))) (t/is (false? (sm/validate schema-6 candidate-2))) (t/is (true? (sm/validate schema-6 candidate-3))) (t/is (false? (sm/validate schema-6 candidate-4))) (t/is (true? (sm/validate schema-6 candidate-5))) (t/is (false? (sm/validate schema-6 (d/ordered-set)))) (t/is (false? (sm/validate schema-6 #{}))) (t/is (false? (sm/validate schema-6 (conj candidate-3 "r@r.com")))) (t/is (false? (sm/validate schema-7 []))) (t/is (false? (sm/validate schema-7 candidate-1))) (t/is (true? (sm/validate schema-7 candidate-2))) (t/is (true? (sm/validate schema-7 candidate-3))) (t/is (true? (sm/validate schema-7 candidate-4))) (t/is (true? (sm/validate schema-7 candidate-5))) (t/is (false? (sm/validate schema-7 (d/ordered-set)))) (t/is (false? (sm/validate schema-7 #{}))) (t/is (false? (sm/validate schema-7 (conj candidate-2 "r@r.com")))) (t/is (false? (sm/validate schema-7 (conj candidate-3 "r@r.com")))))) (t/testing "generate" (let [schema [::sm/set ::sm/email] value (sg/generate schema)] (t/is (true? (sm/validate schema (sg/generate schema))))))) (t/deftest test-set-1 (let [candidate-1 "cff4b058-ca31-8197-8005-32aeb2377d83, cff4b058-ca31-8197-8005-32aeb2377d82" candidate-2 ["cff4b058-ca31-8197-8005-32aeb2377d82", "cff4b058-ca31-8197-8005-32aeb2377d83"] candidate-3 #{"cff4b058-ca31-8197-8005-32aeb2377d82", "cff4b058-ca31-8197-8005-32aeb2377d83"} candidate-4 [#uuid "cff4b058-ca31-8197-8005-32aeb2377d82" #uuid "cff4b058-ca31-8197-8005-32aeb2377d83"] candidate-5 #{#uuid "cff4b058-ca31-8197-8005-32aeb2377d82" #uuid "cff4b058-ca31-8197-8005-32aeb2377d83"} expected candidate-5 schema [::sm/set ::sm/uuid] decode-s (sm/decoder schema sm/string-transformer) decode-j (sm/decoder schema sm/json-transformer) encode-s (sm/encoder schema sm/string-transformer) encode-j (sm/encoder schema sm/json-transformer)] (t/is (= expected (decode-s candidate-1))) (t/is (= expected (decode-s candidate-2))) (t/is (= expected (decode-s candidate-3))) (t/is (= expected (decode-s candidate-4))) (t/is (= expected (decode-s candidate-5))) (t/is (= candidate-1 (encode-s expected))) (t/is (= candidate-3 (encode-j expected))))) (t/deftest test-vec-1 (let [candidate-1 "cff4b058-ca31-8197-8005-32aeb2377d83, cff4b058-ca31-8197-8005-32aeb2377d82" candidate-2 ["cff4b058-ca31-8197-8005-32aeb2377d83", "cff4b058-ca31-8197-8005-32aeb2377d82"] candidate-3 #{"cff4b058-ca31-8197-8005-32aeb2377d82", "cff4b058-ca31-8197-8005-32aeb2377d83"} candidate-4 [#uuid "cff4b058-ca31-8197-8005-32aeb2377d83" #uuid "cff4b058-ca31-8197-8005-32aeb2377d82"] candidate-5 #{#uuid "cff4b058-ca31-8197-8005-32aeb2377d82" #uuid "cff4b058-ca31-8197-8005-32aeb2377d83"} expected candidate-4 schema [::sm/vec ::sm/uuid] decode-s (sm/decoder schema sm/string-transformer) decode-j (sm/decoder schema sm/json-transformer) encode-s (sm/encoder schema sm/string-transformer) encode-j (sm/encoder schema sm/json-transformer)] (t/is (= expected (decode-s candidate-1))) (t/is (= expected (decode-s candidate-2))) (t/is (= expected (decode-s candidate-3))) (t/is (= expected (decode-s candidate-4))) (t/is (= expected (decode-s candidate-5))) (t/is (= candidate-1 (encode-s expected))) (t/is (= candidate-2 (encode-j expected))))) (t/deftest test-boolean (let [decode-s (sm/decoder ::sm/boolean sm/string-transformer)] (t/is (= true (decode-s "true"))) (t/is (= true (decode-s "True"))) (t/is (= true (decode-s "TrUe"))) (t/is (= true (decode-s "TRUE"))) (t/is (= false (decode-s "false"))) (t/is (= false (decode-s "False"))) (t/is (= false (decode-s "fAlSe"))) (t/is (= false (decode-s "FALSE"))) (t/is (= true (decode-s "T"))) (t/is (= false (decode-s "F"))) (t/is (= true (decode-s "t"))) (t/is (= false (decode-s "f"))) (t/is (= true (decode-s "1"))) (t/is (= false (decode-s "0"))))) (t/deftest test-email-validation (t/testing "accepts well-formed email addresses" (doseq [email ["user@domain.com" "user.name@domain.com" "user+tag@domain.com" "user-name@domain.com" "user_name@domain.com" "user123@domain.com" "USER@DOMAIN.COM" "u@domain.io" "user@sub.domain.com" "user@domain.co.uk" "user@domain.dev" "a@bc.co"]] (t/is (sm/validate ::sm/email email) (str "should accept: " email)) (t/is (= email (sm/decode ::sm/email email sm/json-transformer))))) (t/testing "rejects domain with consecutive dots (dot-dot)" (t/is (false? (sm/validate ::sm/email "user@gmail.com.."))) (t/is (false? (sm/validate ::sm/email "user@sub..domain.com"))) (t/is (false? (sm/validate ::sm/email "eissaalbothigi@gmail.com.."))) (t/is (nil? (sm/parse-email "user@gmail.com.."))) (t/is (nil? (sm/parse-email "eissaalbothigi@gmail.com..")))) (t/testing "rejects domain ending with a dot" (t/is (false? (sm/validate ::sm/email "user@domain."))) (t/is (nil? (sm/parse-email "user@domain.")))) (t/testing "rejects domain starting with a dot" (t/is (false? (sm/validate ::sm/email "user@.domain.com"))) (t/is (nil? (sm/parse-email "user@.domain.com")))) (t/testing "rejects local part with consecutive dots" (t/is (false? (sm/validate ::sm/email "user..name@domain.com"))) (t/is (nil? (sm/parse-email "user..name@domain.com")))) (t/testing "rejects local part starting with a dot" (t/is (false? (sm/validate ::sm/email ".user@domain.com"))) (t/is (nil? (sm/parse-email ".user@domain.com")))) (t/testing "rejects label starting or ending with hyphen" (t/is (false? (sm/validate ::sm/email "user@-domain.com"))) (t/is (false? (sm/validate ::sm/email "user@domain-.com")))) (t/testing "rejects TLD shorter than 2 chars" (t/is (false? (sm/validate ::sm/email "user@domain.c")))) (t/testing "rejects domain without a dot" (t/is (false? (sm/validate ::sm/email "user@domain")))) (t/testing "rejects empty or malformed emails" (t/is (false? (sm/validate ::sm/email ""))) (t/is (false? (sm/validate ::sm/email "@domain.com"))) (t/is (false? (sm/validate ::sm/email "user@"))) (t/is (false? (sm/validate ::sm/email "userdomain.com"))) (t/is (false? (sm/validate ::sm/email "user@@domain.com")))))