{-# LANGUAGE QuasiQuotes, OverloadedStrings, UnicodeSyntax, CPP #-} module Data.Microformats2.ParserSpec (spec) where import Test.Hspec import TestCommon import Data.Default import Data.Time.Clock import Data.Time.Calendar import Data.Microformats2 import Data.Microformats2.Parser #if __GLASGOW_HASKELL__ < 709 import Control.Applicative #endif {-# ANN module ("HLint: ignore Redundant do"::String) #-} spec ∷ Spec spec = do describe "parseGeo" $ do let parseGeo' = parseGeo . documentRoot . parseLBS it "parses valid h-geo" $ do parseGeo' [xml|

37.33168 -122.03016 1.2345

|] `shouldBe` [ def { geoLatitude = pure 37.33168, geoLongitude = pure (-122.03016), geoAltitude = pure 1.2345 } , def { geoLatitude = [123.45, 678.9] } ] it "ignores invalid properties" $ do parseGeo' [xml|

HELLO WORLD!! 1.2345

|] `shouldBe` [ def { geoAltitude = pure 1.2345 } ] describe "parseAdr" $ do let parseAdr' = parseAdr . documentRoot . parseLBS it "parses valid h-adr" $ do parseAdr' [xml|
SA

EA

_ L R PC C LB G
|] `shouldBe` [ def { adrStreetAddress = pure "SA", adrExtendedAddress = pure "EA" , adrPostOfficeBox = pure "PO", adrLocality = pure "L" , adrRegion = pure "R", adrPostalCode = pure "PC" , adrCountryName = pure "C", adrLabel = pure "LB" , adrGeo = pure $ TextGeo "G" } ] it "parses p-geo" $ do parseAdr' [xml|
37.33168 -122.03016 1.2345
|] `shouldBe` [ def { adrGeo = [GeoGeo $ def { geoLatitude = pure 37.33168, geoLongitude = pure (-122.03016), geoAltitude = pure 1.2345 }] } ] it "ignores nested h-geo not marked as p-geo" $ do parseAdr' [xml|
1.2345
|] `shouldBe` [ def ] it "parses geo properties into p-geo" $ do parseAdr' [xml|
37.33168 -122.03016 1.2345
|] `shouldBe` [ def { adrGeo = [GeoGeo $ def { geoLatitude = pure 37.33168, geoLongitude = pure (-122.03016), geoAltitude = pure 1.2345 }] } ] describe "parseCard" $ do let parseCard' = parseCard . documentRoot . parseLBS it "parses valid h-card" $ do parseCard' [xml|

Joe Bloggs joebloggs@example.com,

|] `shouldBe` [ def { cardPhoto = pure "photo.png" , cardUrl = pure "http://example.org" , cardName = pure "Joe Bloggs" , cardEmail = pure "mailto:joebloggs@example.com" } ] it "parses valid implied h-card" $ do parseCard' [xml|
Joe Bloggs
|] `shouldBe` [ def { cardUrl = pure "http://example.org" , cardName = pure "Joe Bloggs" } , def { cardPhoto = pure "http://example.org/photo.jpg" }] it "parses p-adr" $ do parseCard' [xml|

17 Reykjavik Iceland

|] `shouldBe` [ def { cardAdr = pure (AdrAdr $ def { adrStreetAddress = pure "17" , adrLocality = pure "Reykjavik" , adrCountryName = pure "Iceland" }) } ] it "ignores nested h-adr not marked as p-adr" $ do parseCard' [xml|

Iceland

|] `shouldBe` [ def ] it "parses adr and geo properties into p-adr" $ do parseCard' [xml|

17 Reykjavik Iceland -122.03016

|] `shouldBe` [ def { cardAdr = pure (AdrAdr $ def { adrStreetAddress = pure "17" , adrLocality = pure "Reykjavik" , adrCountryName = pure "Iceland" , adrGeo = [ GeoGeo $ def { geoLongitude = pure (-122.03016) } ] }) } ] it "parses h-geo into p-adr" $ do parseCard' [xml|

