robocop

Checks KYC attributes against sanction lists
Log | Files | Refs | Submodules | README | LICENSE

commit 460c82d634d54cba8b2f421269ee61505a037dc1
parent 88c9fdf95fd5e6554badcb1c008e0fabcb7a9a40
Author: Vint Leenaars <vl.software@leenaa.rs>
Date:   Sun,  4 May 2025 23:34:20 +0200

Improve checks + tests

Diffstat:
Msrc/KYC/Check.hs | 45++++++++++++++++++++++++++++++++++-----------
Mtest/Tests/Check.hs | 630+++++++++++++------------------------------------------------------------------
Atest/Tests/Targets/Fake.hs | 259+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atest/Tests/Targets/Real.hs | 259+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 654 insertions(+), 539 deletions(-)

diff --git a/src/KYC/Check.hs b/src/KYC/Check.hs @@ -19,7 +19,8 @@ import Data.Maybe import Data.Map (Map, toList) import Data.Ratio -import Data.Text (intercalate, pack, Text) +import Data.Text (intercalate, pack, snoc, Text) +import qualified Data.Text as T import Data.Text.Metrics import Data.Time.Calendar @@ -95,25 +96,39 @@ checkPersons individuals' person = Score { match_quality = 0 checkPersons' :: NaturalPerson -> (Float, [Int]) -> [(Int, Individual)] -> (Float, [Int]) checkPersons' _ score [] = score checkPersons' person (score, ssids) ((ssid,ind):inds) = let - points = checkPerson person ind - new_score = if points >= 300 then 1 else points / 300 + points = checkPerson person ind + new_score = if max_points >= threshold_points + then if points >= 300 then 1 else points / 300 + else points / max_points in - if points >= threshold_points + if new_score >= 2 / 3 then checkPersons' person (max score new_score, ssid:ssids) inds else checkPersons' person (score, ssids) inds + where max_points = foldl1 (+) [ if toList (addresses ind) == [] then 0 else 150 + , if toList (birth_dates ind) == [] then 0 else 100 + , if toList (ids ind) == [] then 0 else 200 + , if toList (names ind) == [] then 0 else 125 + , if toList (nationalities ind) == [] then 0 else 50 + ] checkPerson :: NaturalPerson -> Individual -> Float -checkPerson person individual = foldl1 (+) [ multFloats 150 address_score (removeQuality . removeSSID) - , multFloats 100 date_score (removeQuality . removeSSID) +checkPerson person individual = foldl1 (+) [ address_points , multFloats 200 id_score removeSSID - , multFloats 125 name_score (removeQuality . removeSSID) + , multFloats 100 date_score (removeQuality . removeSSID) , 50 * nationality_score + , name_points ] where address_score = checkAddress (addresses individual) (residential person) - date_score = checkBirthDate (birth_dates individual) (birthdate person) id_score = checkID (ids individual) (national_id person) - name_score = checkNames (names individual) (full_name person) nationality_score = checkCountryCode (nationalities individual) (nationality person) + name_score = checkNames (names individual) (full_name person) + date_score = if name_points == 0 + then [] + else checkBirthDate (birth_dates individual) (birthdate person) + address_points = multFloats 150 address_score (removeQuality . removeSSID) + name_points = if address_points >= 100 + then 125 + else multFloats 125 name_score (removeQuality . removeSSID) multFloats :: Float -> [a] -> (a -> Float) -> Float multFloats factor list toFloat = factor * foldl (\n x -> max n $ toFloat x) 0 list @@ -206,9 +221,13 @@ compareAddress gls_address (ssid, quality) = if total_score >= threshold_float Just det -> let perms = permutateText $ catMaybes [ Just $ street_name gls_address , Just $ street_number gls_address - , lines gls_address + , country_subdivision gls_address + , lines gls_address + , town_district gls_address + , town_location gls_address + , Just $ zipcode gls_address ] - ratio = compareTexts det 0 perms + ratio = compareTexts (cleanText det) 0 perms in Just $ if ratio >= threshold_ratio then ratioToFloat ratio else 0 Nothing -> Nothing @@ -240,6 +259,10 @@ compareAddress gls_address (ssid, quality) = if total_score >= threshold_float Nothing -> Nothing +cleanText :: [Text] -> [Text] +cleanText text = map (T.foldl (\new_text char -> if char `elem` chars_to_rm then new_text else snoc new_text char) start_text) text + where chars_to_rm = ".,-" :: String + start_text = "" :: Text permutateText :: [Text] -> [Text] permutateText elems = map (intercalate " ") $ concatMap permutations $ subsequences elems diff --git a/test/Tests/Check.hs b/test/Tests/Check.hs @@ -6,15 +6,16 @@ module Tests.Check import Control.Monad (when) -import Data.CountryCodes import Data.Map (Map, toList) -import Data.Time.Calendar import KYC.Check import KYC.GLS.Type as GLS import KYC.SSL as SSL import KYC.Type +import Tests.Targets.Real +import Tests.Targets.Fake + import Test.Tasty import Test.Tasty.HUnit @@ -32,552 +33,125 @@ data Distribution = Distribution , threshold_confidence :: Maybe Float } deriving (Show, Eq) -testTrusted :: Bool -> NaturalPerson -> Map Int Individual -> String -> TestTree -testTrusted verbose person sanction_list title = testCase ("Do not find " ++ title) $ do - let score = checkPersons sanction_list person - when verbose $ print score - compareScore (Just 0) (confidence score) "Score" - assertBool "Should not have found any match" ([] == references score) +-- | Test fake target (found in target_SSID.xml, not found in sanction list) +testFakeTarget :: Bool -> Int -> NaturalPerson -> Map Int Individual -> Distribution -> TestTree +testFakeTarget verbose number target sanction_list distribution = + testGroup ("Test fake target " ++ show number) + [ testSingleTarget verbose (show number) target distribution + , dontFindTarget verbose target sanction_list ("target " ++ show number) + ] + + +-- | Test real target (found in target_SSID.xml, found in sanction list) testTarget :: Bool -> Int -> NaturalPerson -> Map Int Individual -> Distribution -> TestTree -testTarget verbose number target ind_map distribution = +testTarget verbose number target sanction_list distribution = testGroup ("Test target " ++ show number) - [ testPerfectTarget verbose (show number) target distribution - , findPerfectTarget verbose number target distribution ind_map + [ testSingleTarget verbose (show number) target distribution + , findRealTarget verbose number target distribution sanction_list ] -findPerfectTarget :: Bool -> Int -> NaturalPerson -> Distribution -> Map Int Individual -> TestTree -findPerfectTarget verbose number target distribution ind_map = testCase ("Find target " ++ show number ++ " in Swiss Sanction List") $ do - let score = checkPersons ind_map target - when verbose $ print score - compareScore (threshold_confidence distribution) (confidence score) "Score" - assertBool ("Should find target " ++ show number) (number `elem` references score) +-- | Find target in sanction list +findRealTarget :: Bool -> Int -> NaturalPerson -> Distribution -> Map Int Individual -> TestTree +findRealTarget verbose number target distribution sanction_list = + testCase ("Find target " ++ show number ++ " in Swiss Sanction List") $ do + let score = checkPersons sanction_list target + + when verbose $ print score + compareScore (threshold_confidence distribution) (confidence score) "Score" + assertBool ("Should find target " ++ show number ++ ", but found " ++ (show . references) score ++ " instead") (number `elem` references score) + +-- | Dont find target in sanction list +dontFindTarget :: Bool -> NaturalPerson -> Map Int Individual -> String -> TestTree +dontFindTarget verbose target sanction_list title = + testCase ("Do not find " ++ title ++ " in Swiss Sanction List") $ do + let score = checkPersons sanction_list target -testPerfectTarget :: Bool -> String -> NaturalPerson -> Distribution -> TestTree -testPerfectTarget verbose number target distribution = testCase ("Find target " ++ number ++ " in test file") $ do - let filepath = "target_" ++ number ++ ".xml" + when verbose $ print score + compareScore (Just 0) (confidence score) "Score" + assertBool ("Should not find " ++ title ++ ", but found " ++ (show . references) score ++ " instead") (references score == []) - ssl <- (individuals . xmlToSSL) <$> parseSwissSanctionsList filepath - assertBool (filepath ++ " should contain only this target") (toList ssl /= []) - let ((ssid,individual):_) = toList ssl - assertBool ("SSID should be " ++ number) (ssid == read number) +-- | Test if target matches target described in target_SSID.xml +testSingleTarget :: Bool -> String -> NaturalPerson -> Distribution -> TestTree +testSingleTarget verbose number target distribution = + testCase ("Find target " ++ number ++ " in test file") $ do + let filepath = "target_" ++ number ++ ".xml" - let - address_score = multFloats 150 (checkAddress (addresses individual) (residential target)) (removeQuality . removeSSID) - date_score = multFloats 100 (checkBirthDate (birth_dates individual) (birthdate target)) (removeQuality . removeSSID) - id_score = multFloats 200 (checkID (ids individual) (national_id target)) removeSSID - name_score = multFloats 125 (checkNames (names individual) (full_name target)) (removeQuality . removeSSID) + ssl <- (individuals . xmlToSSL) <$> parseSwissSanctionsList filepath + assertBool (filepath ++ " should contain only this target") (toList ssl /= []) - nationality_score = 50 * checkCountryCode (nationalities individual) (nationality target) + let ((ssid,individual):_) = toList ssl + assertBool ("SSID should be " ++ number) (ssid == read number) - total_score = checkPersons ssl target + let + address_score = multFloats 150 (checkAddress (addresses individual) (residential target)) (removeQuality . removeSSID) + date_score = multFloats 100 (checkBirthDate (birth_dates individual) (birthdate target)) (removeQuality . removeSSID) + id_score = multFloats 200 (checkID (ids individual) (national_id target)) removeSSID + name_score = multFloats 125 (checkNames (names individual) (full_name target)) (removeQuality . removeSSID) - when verbose $ print total_score - compareScore (threshold_address distribution) address_score "Address" - compareScore (threshold_date distribution) date_score "Date" - compareScore (threshold_id distribution) id_score "ID" - compareScore (threshold_name distribution) name_score "Name" - compareScore (threshold_nationality distribution) nationality_score "Nationality" + nationality_score = 50 * checkCountryCode (nationalities individual) (nationality target) - compareScore (threshold_confidence distribution) (confidence total_score) "Total score" + total_score = checkPersons ssl target + when verbose $ print total_score + compareScore (threshold_address distribution) address_score "Address" + compareScore (threshold_date distribution) date_score "Date" + compareScore (threshold_id distribution) id_score "ID" + compareScore (threshold_name distribution) name_score "Name" + compareScore (threshold_nationality distribution) nationality_score "Nationality" + + compareScore (threshold_confidence distribution) (confidence total_score) "Total score" + + +-- | Compare expected score to real score compareScore :: Maybe Float -> Float -> String -> Assertion compareScore maybe_threshold score title = case maybe_threshold of - Just pts -> assertBool (title ++ " should return >= " ++ show pts ++ " points") (score >= pts) - Nothing -> assertBool (title ++ " should return 0 points" ) (score == 0 ) + Just pts -> assertBool (title ++ " should return >= " ++ show pts ++ " points, but got " ++ show score ++ " instead") (score >= pts) + Nothing -> assertBool (title ++ " should return 0 points, but got " ++ show score ++ " instead") (score == 0 ) + +-- | Test individuals personTests :: Map Int Individual -> TestTree -personTests map_ind = testGroup "Individuals" - [ testGroup "Known Sanctioned" --- testTarget False SSID target_SSID map_ind $ distribution ADDRESS DATE ID NAME NATIONALITY CONFIDENCE --- MAX_SCORE 150 100 200 125 50 0.75 - [ testTarget False 5144 target_5144 map_ind $ distribution 125 100 0 125 0 0.9 - , testTarget False 5266 target_5266 map_ind $ distribution 0 0 0 125 0 0.5 - , testTarget False 49816 target_49816 map_ind $ distribution 0 100 0 125 0 0.75 - , testTarget False 43462 target_43462 map_ind $ distribution 0 100 0 125 0 0.75 - , testTarget False 43616 target_43616 map_ind $ distribution 0 0 0 125 0 0.75 - , testTarget False 43641 target_43641 map_ind $ distribution 0 100 0 125 0 0.75 - , testTarget False 43718 target_43718 map_ind $ distribution 0 100 0 125 0 0.75 - , testTarget False 43662 target_43662 map_ind $ distribution 0 100 0 125 0 0.75 - , testTarget False 43611 target_43611 map_ind $ distribution 0 0 0 125 0 0.75 - , testTarget False 29723 target_29723 map_ind $ distribution 0 100 0 125 0 0.75 - , testTarget False 6 target_6 map_ind $ distribution 0 100 0 125 0 0.75 - , testTarget False 38925 target_38925 map_ind $ distribution 100 0 0 0 0 0.75 - ] - , testGroup "Public and imaginary figures" - [ testTrusted False public_figure_1 map_ind "Hergé" - , testTrusted False public_figure_2 map_ind "Bezos" - , testTrusted False public_figure_3 map_ind "Lincoln" - , testTrusted False public_figure_4 map_ind "Willem-Alexander" - , testTrusted False public_figure_5 map_ind "Da Vinci" - , testTrusted True imaginary_figure_1 map_ind "Smurf" - , testTrusted False imaginary_figure_2 map_ind "Donald" - , testTrusted True imaginary_figure_3 map_ind "Wonka" - , testTrusted False imaginary_figure_4 map_ind "Bilbo" - , testTrusted True imaginary_figure_5 map_ind "Batman" - ] - ] +personTests sanction_list = + testGroup "Individuals" + [ testGroup "Known Sanctioned" + {- testTarget False SSID target_SSID sanction_list $ distribution ADDRESS DATE ID NAME NATIONALITY CONFIDENCE + MAX_SCORE 150 100 200 125 50 0.75 -} + [ testTarget False 5144 target_5144 sanction_list $ distribution 125 100 0 125 0 0.9 + , testTarget False 5266 target_5266 sanction_list $ distribution 0 0 0 125 0 0.5 + , testTarget False 49816 target_49816 sanction_list $ distribution 0 100 0 125 0 0.75 + , testTarget False 43462 target_43462 sanction_list $ distribution 0 100 0 125 0 0.75 + , testTarget False 43616 target_43616 sanction_list $ distribution 0 0 0 125 0 0.75 + , testTarget False 43641 target_43641 sanction_list $ distribution 0 100 0 125 0 0.75 + , testTarget False 43718 target_43718 sanction_list $ distribution 0 100 0 125 0 0.75 + , testTarget False 43662 target_43662 sanction_list $ distribution 0 100 0 125 0 0.75 + , testTarget False 43611 target_43611 sanction_list $ distribution 0 0 0 125 0 0.75 + , testTarget False 29723 target_29723 sanction_list $ distribution 0 100 0 125 0 0.75 + , testTarget False 38925 target_38925 sanction_list $ distribution 100 0 0 0 0 0.75 + ] + + , testGroup "Fake target with XML file" + {- testFakeTarget False SSID target_SSID sanction_list $ distribution ADDRESS DATE ID NAME NATIONALITY CONFIDENCE + 150 100 200 125 50 0.75 -} + [ testFakeTarget False 6 target_6 sanction_list $ distribution 0 100 0 125 0 0.75 + ] + + , testGroup "Public and imaginary figures" + [ dontFindTarget False public_figure_1 sanction_list "Hergé" + , dontFindTarget False public_figure_2 sanction_list "Bezos" + , dontFindTarget False public_figure_3 sanction_list "Lincoln" + , dontFindTarget False public_figure_4 sanction_list "Willem-Alexander" + , dontFindTarget False public_figure_5 sanction_list "Da Vinci" + , dontFindTarget False imaginary_figure_1 sanction_list "Smurf" + , dontFindTarget False imaginary_figure_2 sanction_list "Donald" + , dontFindTarget False imaginary_figure_3 sanction_list "Wonka" + , dontFindTarget False imaginary_figure_4 sanction_list "Bilbo" + , dontFindTarget False imaginary_figure_5 sanction_list "Batman" + ] + ] where distribution addr date id' name nat conf = Distribution (toMaybe addr) (toMaybe date) (toMaybe id') (toMaybe name) (toMaybe nat) (toMaybe conf) toMaybe float = case float of 0 -> Nothing; f -> Just f - --- target :: NaturalPerson --- target = NaturalPerson --- { full_name = --- , last_name = --- , birthdate = --- , nationality = --- , national_id = --- , residential = GLS.Address { GLS.country = --- , street_name = --- , street_number = --- , GLS.lines = --- , building_name = --- , building_number = --- , zipcode = --- , town_location = --- , town_district = --- , country_subdivision = - -target_5144 :: NaturalPerson -target_5144 = NaturalPerson - { full_name = "Dmitri Aliaksandravich Lukashenko" - , last_name = "Lukashenko" - , birthdate = YearMonthDay 1980 03 23 - , nationality = BY - , national_id = "012345ABCDEF" - , residential = GLS.Address { GLS.country = BY - , street_name = "ул. Старовиленская" - , street_number = "4" - , GLS.lines = Just "President's Sports Club" - , building_name = Nothing - , building_number = Nothing - , zipcode = "220029" - , town_location = Just "г. Минск" - , town_district = Nothing - , country_subdivision = Nothing - } - } - -target_5266 :: NaturalPerson -target_5266 = NaturalPerson - { full_name = "Natallia Alexeeuna Chatviartkova" - , last_name = "Chatviartkova" - , birthdate = YearMonthDay 1960 01 01 -- Made up birth date - , nationality = RU - , national_id = "012345ABCDEF" - , residential = GLS.Address { GLS.country = RU - , street_name = "Non existent" - , street_number = "Non existent" - , GLS.lines = Nothing - , building_name = Nothing - , building_number = Nothing - , zipcode = "Non existent" - , town_location = Nothing - , town_district = Nothing - , country_subdivision = Nothing - } - } - -target_49816 :: NaturalPerson -target_49816 = NaturalPerson - { full_name = "Vladimir Vladimirovich Putin" - , last_name = "Putin" - , birthdate = YearMonthDay 1952 10 07 - , nationality = RU - , national_id = "012345ABCDEF" - , residential = GLS.Address { GLS.country = RU - , street_name = "Инжирный переулок" - , street_number = "1" - , GLS.lines = Nothing - , building_name = Just "Bocharov Ruchey" - , building_number = Nothing - , zipcode = "354008" - , town_location = Just "Sochi" - , town_district = Just "Town district of Sochi" - , country_subdivision = Just "Krasnodar Krai" - } - } - -target_43462 :: NaturalPerson -target_43462 = NaturalPerson - { full_name = "Aleksandr Petrovich Barsukov" - , last_name = "Barsukov" - , birthdate = YearMonthDay 1965 04 29 - , nationality = BY - , national_id = "012345ABCDEF" - , residential = GLS.Address { GLS.country = BY - , street_name = "Non existent" - , street_number = "Non existent" - , GLS.lines = Nothing - , building_name = Nothing - , building_number = Nothing - , zipcode = "Non existent" - , town_location = Nothing - , town_district = Nothing - , country_subdivision = Nothing - } - } - -target_43616 :: NaturalPerson -target_43616 = NaturalPerson - { full_name = "Oleg Anatolievich Chernyshev" - , last_name = "Chernyshev" - , birthdate = YearMonthDay 1985 07 27 -- Made up birth date - , nationality = RU - , national_id = "012345ABCDEF" - , residential = GLS.Address { GLS.country = RU - , street_name = "Non existent" - , street_number = "Non existent" - , GLS.lines = Nothing - , building_name = Nothing - , building_number = Nothing - , zipcode = "Non existent" - , town_location = Nothing - , town_district = Nothing - , country_subdivision = Nothing - } - } - -target_43641 :: NaturalPerson -target_43641 = NaturalPerson - { full_name = "Vadzim Dzmitryevich Ipatau" - , last_name = "Ipatau" - , birthdate = YearMonthDay 1964 10 30 - , nationality = BY - , national_id = "012345ABCDEF" - , residential = GLS.Address { GLS.country = BY - , street_name = "Non existent" - , street_number = "Non existent" - , GLS.lines = Nothing - , building_name = Nothing - , building_number = Nothing - , zipcode = "Non existent" - , town_location = Nothing - , town_district = Nothing - , country_subdivision = Nothing - } - } - -target_43718 :: NaturalPerson -target_43718 = NaturalPerson - { full_name = "Irina Aliaksandrauna Tselikavets" - , last_name = "Tselikavets" - , birthdate = YearMonthDay 1976 11 02 - , nationality = BY - , national_id = "012345ABCDEF" - , residential = GLS.Address { GLS.country = BY - , street_name = "Non existent" - , street_number = "Non existent" - , GLS.lines = Nothing - , building_name = Nothing - , building_number = Nothing - , zipcode = "Non existent" - , town_location = Nothing - , town_district = Nothing - , country_subdivision = Nothing - } - } - -target_43662 :: NaturalPerson -target_43662 = NaturalPerson - { full_name = "Olga Leonidovna Doroshenko" - , last_name = "Doroshenko" - , birthdate = YearMonthDay 1976 09 02 -- Made up birth month and day - , nationality = BY - , national_id = "012345ABCDEF" - , residential = GLS.Address { GLS.country = BY - , street_name = "Non existent" - , street_number = "Non existent" - , GLS.lines = Nothing - , building_name = Nothing - , building_number = Nothing - , zipcode = "Non existent" - , town_location = Nothing - , town_district = Nothing - , country_subdivision = Nothing - } - } - -target_43611 :: NaturalPerson -target_43611 = NaturalPerson - { full_name = "Vladimir Viktorovich Kalach" - , last_name = "Kalach" - , birthdate = YearMonthDay 1960 12 22 -- Made up birth date - , nationality = BY - , national_id = "012345ABCDEF" - , residential = GLS.Address { GLS.country = BY - , street_name = "Non existent" - , street_number = "Non existent" - , GLS.lines = Nothing - , building_name = Nothing - , building_number = Nothing - , zipcode = "Non existent" - , town_location = Nothing - , town_district = Nothing - , country_subdivision = Nothing - } - } - -target_29723 :: NaturalPerson -target_29723 = NaturalPerson - { full_name = "Равиль Закариевич Халиков" - , last_name = "Халиков" - , birthdate = YearMonthDay 1969 02 23 - , nationality = RU - , national_id = "012345ABCDEF" - , residential = GLS.Address { GLS.country = RU - , street_name = "Non existent" - , street_number = "Non existent" - , GLS.lines = Nothing - , building_name = Nothing - , building_number = Nothing - , zipcode = "Non existent" - , town_location = Nothing - , town_district = Nothing - , country_subdivision = Nothing - } - } - -target_38925 :: NaturalPerson -target_38925 = NaturalPerson - { full_name = "Solomon Grundy" - , last_name = "Grundy" - , birthdate = YearMonthDay 1800 06 06 - , nationality = BE - , national_id = "012345ABCDEF" - , residential = GLS.Address { GLS.country = BE - , street_name = "Kryzhizhanovskogo str." - , street_number = "5A" - , GLS.lines = Nothing - , building_name = Nothing - , building_number = Just "64" - , zipcode = "Non existent" - , town_location = Just "Gresovskoe" - , town_district = Nothing - , country_subdivision = Nothing - } - } - -public_figure_1 :: NaturalPerson -public_figure_1 = NaturalPerson - { full_name = "Georges Prosper Remi" - , last_name = "Remi" - , birthdate = YearMonthDay 1907 05 22 - , nationality = BE - , national_id = "012345ABCDEF" - , residential = GLS.Address { GLS.country = BE - , street_name = "Non existent" - , street_number = "Non existent" - , GLS.lines = Nothing - , building_name = Nothing - , building_number = Nothing - , zipcode = "Non existent" - , town_location = Just "Etterbeek" - , town_district = Just "Bruxelles" - , country_subdivision = Just "Brussels" - } - } - -public_figure_2 :: NaturalPerson -public_figure_2 = NaturalPerson - { full_name = "Jeffrey Preston Bezos" - , last_name = "Bezos" - , birthdate = YearMonthDay 1964 01 12 - , nationality = US - , national_id = "012345ABCDEF" - , residential = GLS.Address { GLS.country = US - , street_name = "Negra Arroyo Lane" - , street_number = "308" - , GLS.lines = Nothing - , building_name = Nothing - , building_number = Nothing - , zipcode = "87112" - , town_location = Just "Albuquerque" - , town_district = Just "Bernalillo" - , country_subdivision = Just "New Mexico" - } - } - -public_figure_3 :: NaturalPerson -public_figure_3 = NaturalPerson - { full_name = "Abraham Lincoln" - , last_name = "Lincoln" - , birthdate = YearMonthDay 1809 02 12 - , nationality = US - , national_id = "012345ABCDEF" - , residential = GLS.Address { GLS.country = US - , street_name = "Lincoln Farm Road" - , street_number = "2995" - , GLS.lines = Nothing - , building_name = Just "Abraham Lincoln Birthplace" - , building_number = Nothing - , zipcode = "42748" - , town_location = Just "Hodgenville" - , town_district = Just "LaRue" - , country_subdivision = Just "Kentucky" - } - } - -public_figure_4 :: NaturalPerson -public_figure_4 = NaturalPerson - { full_name = "Willem-Alexander Claus George Ferdinand van Oranje-Nassau" - , last_name = "van Oranje-Nassau" - , birthdate = YearMonthDay 1980 04 30 - , nationality = NL - , national_id = "012345ABCDEF" - , residential = GLS.Address { GLS.country = NL - , street_name = "'s-Gravenhaagse Bos" - , street_number = "10" - , GLS.lines = Nothing - , building_name = Just "Huis ten Bosch" - , building_number = Nothing - , zipcode = "2594BD" - , town_location = Just "'s-Gravenhage" - , town_district = Nothing - , country_subdivision = Just "Zuid-Holland" - } - } - -public_figure_5 :: NaturalPerson -public_figure_5 = NaturalPerson - { full_name = "Leonardo di ser Piero da Vinci" - , last_name = "da Vinci" - , birthdate = YearMonthDay 1452 04 15 - , nationality = IT - , national_id = "012345ABCDEF" - , residential = GLS.Address { GLS.country = IT - , street_name = "Non existent" - , street_number = "Non existent" - , GLS.lines = Nothing - , building_name = Nothing - , building_number = Nothing - , zipcode = "2594BD" - , town_location = Just "Vinci" - , town_district = Just "Florence" - , country_subdivision = Just "Tuscany" - } - } - -imaginary_figure_1 :: NaturalPerson -imaginary_figure_1 = NaturalPerson - { full_name = "Papa Smurf" - , last_name = "Smurf" - , birthdate = YearMonthDay 1958 10 23 - , nationality = FR - , national_id = "012345ABCDEF" - , residential = GLS.Address { GLS.country = FR - , street_name = "Non existent" - , street_number = "Non existent" - , GLS.lines = Nothing - , building_name = Nothing - , building_number = Nothing - , zipcode = "Non existent" - , town_location = Nothing - , town_district = Nothing - , country_subdivision = Just "Smurf Village" - } - } - -imaginary_figure_2 :: NaturalPerson -imaginary_figure_2 = NaturalPerson - { full_name = "Donald Fauntleroy Duck" - , last_name = "Duck" - , birthdate = YearMonthDay 1934 06 09 - , nationality = US - , national_id = "012345ABCDEF" - , residential = GLS.Address { GLS.country = US - , street_name = "South Harbor Boulevard" - , street_number = "1313" - , GLS.lines = Nothing - , building_name = Just "Disneyland" - , building_number = Nothing - , zipcode = "92802" - , town_location = Just "Anaheim" - , town_district = Just "Orange" - , country_subdivision = Just "California" - } - } - -imaginary_figure_3 :: NaturalPerson -imaginary_figure_3 = NaturalPerson - { full_name = "Willy Wonka" - , last_name = "Wonka" - , birthdate = YearMonthDay 1964 01 17 - , nationality = GB - , national_id = "012345ABCDEF" - , residential = GLS.Address { GLS.country = GB - , street_name = "Non existent" - , street_number = "Non existent" - , GLS.lines = Nothing - , building_name = Nothing - , building_number = Nothing - , zipcode = "Non existent" - , town_location = Just "Cardiff" - , town_district = Nothing - , country_subdivision = Just "Wales" - } - } - -imaginary_figure_4 :: NaturalPerson -imaginary_figure_4 = NaturalPerson - { full_name = "Bilbo Baggins" - , last_name = "Baggins" - , birthdate = YearMonthDay 1937 09 21 - , nationality = GB - , national_id = "012345ABCDEF" - , residential = GLS.Address { GLS.country = GB - , street_name = "Bagshot Row" - , street_number = "Non existent" - , GLS.lines = Nothing - , building_name = Just "Bag End" - , building_number = Nothing - , zipcode = "Non existent" - , town_location = Just "Hobbiton" - , town_district = Just "Westfarthing" - , country_subdivision = Just "The Shire" - } - } - -imaginary_figure_5 :: NaturalPerson -imaginary_figure_5 = NaturalPerson - { full_name = "Bruce Wayne" - , last_name = "Wayne" - , birthdate = YearMonthDay 1972 02 19 - , nationality = US - , national_id = "012345ABCDEF" - , residential = GLS.Address { GLS.country = US - , street_name = "Park Drive" - , street_number = "224" - , GLS.lines = Nothing - , building_name = Just "Wayne Manor" - , building_number = Nothing - , zipcode = "19007" - , town_location = Just "Bristol Township" - , town_district = Just "Bucks" - , country_subdivision = Just "Pennsylvania" - } - } - -target_6 :: NaturalPerson -target_6 = NaturalPerson - { full_name = "Bowser" - , last_name = "Bowser" - , birthdate = YearMonthDay 1985 09 13 - , nationality = JP - , national_id = "012345ABCDEF" - , residential = GLS.Address { GLS.country = JP - , street_name = "Non existent" - , street_number = "Non existent" - , GLS.lines = Nothing - , building_name = Nothing - , building_number = Nothing - , zipcode = "Non existent" - , town_location = Nothing - , town_district = Nothing - , country_subdivision = Nothing - } - } diff --git a/test/Tests/Targets/Fake.hs b/test/Tests/Targets/Fake.hs @@ -0,0 +1,259 @@ +{-# LANGUAGE OverloadedStrings #-} + +module Tests.Targets.Fake + ( target_6 + , public_figure_1 + , public_figure_2 + , public_figure_3 + , public_figure_4 + , public_figure_5 + , imaginary_figure_1 + , imaginary_figure_2 + , imaginary_figure_3 + , imaginary_figure_4 + , imaginary_figure_5 + ) where + +import Data.CountryCodes +import Data.Time.Calendar + +import KYC.GLS.Type as GLS + + +-- target :: NaturalPerson +-- target = NaturalPerson +-- { full_name = +-- , last_name = +-- , birthdate = +-- , nationality = +-- , national_id = +-- , residential = GLS.Address { GLS.country = +-- , street_name = +-- , street_number = +-- , GLS.lines = +-- , building_name = +-- , building_number = +-- , zipcode = +-- , town_location = +-- , town_district = +-- , country_subdivision = + +public_figure_1 :: NaturalPerson +public_figure_1 = NaturalPerson + { full_name = "Georges Prosper Remi" + , last_name = "Remi" + , birthdate = YearMonthDay 1907 05 22 + , nationality = BE + , national_id = "012345ABCDEF" + , residential = GLS.Address { GLS.country = BE + , street_name = "Non existent" + , street_number = "Non existent" + , GLS.lines = Nothing + , building_name = Nothing + , building_number = Nothing + , zipcode = "Non existent" + , town_location = Just "Etterbeek" + , town_district = Just "Bruxelles" + , country_subdivision = Just "Brussels" + } + } + +public_figure_2 :: NaturalPerson +public_figure_2 = NaturalPerson + { full_name = "Jeffrey Preston Bezos" + , last_name = "Bezos" + , birthdate = YearMonthDay 1964 01 12 + , nationality = US + , national_id = "012345ABCDEF" + , residential = GLS.Address { GLS.country = US + , street_name = "Negra Arroyo Lane" + , street_number = "308" + , GLS.lines = Nothing + , building_name = Nothing + , building_number = Nothing + , zipcode = "87112" + , town_location = Just "Albuquerque" + , town_district = Just "Bernalillo" + , country_subdivision = Just "New Mexico" + } + } + +public_figure_3 :: NaturalPerson +public_figure_3 = NaturalPerson + { full_name = "Abraham Lincoln" + , last_name = "Lincoln" + , birthdate = YearMonthDay 1809 02 12 + , nationality = US + , national_id = "012345ABCDEF" + , residential = GLS.Address { GLS.country = US + , street_name = "Lincoln Farm Road" + , street_number = "2995" + , GLS.lines = Nothing + , building_name = Just "Abraham Lincoln Birthplace" + , building_number = Nothing + , zipcode = "42748" + , town_location = Just "Hodgenville" + , town_district = Just "LaRue" + , country_subdivision = Just "Kentucky" + } + } + +public_figure_4 :: NaturalPerson +public_figure_4 = NaturalPerson + { full_name = "Willem-Alexander Claus George Ferdinand van Oranje-Nassau" + , last_name = "van Oranje-Nassau" + , birthdate = YearMonthDay 1980 04 30 + , nationality = NL + , national_id = "012345ABCDEF" + , residential = GLS.Address { GLS.country = NL + , street_name = "'s-Gravenhaagse Bos" + , street_number = "10" + , GLS.lines = Nothing + , building_name = Just "Huis ten Bosch" + , building_number = Nothing + , zipcode = "2594BD" + , town_location = Just "'s-Gravenhage" + , town_district = Nothing + , country_subdivision = Just "Zuid-Holland" + } + } + +public_figure_5 :: NaturalPerson +public_figure_5 = NaturalPerson + { full_name = "Leonardo di ser Piero da Vinci" + , last_name = "da Vinci" + , birthdate = YearMonthDay 1452 04 15 + , nationality = IT + , national_id = "012345ABCDEF" + , residential = GLS.Address { GLS.country = IT + , street_name = "Non existent" + , street_number = "Non existent" + , GLS.lines = Nothing + , building_name = Nothing + , building_number = Nothing + , zipcode = "2594BD" + , town_location = Just "Vinci" + , town_district = Just "Florence" + , country_subdivision = Just "Tuscany" + } + } + +imaginary_figure_1 :: NaturalPerson +imaginary_figure_1 = NaturalPerson + { full_name = "Papa Smurf" + , last_name = "Smurf" + , birthdate = YearMonthDay 1958 10 23 + , nationality = FR + , national_id = "012345ABCDEF" + , residential = GLS.Address { GLS.country = FR + , street_name = "Non existent" + , street_number = "Non existent" + , GLS.lines = Nothing + , building_name = Nothing + , building_number = Nothing + , zipcode = "Non existent" + , town_location = Nothing + , town_district = Nothing + , country_subdivision = Just "Smurf Village" + } + } + +imaginary_figure_2 :: NaturalPerson +imaginary_figure_2 = NaturalPerson + { full_name = "Donald Fauntleroy Duck" + , last_name = "Duck" + , birthdate = YearMonthDay 1934 06 09 + , nationality = US + , national_id = "012345ABCDEF" + , residential = GLS.Address { GLS.country = US + , street_name = "South Harbor Boulevard" + , street_number = "1313" + , GLS.lines = Nothing + , building_name = Just "Disneyland" + , building_number = Nothing + , zipcode = "92802" + , town_location = Just "Anaheim" + , town_district = Just "Orange" + , country_subdivision = Just "California" + } + } + +imaginary_figure_3 :: NaturalPerson +imaginary_figure_3 = NaturalPerson + { full_name = "Willy Wonka" + , last_name = "Wonka" + , birthdate = YearMonthDay 1964 01 17 + , nationality = GB + , national_id = "012345ABCDEF" + , residential = GLS.Address { GLS.country = GB + , street_name = "Non existent" + , street_number = "Non existent" + , GLS.lines = Nothing + , building_name = Nothing + , building_number = Nothing + , zipcode = "Non existent" + , town_location = Just "Cardiff" + , town_district = Nothing + , country_subdivision = Just "Wales" + } + } + +imaginary_figure_4 :: NaturalPerson +imaginary_figure_4 = NaturalPerson + { full_name = "Bilbo Baggins" + , last_name = "Baggins" + , birthdate = YearMonthDay 1937 09 21 + , nationality = GB + , national_id = "012345ABCDEF" + , residential = GLS.Address { GLS.country = GB + , street_name = "Bagshot Row" + , street_number = "Non existent" + , GLS.lines = Nothing + , building_name = Just "Bag End" + , building_number = Nothing + , zipcode = "Non existent" + , town_location = Just "Hobbiton" + , town_district = Just "Westfarthing" + , country_subdivision = Just "The Shire" + } + } + +imaginary_figure_5 :: NaturalPerson +imaginary_figure_5 = NaturalPerson + { full_name = "Bruce Wayne" + , last_name = "Wayne" + , birthdate = YearMonthDay 1972 02 19 + , nationality = US + , national_id = "012345ABCDEF" + , residential = GLS.Address { GLS.country = US + , street_name = "Park Drive" + , street_number = "224" + , GLS.lines = Nothing + , building_name = Just "Wayne Manor" + , building_number = Nothing + , zipcode = "19007" + , town_location = Just "Bristol Township" + , town_district = Just "Bucks" + , country_subdivision = Just "Pennsylvania" + } + } + +target_6 :: NaturalPerson +target_6 = NaturalPerson + { full_name = "Bowser" + , last_name = "Bowser" + , birthdate = YearMonthDay 1985 09 13 + , nationality = JP + , national_id = "012345ABCDEF" + , residential = GLS.Address { GLS.country = JP + , street_name = "Non existent" + , street_number = "Non existent" + , GLS.lines = Nothing + , building_name = Nothing + , building_number = Nothing + , zipcode = "Non existent" + , town_location = Nothing + , town_district = Nothing + , country_subdivision = Nothing + } + } diff --git a/test/Tests/Targets/Real.hs b/test/Tests/Targets/Real.hs @@ -0,0 +1,259 @@ +{-# LANGUAGE OverloadedStrings #-} + +module Tests.Targets.Real + ( target_5144 + , target_5266 + , target_49816 + , target_43462 + , target_43616 + , target_43641 + , target_43718 + , target_43662 + , target_43611 + , target_29723 + , target_38925 + ) where + +import Data.CountryCodes +import Data.Time.Calendar + +import KYC.GLS.Type as GLS + + +-- target :: NaturalPerson +-- target = NaturalPerson +-- { full_name = +-- , last_name = +-- , birthdate = +-- , nationality = +-- , national_id = +-- , residential = GLS.Address { GLS.country = +-- , street_name = +-- , street_number = +-- , GLS.lines = +-- , building_name = +-- , building_number = +-- , zipcode = +-- , town_location = +-- , town_district = +-- , country_subdivision = + +target_5144 :: NaturalPerson +target_5144 = NaturalPerson + { full_name = "Dmitri Aliaksandravich Lukashenko" + , last_name = "Lukashenko" + , birthdate = YearMonthDay 1980 03 23 + , nationality = BY + , national_id = "012345ABCDEF" + , residential = GLS.Address { GLS.country = BY + , street_name = "ул. Старовиленская" + , street_number = "4" + , GLS.lines = Just "President's Sports Club" + , building_name = Nothing + , building_number = Nothing + , zipcode = "220029" + , town_location = Just "г. Минск" + , town_district = Nothing + , country_subdivision = Nothing + } + } + +target_5266 :: NaturalPerson +target_5266 = NaturalPerson + { full_name = "Natallia Alexeeuna Chatviartkova" + , last_name = "Chatviartkova" + , birthdate = YearMonthDay 1960 01 01 -- Made up birth date + , nationality = RU + , national_id = "012345ABCDEF" + , residential = GLS.Address { GLS.country = RU + , street_name = "Non existent" + , street_number = "Non existent" + , GLS.lines = Nothing + , building_name = Nothing + , building_number = Nothing + , zipcode = "Non existent" + , town_location = Nothing + , town_district = Nothing + , country_subdivision = Nothing + } + } + +target_49816 :: NaturalPerson +target_49816 = NaturalPerson + { full_name = "Vladimir Vladimirovich Putin" + , last_name = "Putin" + , birthdate = YearMonthDay 1952 10 07 + , nationality = RU + , national_id = "012345ABCDEF" + , residential = GLS.Address { GLS.country = RU + , street_name = "Инжирный переулок" + , street_number = "1" + , GLS.lines = Nothing + , building_name = Just "Bocharov Ruchey" + , building_number = Nothing + , zipcode = "354008" + , town_location = Just "Sochi" + , town_district = Just "Town district of Sochi" + , country_subdivision = Just "Krasnodar Krai" + } + } + +target_43462 :: NaturalPerson +target_43462 = NaturalPerson + { full_name = "Aleksandr Petrovich Barsukov" + , last_name = "Barsukov" + , birthdate = YearMonthDay 1965 04 29 + , nationality = BY + , national_id = "012345ABCDEF" + , residential = GLS.Address { GLS.country = BY + , street_name = "Non existent" + , street_number = "Non existent" + , GLS.lines = Nothing + , building_name = Nothing + , building_number = Nothing + , zipcode = "Non existent" + , town_location = Nothing + , town_district = Nothing + , country_subdivision = Nothing + } + } + +target_43616 :: NaturalPerson +target_43616 = NaturalPerson + { full_name = "Oleg Anatolievich Chernyshev" + , last_name = "Chernyshev" + , birthdate = YearMonthDay 1985 07 27 -- Made up birth date + , nationality = RU + , national_id = "012345ABCDEF" + , residential = GLS.Address { GLS.country = RU + , street_name = "Non existent" + , street_number = "Non existent" + , GLS.lines = Nothing + , building_name = Nothing + , building_number = Nothing + , zipcode = "Non existent" + , town_location = Nothing + , town_district = Nothing + , country_subdivision = Nothing + } + } + +target_43641 :: NaturalPerson +target_43641 = NaturalPerson + { full_name = "Vadzim Dzmitryevich Ipatau" + , last_name = "Ipatau" + , birthdate = YearMonthDay 1964 10 30 + , nationality = BY + , national_id = "012345ABCDEF" + , residential = GLS.Address { GLS.country = BY + , street_name = "Non existent" + , street_number = "Non existent" + , GLS.lines = Nothing + , building_name = Nothing + , building_number = Nothing + , zipcode = "Non existent" + , town_location = Nothing + , town_district = Nothing + , country_subdivision = Nothing + } + } + +target_43718 :: NaturalPerson +target_43718 = NaturalPerson + { full_name = "Irina Aliaksandrauna Tselikavets" + , last_name = "Tselikavets" + , birthdate = YearMonthDay 1976 11 02 + , nationality = BY + , national_id = "012345ABCDEF" + , residential = GLS.Address { GLS.country = BY + , street_name = "Non existent" + , street_number = "Non existent" + , GLS.lines = Nothing + , building_name = Nothing + , building_number = Nothing + , zipcode = "Non existent" + , town_location = Nothing + , town_district = Nothing + , country_subdivision = Nothing + } + } + +target_43662 :: NaturalPerson +target_43662 = NaturalPerson + { full_name = "Olga Leonidovna Doroshenko" + , last_name = "Doroshenko" + , birthdate = YearMonthDay 1976 09 02 -- Made up birth month and day + , nationality = BY + , national_id = "012345ABCDEF" + , residential = GLS.Address { GLS.country = BY + , street_name = "Non existent" + , street_number = "Non existent" + , GLS.lines = Nothing + , building_name = Nothing + , building_number = Nothing + , zipcode = "Non existent" + , town_location = Nothing + , town_district = Nothing + , country_subdivision = Nothing + } + } + +target_43611 :: NaturalPerson +target_43611 = NaturalPerson + { full_name = "Vladimir Viktorovich Kalach" + , last_name = "Kalach" + , birthdate = YearMonthDay 1960 12 22 -- Made up birth date + , nationality = BY + , national_id = "012345ABCDEF" + , residential = GLS.Address { GLS.country = BY + , street_name = "Non existent" + , street_number = "Non existent" + , GLS.lines = Nothing + , building_name = Nothing + , building_number = Nothing + , zipcode = "Non existent" + , town_location = Nothing + , town_district = Nothing + , country_subdivision = Nothing + } + } + +target_29723 :: NaturalPerson +target_29723 = NaturalPerson + { full_name = "Равиль Закариевич Халиков" + , last_name = "Халиков" + , birthdate = YearMonthDay 1969 02 23 + , nationality = RU + , national_id = "012345ABCDEF" + , residential = GLS.Address { GLS.country = RU + , street_name = "Non existent" + , street_number = "Non existent" + , GLS.lines = Nothing + , building_name = Nothing + , building_number = Nothing + , zipcode = "Non existent" + , town_location = Nothing + , town_district = Nothing + , country_subdivision = Nothing + } + } + +target_38925 :: NaturalPerson +target_38925 = NaturalPerson + { full_name = "Solomon Grundy" + , last_name = "Grundy" + , birthdate = YearMonthDay 1800 06 06 + , nationality = BE + , national_id = "012345ABCDEF" + , residential = GLS.Address { GLS.country = BE + , street_name = "Kryzhizhanovskogo str." + , street_number = "5A" + , GLS.lines = Nothing + , building_name = Nothing + , building_number = Just "64" + , zipcode = "Non existent" + , town_location = Just "Gresovskoe" + , town_district = Nothing + , country_subdivision = Nothing + } + }