From 6ce74cab3ebbab63eddac37daddb2c5bf83d6a76 Mon Sep 17 00:00:00 2001 From: nikola Date: Fri, 8 Jul 2022 13:27:00 +0300 Subject: [PATCH] fix cvc validation --- .gitignore | 2 ++ spec/CreditCardSpec.hs | 27 +++++++++++++++++++++++++ src/Data/CreditCard.hs | 3 +-- stack.yaml.lock | 45 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 2 deletions(-) create mode 100644 .gitignore create mode 100644 stack.yaml.lock diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..186eb6c --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.stack-work +.hie-yaml diff --git a/spec/CreditCardSpec.hs b/spec/CreditCardSpec.hs index aa45e6a..8ba8946 100644 --- a/spec/CreditCardSpec.hs +++ b/spec/CreditCardSpec.hs @@ -72,6 +72,29 @@ wrongNumbers = , "353011133330000" , "3566002028360505" ] +correctCvc :: [Text] +correctCvc = + [ "311" + , "3211" + , "9999" + , "0000" + , "000" + , "1234" + , "111" + ] + +wrongCvc :: [Text] +wrongCvc = + [ "31111" + , "a31" + , "zzz" + , "00O" + , "000O" + , "OOO" + , "11111" + , "11" + ] + checkNumbers :: [Text] -> CreditCardType -> Spec checkNumbers ns t = describe (show t) $ do for_ ns $ \n -> it (T.unpack n) $ do @@ -94,3 +117,7 @@ spec = describe "Credit card number validation" $ do (parseExpirationDate . formatExpiryDate) d == Just d prop "JSON instances isomorphism" $ \(cc :: CreditCard) -> (decode . encode) cc == Just cc + it "Wrong CVC" $ for_ wrongCvc $ \cvc -> do + parseCreditCardSecurity cvc `shouldBe` Nothing + it "Correct CVC" $ for_ correctCvc $ \cvc -> do + parseCreditCardSecurity cvc `shouldBe` Just (CreditCardSecurity cvc) diff --git a/src/Data/CreditCard.hs b/src/Data/CreditCard.hs index 5e27999..ab5c968 100644 --- a/src/Data/CreditCard.hs +++ b/src/Data/CreditCard.hs @@ -54,7 +54,6 @@ import Control.Lens hiding (elements) import Control.Monad (guard) import Data.Aeson as Aeson import Data.Aeson.Inflections (defaultFieldLabelModifier) -import Data.Aeson.Types (withText) import Data.Char (isDigit) import Data.Digit import Data.Either (isRight) @@ -245,7 +244,7 @@ parseCreditCardSecurity txt | otherwise = Nothing where isValid = and - [ T.length txt == 3 + [ (3, 4) `inRange` T.length txt , T.all isDigit txt ] data CreditCard = CreditCard diff --git a/stack.yaml.lock b/stack.yaml.lock new file mode 100644 index 0000000..04faef3 --- /dev/null +++ b/stack.yaml.lock @@ -0,0 +1,45 @@ +# This file was autogenerated by Stack. +# You should not edit this file by hand. +# For more information, please see the documentation at: +# https://docs.haskellstack.org/en/stable/lock_files + +packages: +- completed: + name: aeson-inflections + version: 0.1.0.0 + git: https://github.com/typeable/aeson-inflections + pantry-tree: + size: 305 + sha256: 306e91dd974dae0170d0b7cf7b74769782b4d4342575a2e39d82224ac69d6dad + commit: 66ac49cc1e468f36bf9d6c78b73bdabcfca0855d + original: + git: https://github.com/typeable/aeson-inflections + commit: 66ac49cc1e468f36bf9d6c78b73bdabcfca0855d +- completed: + name: digit + version: 0.1.0.0 + git: https://github.com/typeable/digit.git + pantry-tree: + size: 314 + sha256: 41a3214a12218a1cf85baa3dc33292491b662c32218ba88ce0f0e27478e1d78c + commit: e03f087c90c9228a9ae52a0e516eba22589eef94 + original: + git: https://github.com/typeable/digit.git + commit: e03f087c90c9228a9ae52a0e516eba22589eef94 +- completed: + name: missing-lens + version: 0.1.0.0 + git: https://github.com/typeable/missing-lens.git + pantry-tree: + size: 221 + sha256: ab572e39921e6f367dbc4b0a8df29fa170dc4ab015e407c4dfe03d84d07665ec + commit: 328659fdda8fd7ec509abfab6298775062fc2926 + original: + git: https://github.com/typeable/missing-lens.git + commit: 328659fdda8fd7ec509abfab6298775062fc2926 +snapshots: +- completed: + size: 616897 + url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/19/0.yaml + sha256: bbf2be02f17940bac1f87cb462d4fb0c3355de6dcfc53d84f4f9ad3ee2164f65 + original: lts-19.0