-122.03016

|] `shouldBe` [ def { cardAdr = pure (AdrAdr $ def { adrGeo = [ GeoGeo $ def { geoLongitude = pure (-122.03016) } ] }) } ] it "ignores nested h-geo not marked as p-geo" $ do parseCard' [xml|

-122.03016

|] `shouldBe` [ def ] it "parses multiple things into p-adr" $ do parseCard' [xml|

-122.03016

-122.03016 Iceland

Reykjavik

|] `shouldBe` [ def { cardAdr = [ (AdrAdr $ def { adrCountryName = pure "Iceland" , adrGeo = [ GeoGeo $ def { geoAltitude = pure (-122.03016) } , GeoGeo $ def { geoLongitude = pure (-122.03016) } ] }) , (AdrAdr $ def { adrLocality = pure "Reykjavik" }) ]} ] it "parses p-org" $ do parseCard' [xml|

IndieWebCamp

Microformats
|] `shouldBe` [ def { cardOrg = [ TextCard "Microformats" , (CardCard $ def { cardName = pure "IndieWebCamp" }) ] } , def { cardName = pure "IndieWebCamp" }] describe "parseCite" $ do let parseCite' = parseCite Strip . documentRoot . parseLBS it "parses valid h-cite" $ do parseCite' [xml|
Rails is Omakase DHH

Rails is not that. Rails is omakase...

|] `shouldBe` [ def { citeName = pure "Rails is Omakase" , citeUrl = pure "https://youtu.be/E99FnoYqoII" , citeUid = pure "https://youtu.be/E99FnoYqoII" , citeAuthor = pure $ CardCard $ def { cardName = pure "DHH" } , citeContent = pure $ TextContent "Rails is not that. Rails is omakase..." , citePublished = pure $ UTCTime (fromGregorian 2013 1 25) (secondsToDiffTime 0) } ] describe "parseEntry" $ do let parseEntry' m = parseEntry m . documentRoot . parseLBS it "parses valid h-entry" $ do parseEntry' Strip [xml|
Rails is Omakase DHH DHH David

Rails is not that. Rails is omakase...

|] `shouldBe` [ def { entryName = pure "Rails is Omakase" , entryUrl = pure "https://youtu.be/E99FnoYqoII" , entryUid = pure "https://youtu.be/E99FnoYqoII" , entryAuthor = [ TextCard "David" , CardCard $ def { cardName = pure "DHH" } , CardCard $ def { cardName = pure "DHH", cardUrl = pure "http://david.heinemeierhansson.com" } ] , entryContent = pure $ TextContent "Rails is not that. Rails is omakase..." , entryPublished = pure $ UTCTime (fromGregorian 2013 1 25) (secondsToDiffTime 0) , entryUpdated = pure $ UTCTime (fromGregorian 2013 1 25) (secondsToDiffTime 4980) } ] it "supports different html content modes" $ do let src = [xml|

Rails is not that. Rails is omakase...

|] parseEntry' Unsafe src `shouldBe` [ def { entryContent = pure $ TextContent "Rails is not that. Rails is omakase..." } ] parseEntry' Strip src `shouldBe` [ def { entryContent = pure $ TextContent "alert('XSS')Rails is not that. Rails is omakase..." } ] parseEntry' Escape src `shouldBe` [ def { entryContent = pure $ TextContent "<script>alert('XSS')</script><a href=\"http://rubyonrails.org\" onclick=\"alert()\">Rails</a> is not that. Rails is omakase..." } ] parseEntry' Sanitize src `shouldBe` [ def { entryContent = pure $ TextContent "Rails is not that. Rails is omakase..." } ] it "parses p-location" $ do parseEntry' Strip [xml|

Pen Island

USA

|] `shouldBe` [ def { entryLocation = [ CardLoc $ def { cardName = pure "Pen Island", cardUrl = pure "http://penisland.net" } , AdrLoc $ def { adrCountryName = pure "USA" } , GeoLoc $ def { geoLatitude = pure 123.45 } ] } ]