packages feed

wai-middleware-rollbar 0.3.0 → 0.4.0

raw patch · 21 files changed

+315/−127 lines, 21 filesdep +hspecdep +hspec-golden-aesondep ~QuickCheckdep ~aesondep ~http-clientPVP ok

version bump matches the API change (PVP)

Dependencies added: hspec, hspec-golden-aeson

Dependency ranges changed: QuickCheck, aeson, http-client, http-conduit, lens

API changes (from Hackage documentation)

+ Rollbar.AccessToken: instance Data.Aeson.Types.FromJSON.FromJSON Rollbar.AccessToken.AccessToken
+ Rollbar.Item: instance Data.Aeson.Types.FromJSON.FromJSON a => Data.Aeson.Types.FromJSON.FromJSON (Rollbar.Item.Item a headers)
+ Rollbar.Item.Body: instance Data.Aeson.Types.FromJSON.FromJSON Rollbar.Item.Body.MessageBody
+ Rollbar.Item.Body: instance Data.Aeson.Types.FromJSON.FromJSON arbitrary => Data.Aeson.Types.FromJSON.FromJSON (Rollbar.Item.Body.Body arbitrary)
+ Rollbar.Item.CodeVersion: instance Data.Aeson.Types.FromJSON.FromJSON Rollbar.Item.CodeVersion.CodeVersion
+ Rollbar.Item.Data: instance Data.Aeson.Types.FromJSON.FromJSON Rollbar.Item.Data.Context
+ Rollbar.Item.Data: instance Data.Aeson.Types.FromJSON.FromJSON Rollbar.Item.Data.Fingerprint
+ Rollbar.Item.Data: instance Data.Aeson.Types.FromJSON.FromJSON Rollbar.Item.Data.Framework
+ Rollbar.Item.Data: instance Data.Aeson.Types.FromJSON.FromJSON Rollbar.Item.Data.Title
+ Rollbar.Item.Data: instance Data.Aeson.Types.FromJSON.FromJSON Rollbar.Item.Data.UUID4
+ Rollbar.Item.Data: instance Data.Aeson.Types.FromJSON.FromJSON body => Data.Aeson.Types.FromJSON.FromJSON (Rollbar.Item.Data.Data body headers)
+ Rollbar.Item.Environment: instance Data.Aeson.Types.FromJSON.FromJSON Rollbar.Item.Environment.Environment
+ Rollbar.Item.Hardcoded: instance GHC.TypeLits.KnownSymbol symbol => Data.Aeson.Types.FromJSON.FromJSON (Rollbar.Item.Hardcoded.Hardcoded symbol)
+ Rollbar.Item.Internal.Notifier: instance Data.Aeson.Types.FromJSON.FromJSON Rollbar.Item.Internal.Notifier.Notifier
+ Rollbar.Item.Internal.Platform: instance Data.Aeson.Types.FromJSON.FromJSON Rollbar.Item.Internal.Platform.Platform
+ Rollbar.Item.Level: instance Data.Aeson.Types.FromJSON.FromJSON Rollbar.Item.Level.Level
+ Rollbar.Item.MissingHeaders: instance Data.Aeson.Types.FromJSON.FromJSON (Rollbar.Item.MissingHeaders.MissingHeaders headers)
+ Rollbar.Item.Person: instance Data.Aeson.Types.FromJSON.FromJSON Rollbar.Item.Person.Email
+ Rollbar.Item.Person: instance Data.Aeson.Types.FromJSON.FromJSON Rollbar.Item.Person.Id
+ Rollbar.Item.Person: instance Data.Aeson.Types.FromJSON.FromJSON Rollbar.Item.Person.Person
+ Rollbar.Item.Person: instance Data.Aeson.Types.FromJSON.FromJSON Rollbar.Item.Person.Username
+ Rollbar.Item.Request: instance Data.Aeson.Types.FromJSON.FromJSON (Rollbar.Item.Request.Request headers)
+ Rollbar.Item.Request: instance Data.Aeson.Types.FromJSON.FromJSON Rollbar.Item.Request.Get
+ Rollbar.Item.Request: instance Data.Aeson.Types.FromJSON.FromJSON Rollbar.Item.Request.IP
+ Rollbar.Item.Request: instance Data.Aeson.Types.FromJSON.FromJSON Rollbar.Item.Request.Method
+ Rollbar.Item.Request: instance Data.Aeson.Types.FromJSON.FromJSON Rollbar.Item.Request.QueryString
+ Rollbar.Item.Request: instance Data.Aeson.Types.FromJSON.FromJSON Rollbar.Item.Request.RawBody
+ Rollbar.Item.Request: instance Data.Aeson.Types.FromJSON.FromJSON Rollbar.Item.Request.URL
+ Rollbar.Item.Server: instance Data.Aeson.Types.FromJSON.FromJSON Rollbar.Item.Server.Branch
+ Rollbar.Item.Server: instance Data.Aeson.Types.FromJSON.FromJSON Rollbar.Item.Server.Root
+ Rollbar.Item.Server: instance Data.Aeson.Types.FromJSON.FromJSON Rollbar.Item.Server.Server

Files

src/Rollbar/AccessToken.hs view
@@ -13,7 +13,7 @@     ( AccessToken(..)     ) where -import Data.Aeson  (ToJSON)+import Data.Aeson  (FromJSON, ToJSON) import Data.String (IsString)  import qualified Data.Text as T@@ -21,4 +21,4 @@ -- | Should have the scope "post_server_item". newtype AccessToken     = AccessToken T.Text-    deriving (Eq, IsString, Show, ToJSON)+    deriving (Eq, FromJSON, IsString, Show, ToJSON)
src/Rollbar/Item.hs view
@@ -85,9 +85,22 @@     , Root(..)     ) where -import Data.Aeson   (KeyValue, ToJSON, object, pairs, toEncoding, toJSON, (.=))-import Data.Maybe   (fromMaybe)-import Data.Version (showVersion)+import Data.Aeson+    ( FromJSON+    , KeyValue+    , ToJSON+    , Value(Object)+    , object+    , pairs+    , parseJSON+    , toEncoding+    , toJSON+    , (.:)+    , (.=)+    )+import Data.Aeson.Types (typeMismatch)+import Data.Maybe       (fromMaybe)+import Data.Version     (showVersion)  import GHC.Generics (Generic) @@ -194,6 +207,10 @@     [ "access_token" .= accessToken     , "data" .= itemData     ]++instance FromJSON a => FromJSON (Item a headers) where+    parseJSON (Object o) = Item <$> o .: "access_token" <*> o .: "data"+    parseJSON v          = typeMismatch "Item a headers" v  instance (RemoveHeaders headers, ToJSON a) => ToJSON (Item a headers) where     toJSON = object . itemKVs
src/Rollbar/Item/Body.hs view
@@ -20,8 +20,20 @@     ) where  import Data.Aeson-    (KeyValue, ToJSON, object, pairs, toEncoding, toJSON, (.=))+    ( FromJSON+    , KeyValue+    , ToJSON+    , Value(Object)+    , object+    , pairs+    , parseJSON+    , toEncoding+    , toJSON+    , (.:)+    , (.=)+    ) import Data.Aeson.Encoding (pair)+import Data.Aeson.Types    (typeMismatch) import Data.String         (IsString)  import GHC.Generics (Generic)@@ -46,6 +58,12 @@     , "data" .= messageData     ] +instance FromJSON arbitrary => FromJSON (Body arbitrary) where+    parseJSON (Object o') = do+        o <- o' .: "message"+        Message <$> o .: "body" <*> o .: "data"+    parseJSON v = typeMismatch "Body arbitrary" v+ instance ToJSON arbitrary => ToJSON (Body arbitrary) where     toJSON x = object ["message" .= object (bodyKVs x)]     toEncoding = pairs . pair "message" . pairs . mconcat . bodyKVs@@ -53,4 +71,4 @@ -- | The primary message text to send to Rollbar. newtype MessageBody     = MessageBody T.Text-    deriving (Eq, IsString, Show, ToJSON)+    deriving (Eq, FromJSON, IsString, Show, ToJSON)
src/Rollbar/Item/CodeVersion.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE OverloadedStrings #-}  {-|     Module      : Rollbar.Item.CodeVersion@@ -13,11 +14,13 @@     ( CodeVersion(..)     ) where -import Data.Aeson (ToJSON, toEncoding, toJSON)+import Data.Aeson       (FromJSON, ToJSON, parseJSON, toEncoding, toJSON)+import Data.Aeson.Types (typeMismatch)  import GHC.Generics (Generic) -import qualified Data.Text as T+import qualified Data.Aeson as A+import qualified Data.Text  as T  -- | Rollbar supports different ways to say what version the code is. data CodeVersion@@ -34,6 +37,13 @@ prettyCodeVersion (SemVer s) = s prettyCodeVersion (Number n) = T.pack . show $ n prettyCodeVersion (SHA h)    = h++instance FromJSON CodeVersion where+    parseJSON (A.String s) = case T.splitOn "." s of+        [_major, _minor, _patch] -> pure $ SemVer s+        _                        -> pure $ SHA s+    parseJSON (A.Number n) = pure $ Number $ floor n+    parseJSON v = typeMismatch "CodeVersion" v  instance ToJSON CodeVersion where     toJSON = toJSON . prettyCodeVersion
src/Rollbar/Item/Data.hs view
@@ -27,18 +27,22 @@     ) where  import Data.Aeson-    ( ToJSON-    , Value+    ( FromJSON+    , ToJSON+    , Value(String)     , defaultOptions+    , genericParseJSON     , genericToEncoding     , genericToJSON+    , parseJSON     , toEncoding     , toJSON     )-import Data.Aeson.Types (fieldLabelModifier, omitNothingFields)+import Data.Aeson.Types+    (Options, fieldLabelModifier, omitNothingFields, typeMismatch) import Data.String      (IsString) import Data.Time        (UTCTime)-import Data.UUID        (UUID, toText)+import Data.UUID        (UUID, fromText, toText)  import GHC.Generics (Generic) @@ -87,16 +91,19 @@         }     deriving (Eq, Generic, Show) +instance FromJSON body => FromJSON (Data body headers) where+    parseJSON = genericParseJSON options+ instance (RemoveHeaders headers, ToJSON body) => ToJSON (Data body headers) where-    toJSON = genericToJSON defaultOptions-        { fieldLabelModifier = codeVersionModifier-        , omitNothingFields = True-        }-    toEncoding = genericToEncoding defaultOptions-        { fieldLabelModifier = codeVersionModifier-        , omitNothingFields = True-        }+    toJSON = genericToJSON options+    toEncoding = genericToEncoding options +options :: Options+options = defaultOptions+    { fieldLabelModifier = codeVersionModifier+    , omitNothingFields = True+    }+ codeVersionModifier :: (Eq s, IsString s) => s -> s codeVersionModifier = \case     "codeVersion" -> "code_version"@@ -106,27 +113,32 @@ --  E.g. "scotty", "servant", "yesod" newtype Framework     = Framework T.Text-    deriving (Eq, IsString, Show, ToJSON)+    deriving (Eq, FromJSON, IsString, Show, ToJSON)  -- | The place in the code where this item came from. newtype Context     = Context T.Text-    deriving (Eq, IsString, Show, ToJSON)+    deriving (Eq, FromJSON, IsString, Show, ToJSON)  -- | How to group the item. newtype Fingerprint     = Fingerprint T.Text-    deriving (Eq, IsString, Show, ToJSON)+    deriving (Eq, FromJSON, IsString, Show, ToJSON)  -- | The title of the item. newtype Title     = Title T.Text-    deriving (Eq, IsString, Show, ToJSON)+    deriving (Eq, FromJSON, IsString, Show, ToJSON)  -- | A unique identifier for each item. newtype UUID4     = UUID4 UUID     deriving (Eq, Generic, Show)++instance FromJSON UUID4 where+    parseJSON v@(String s) =+        maybe (typeMismatch "UUID4" v) (pure . UUID4) $ fromText s+    parseJSON v = typeMismatch "UUID4" v  instance ToJSON UUID4 where     toJSON (UUID4 u) = toJSON (toText u)
src/Rollbar/Item/Environment.hs view
@@ -13,7 +13,7 @@     ( Environment(..)     ) where -import Data.Aeson  (ToJSON)+import Data.Aeson  (FromJSON, ToJSON) import Data.String (IsString)  import qualified Data.Text as T@@ -22,4 +22,4 @@ --  E.g. "development", "production", "staging" newtype Environment     = Environment T.Text-    deriving (Eq, IsString, Show, ToJSON)+    deriving (Eq, FromJSON, IsString, Show, ToJSON)
src/Rollbar/Item/Hardcoded.hs view
@@ -1,6 +1,7 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE KindSignatures #-}+{-# LANGUAGE ScopedTypeVariables #-}  {-|     Module      : Rollbar.Item.Hardcoded@@ -17,7 +18,10 @@     ( Hardcoded(..)     ) where -import Data.Aeson (ToJSON, toEncoding, toJSON)+import Data.Aeson+    (FromJSON, ToJSON, Value(String), parseJSON, toEncoding, toJSON)+import Data.Aeson.Types (typeMismatch)+import Data.Text        (pack)  import GHC.Generics (Generic) import GHC.TypeLits (KnownSymbol, Symbol, symbolVal)@@ -31,3 +35,8 @@ instance KnownSymbol symbol => ToJSON (Hardcoded symbol) where     toJSON = toJSON . symbolVal     toEncoding = toEncoding . symbolVal++instance KnownSymbol symbol => FromJSON (Hardcoded symbol) where+    parseJSON (String str)+        | str == pack (symbolVal (Hardcoded :: Hardcoded symbol)) = pure Hardcoded+    parseJSON v = typeMismatch "Hardcoded symbol" v
src/Rollbar/Item/Internal/Notifier.hs view
@@ -17,7 +17,8 @@     ( Notifier(..)     ) where -import Data.Aeson   (ToJSON, defaultOptions, genericToEncoding, toEncoding)+import Data.Aeson+    (FromJSON, ToJSON, defaultOptions, genericToEncoding, toEncoding) import Data.Version (Version)  import GHC.Generics (Generic)@@ -34,5 +35,6 @@         }     deriving (Eq, Generic, Show) +instance FromJSON Notifier instance ToJSON Notifier where     toEncoding = genericToEncoding defaultOptions
src/Rollbar/Item/Internal/Platform.hs view
@@ -15,7 +15,7 @@     ( Platform(..)     ) where -import Data.Aeson  (ToJSON)+import Data.Aeson  (FromJSON, ToJSON) import Data.String (IsString)  import qualified Data.Text as T@@ -23,4 +23,4 @@ -- | Should be something meaningful to rollbar, like "linux". newtype Platform     = Platform T.Text-    deriving (Eq, IsString, Show, ToJSON)+    deriving (Eq, FromJSON, IsString, Show, ToJSON)
src/Rollbar/Item/Level.hs view
@@ -14,14 +14,17 @@     ) where  import Data.Aeson-    ( ToJSON+    ( FromJSON+    , ToJSON     , defaultOptions+    , genericParseJSON     , genericToEncoding     , genericToJSON+    , parseJSON     , toEncoding     , toJSON     )-import Data.Aeson.Types (constructorTagModifier)+import Data.Aeson.Types (Options, constructorTagModifier) import Data.Char        (toLower)  import GHC.Generics (Generic)@@ -35,10 +38,14 @@     | Critical     deriving (Bounded, Enum, Eq, Generic, Ord, Show) +instance FromJSON Level where+    parseJSON = genericParseJSON options+ instance ToJSON Level where-    toJSON = genericToJSON defaultOptions-        { constructorTagModifier = fmap toLower-        }-    toEncoding = genericToEncoding defaultOptions-        { constructorTagModifier = fmap toLower-        }+    toJSON = genericToJSON options+    toEncoding = genericToEncoding options++options :: Options+options = defaultOptions+    { constructorTagModifier = fmap toLower+    }
src/Rollbar/Item/MissingHeaders.hs view
@@ -18,7 +18,9 @@     , RemoveHeaders     ) where -import Data.Aeson           (KeyValue, ToJSON, object, toJSON, (.=))+import Data.Aeson+    (FromJSON, KeyValue, ToJSON, object, parseJSON, toJSON, (.=))+import Data.Bifunctor       (bimap) import Data.CaseInsensitive (mk, original) import Data.Maybe           (catMaybes) import Data.Proxy           (Proxy(Proxy))@@ -54,6 +56,9 @@         where         go (rh, _) =             rh /= (mk . BSC8.pack $ symbolVal (Proxy :: Proxy header))++instance FromJSON (MissingHeaders headers) where+    parseJSON v = MissingHeaders . fmap (bimap (mk . BS.pack) BS.pack) <$> parseJSON v  instance RemoveHeaders headers => ToJSON (MissingHeaders headers) where     toJSON = object . catMaybes . requestHeadersKVs . removeHeaders
src/Rollbar/Item/Person.hs view
@@ -19,7 +19,8 @@     ) where  import Data.Aeson-    ( ToJSON+    ( FromJSON+    , ToJSON     , defaultOptions     , genericToEncoding     , genericToJSON@@ -45,6 +46,7 @@         }     deriving (Eq, Generic, Show) +instance FromJSON Person instance ToJSON Person where     toJSON = genericToJSON defaultOptions { omitNothingFields = True }     toEncoding = genericToEncoding defaultOptions { omitNothingFields = True }@@ -52,14 +54,14 @@ -- | The user's identifier. This uniquely identifies a 'Person' to Rollbar. newtype Id     = Id T.Text-    deriving (Eq, IsString, Show, ToJSON)+    deriving (Eq, FromJSON, IsString, Show, ToJSON)  -- | The user's name. newtype Username     = Username T.Text-    deriving (Eq, IsString, Show, ToJSON)+    deriving (Eq, FromJSON, IsString, Show, ToJSON)  -- | The user's email. newtype Email     = Email T.Text-    deriving (Eq, IsString, Show, ToJSON)+    deriving (Eq, FromJSON, IsString, Show, ToJSON)
src/Rollbar/Item/Request.hs view
@@ -25,17 +25,33 @@     , RemoveHeaders     ) where -import Data.Aeson  (KeyValue, ToJSON, object, pairs, toEncoding, toJSON, (.=))-import Data.Maybe  (catMaybes, fromMaybe)-import Data.String (IsString)+import Data.Aeson+    ( FromJSON+    , KeyValue+    , ToJSON+    , Value(Object, String)+    , object+    , pairs+    , parseJSON+    , toEncoding+    , toJSON+    , (.:)+    , (.=)+    )+import Data.Aeson.Types (typeMismatch)+import Data.Bifunctor   (bimap)+import Data.Maybe       (catMaybes, fromMaybe)+import Data.String      (IsString)  import GHC.Generics (Generic)  import Network.HTTP.Types (Query)-import Network.Socket     (SockAddr)+import Network.Socket     (SockAddr(SockAddrInet), tupleToHostAddress)  import Rollbar.Item.MissingHeaders +import Text.Read (readMaybe)+ import qualified Data.ByteString    as BS import qualified Data.Text          as T import qualified Data.Text.Encoding as TE@@ -61,6 +77,9 @@     = RawBody BS.ByteString     deriving (Eq, Generic, IsString, Show) +instance FromJSON RawBody where+    parseJSON v = RawBody . BS.pack <$> parseJSON v+ instance ToJSON RawBody where     toJSON (RawBody body) = toJSON (myDecodeUtf8 body)     toEncoding (RawBody body) = toEncoding (myDecodeUtf8 body)@@ -70,6 +89,9 @@     = Get Query     deriving (Eq, Generic, Show) +instance FromJSON Get where+    parseJSON v = Get . fmap (bimap BS.pack (fmap BS.pack)) <$> parseJSON v+ instance ToJSON Get where     toJSON (Get q) = object . catMaybes . queryKVs $ q     toEncoding (Get q) = pairs . mconcat . catMaybes . queryKVs $ q@@ -88,6 +110,9 @@     = Method BS.ByteString     deriving (Eq, Generic, Show) +instance FromJSON Method where+    parseJSON v = Method . BS.pack <$> parseJSON v+ instance ToJSON Method where     toJSON (Method q) = toJSON (myDecodeUtf8 q)     toEncoding (Method q) = toEncoding (myDecodeUtf8 q)@@ -97,6 +122,9 @@     = QueryString BS.ByteString     deriving (Eq, Generic, Show) +instance FromJSON QueryString where+    parseJSON v = QueryString . BS.pack <$> parseJSON v+ instance ToJSON QueryString where     toJSON (QueryString q) = toJSON (myDecodeUtf8' q)     toEncoding (QueryString q) = toEncoding (myDecodeUtf8' q)@@ -106,6 +134,17 @@     = IP SockAddr     deriving (Eq, Generic, Show) +instance FromJSON IP where+    parseJSON v@(String s) = case T.splitOn "." s of+        [a', b', c', d] -> case T.splitOn ":" d of+            [e', f'] -> maybe (typeMismatch "IP" v) pure $ do+                [a, b, c, e] <- traverse (readMaybe . T.unpack) [a', b', c', e']+                f <- (readMaybe . T.unpack) f'+                pure . IP . SockAddrInet f $ tupleToHostAddress (a, b, c, e)+            _ -> typeMismatch "IP" v+        _ -> typeMismatch "IP" v+    parseJSON v = typeMismatch "IP" v+ instance ToJSON IP where     toJSON (IP ip) = toJSON (show ip)     toEncoding (IP ip) = toEncoding (show ip)@@ -121,6 +160,18 @@     , "user_ip" .= userIP     ] +instance FromJSON (Request headers) where+    parseJSON (Object o) =+        Request+            <$> o .: "body"+            <*> o .: "GET"+            <*> o .: "headers"+            <*> o .: "method"+            <*> o .: "query_string"+            <*> o .: "url"+            <*> o .: "user_ip"+    parseJSON v = typeMismatch "Request headers" v+ instance (RemoveHeaders headers) => ToJSON (Request headers) where     toJSON = object . requestKVs     toEncoding = pairs . mconcat . requestKVs@@ -133,6 +184,12 @@ prettyURL :: URL -> T.Text prettyURL (URL (host, parts)) =     T.intercalate "/" (fromMaybe "" (host >>= myDecodeUtf8) : parts)++instance FromJSON URL where+    parseJSON (String s) = case T.splitOn "/" s of+        host:parts | "http" `T.isPrefixOf` host -> pure $ URL (Just $ TE.encodeUtf8 host, parts)+        parts -> pure $ URL (Nothing, parts)+    parseJSON v       = typeMismatch "URL" v  instance ToJSON URL where     toJSON = toJSON . prettyURL
src/Rollbar/Item/Server.hs view
@@ -18,9 +18,22 @@     , Branch(..)     ) where -import Data.Aeson  (KeyValue, ToJSON, object, pairs, toEncoding, toJSON, (.=))-import Data.Maybe  (catMaybes)-import Data.String (IsString)+import Data.Aeson+    ( FromJSON+    , KeyValue+    , ToJSON+    , Value(Object)+    , object+    , pairs+    , parseJSON+    , toEncoding+    , toJSON+    , (.:)+    , (.=)+    )+import Data.Aeson.Types (typeMismatch)+import Data.Maybe       (catMaybes)+import Data.String      (IsString)  import GHC.Generics (Generic) @@ -52,6 +65,15 @@     , ("code_version" .=) <$> serverCodeVersion     ] +instance FromJSON Server where+    parseJSON (Object o) =+        Server+            <$> o .: "host"+            <*> o .: "root"+            <*> o .: "branch"+            <*> o .: "code_version"+    parseJSON v = typeMismatch "Server" v+ instance ToJSON Server where     toJSON = object . catMaybes . serverKVs     toEncoding = pairs . mconcat . catMaybes . serverKVs@@ -59,9 +81,9 @@ -- | The root directory. newtype Root     = Root T.Text-    deriving (Eq, IsString, Show, ToJSON)+    deriving (Eq, FromJSON, IsString, Show, ToJSON)  -- | The git branch the server is running on. newtype Branch     = Branch T.Text-    deriving (Eq, IsString, Show, ToJSON)+    deriving (Eq, FromJSON, IsString, Show, ToJSON)
test/Main.hs view
@@ -1,14 +1,14 @@ {-# LANGUAGE OverloadedStrings #-} module Main where -import Test.QuickCheck (conjoin, quickCheck)-+import qualified Rollbar.Golden import qualified Rollbar.Item.Data.Test import qualified Rollbar.Item.MissingHeaders.Test import qualified Rollbar.Item.Request.Test  main :: IO () main = do+    Rollbar.Golden.main     Rollbar.Item.Data.Test.props     Rollbar.Item.MissingHeaders.Test.props     Rollbar.Item.Request.Test.props
+ test/Rollbar/Golden.hs view
@@ -0,0 +1,14 @@+{-# LANGUAGE DataKinds #-}+module Rollbar.Golden where++import Data.Proxy (Proxy(Proxy))++import Rollbar.Item       (Item)+import Rollbar.QuickCheck ()++import Test.Aeson.GenericSpecs (roundtripAndGoldenSpecs)+import Test.Hspec              (hspec)++main :: IO ()+main =+  hspec $ roundtripAndGoldenSpecs (Proxy :: Proxy (Item () '["Authorization"]))
test/Rollbar/Item/Data/Test.hs view
@@ -1,5 +1,4 @@ {-# LANGUAGE DataKinds #-}-{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE OverloadedStrings #-} module Rollbar.Item.Data.Test where @@ -7,14 +6,12 @@  import Data.Aeson      (encode, toJSON) import Data.Aeson.Lens (key, members)-import Data.Text       (Text, pack)--import Prelude hiding (error)+import Data.Text       (Text)  import Rollbar.Item+import Rollbar.QuickCheck () -import Test.QuickCheck-    (Arbitrary, Property, arbitrary, conjoin, elements, quickCheck)+import Test.QuickCheck (conjoin, quickCheck)  props :: IO () props =@@ -34,16 +31,6 @@     length ms == 1 && fst (head ms) `elem` requiredBodyKeys     where     ms = encode x ^@.. key "body" . members--instance Arbitrary a => Arbitrary (Data a '["Authorization"]) where-    arbitrary = do-        env <- Environment . pack <$> arbitrary-        message <- fmap (MessageBody . pack) <$> arbitrary-        payload <- arbitrary-        elements $ (\f -> f env message payload) <$> datas--datas :: [Environment -> Maybe MessageBody -> a -> Data a '["Authorization"]]-datas = [debug, info, warning, error, critical]  requiredBodyKeys :: [Text] requiredBodyKeys = ["trace", "trace_chain", "message", "crash_report"]
test/Rollbar/Item/MissingHeaders/Test.hs view
@@ -2,31 +2,22 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeOperators #-} module Rollbar.Item.MissingHeaders.Test where  import Control.Lens ((&), (^@..)) -import Data.Aeson           (encode, toJSON)-import Data.Aeson.Lens      (key, members)-import Data.Bifunctor       (bimap)-import Data.CaseInsensitive (mk, original)-import Data.Proxy           (Proxy(Proxy))-import Data.Text            (Text, pack)--import GHC.TypeLits (KnownSymbol, symbolVal)+import Data.Aeson      (encode, toJSON)+import Data.Aeson.Lens (members)  import Prelude hiding (error)  import Rollbar.Item.MissingHeaders (MissingHeaders(..))+import Rollbar.QuickCheck          () -import Test.QuickCheck-    (Arbitrary, Gen, Property, arbitrary, conjoin, elements, quickCheck)+import Test.QuickCheck (conjoin, quickCheck) -import Data.ByteString.Char8 as BSC8-import Data.Set              as S-import Data.Text.Encoding    as TE+import Data.Set as S  props :: IO () props = do@@ -46,25 +37,25 @@         ]  prop_valueAuthorizationIsRemoved :: MissingHeaders '["Authorization"] -> Bool-prop_valueAuthorizationIsRemoved hs@(MissingHeaders rhs) =+prop_valueAuthorizationIsRemoved hs =     "Authorization" `S.notMember` actual     where     actual = toJSON hs ^@.. members & fmap fst & S.fromList  prop_encodingAuthorizationIsRemoved :: MissingHeaders '["Authorization"] -> Bool-prop_encodingAuthorizationIsRemoved hs@(MissingHeaders rhs) =+prop_encodingAuthorizationIsRemoved hs =     "Authorization" `S.notMember` actual     where     actual = encode hs ^@.. members & fmap fst & S.fromList  prop_valueX_AccessTokenIsRemoved :: MissingHeaders '["X-AccessToken"] -> Bool-prop_valueX_AccessTokenIsRemoved hs@(MissingHeaders rhs) =+prop_valueX_AccessTokenIsRemoved hs =     "X-AccessToken" `S.notMember` actual     where     actual = toJSON hs ^@.. members & fmap fst & S.fromList  prop_encodingX_AccessTokenIsRemoved :: MissingHeaders '["X-AccessToken"] -> Bool-prop_encodingX_AccessTokenIsRemoved hs@(MissingHeaders rhs) =+prop_encodingX_AccessTokenIsRemoved hs =     "X-AccessToken" `S.notMember` actual     where     actual = encode hs ^@.. members & fmap fst & S.fromList@@ -73,7 +64,7 @@     :: MissingHeaders         '["Authorization", "this is made up", "Server", "X-AccessToken"]     -> Bool-prop_valueAllHeadersAreRemoved hs@(MissingHeaders rhs) =+prop_valueAllHeadersAreRemoved hs =     "Authorization" `S.notMember` actual         && "this is made up" `S.notMember` actual         && "Server" `S.notMember` actual@@ -85,24 +76,10 @@     :: MissingHeaders         '["Authorization", "this is made up", "Server", "X-AccessToken"]     -> Bool-prop_encodingAllHeadersAreRemoved hs@(MissingHeaders rhs) =+prop_encodingAllHeadersAreRemoved hs =     "Authorization" `S.notMember` actual         && "this is made up" `S.notMember` actual         && "Server" `S.notMember` actual         && "X-AccessToken" `S.notMember` actual     where     actual = encode hs ^@.. members & fmap fst & S.fromList--instance Arbitrary (MissingHeaders '[]) where-    arbitrary = do-        xs <- arbitrary-        let hs = bimap (mk . BSC8.pack) BSC8.pack <$> xs-        pure . MissingHeaders $ hs--instance (KnownSymbol header, Arbitrary (MissingHeaders headers))-    => Arbitrary (MissingHeaders (header ': headers)) where-    arbitrary = do-        MissingHeaders hs <- arbitrary :: Gen (MissingHeaders headers)-        let name = mk . BSC8.pack $ symbolVal (Proxy :: Proxy header)-        value <- BSC8.pack <$> arbitrary-        pure . MissingHeaders $ (name, value) : hs
test/Rollbar/Item/Request/Test.hs view
@@ -7,21 +7,18 @@ import Control.Lens ((&), (^@..))  import Data.Aeson           (encode, toJSON)-import Data.Aeson.Lens      (key, members)-import Data.Bifunctor       (bimap)-import Data.CaseInsensitive (mk, original)-import Data.Text            (Text, pack)+import Data.Aeson.Lens      (members)+import Data.CaseInsensitive (original)  import Prelude hiding (error) -import Rollbar.Item.Request (MissingHeaders(..), RemoveHeaders)+import Rollbar.Item.Request (MissingHeaders(..))+import Rollbar.QuickCheck   () -import Test.QuickCheck-    (Arbitrary, Property, arbitrary, conjoin, elements, quickCheck)+import Test.QuickCheck (conjoin, quickCheck) -import Data.ByteString.Char8 as BSC8-import Data.Set              as S-import Data.Text.Encoding    as TE+import Data.Set           as S+import Data.Text.Encoding as TE  props :: IO () props =@@ -43,8 +40,3 @@     where     actual = encode hs ^@.. members & fmap fst & S.fromList     expected = S.fromList $ either (const "") id . TE.decodeUtf8' . original . fst <$> rhs--instance Arbitrary (MissingHeaders ("Authorization" ': headers)) where-    arbitrary = do-        xs <- arbitrary-        pure . MissingHeaders $ bimap (mk . BSC8.pack) BSC8.pack <$> xs
+ test/Rollbar/QuickCheck.hs view
@@ -0,0 +1,52 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeOperators #-}+module Rollbar.QuickCheck where++import Data.Bifunctor       (bimap)+import Data.CaseInsensitive (mk)+import Data.Proxy           (Proxy(Proxy))++import GHC.TypeLits (KnownSymbol, symbolVal)++import Prelude hiding (error)++import Rollbar.Item++import Test.QuickCheck++import qualified Data.ByteString.Char8 as BSC8+import qualified Data.Text             as T++instance Arbitrary a => Arbitrary (Item a '["Authorization"]) where+    arbitrary = Item <$> arbitrary <*> arbitrary++instance Arbitrary AccessToken where+    arbitrary = AccessToken . T.pack <$> arbitrary++instance Arbitrary a => Arbitrary (Data a '["Authorization"]) where+    arbitrary = do+        env <- Environment . T.pack <$> arbitrary+        message <- fmap (MessageBody . T.pack) <$> arbitrary+        payload <- arbitrary+        elements $ (\f -> f env message payload) <$> datas++datas :: [Environment -> Maybe MessageBody -> a -> Data a '["Authorization"]]+datas = [debug, info, warning, error, critical]++instance Arbitrary (MissingHeaders '[]) where+    arbitrary = do+        xs <- arbitrary+        let hs = bimap (mk . BSC8.pack) BSC8.pack <$> xs+        pure . MissingHeaders $ hs++instance (KnownSymbol header, Arbitrary (MissingHeaders headers))+    => Arbitrary (MissingHeaders (header ': headers)) where+    arbitrary = do+        MissingHeaders hs <- arbitrary :: Gen (MissingHeaders headers)+        let name = mk . BSC8.pack $ symbolVal (Proxy :: Proxy header)+        value <- BSC8.pack <$> arbitrary+        pure . MissingHeaders $ (name, value) : hs
wai-middleware-rollbar.cabal view
@@ -1,5 +1,5 @@ name:                wai-middleware-rollbar-version:             0.3.0+version:             0.4.0 synopsis:            Middleware that communicates to Rollbar. description:         Middleware that communicates to Rollbar. homepage:            https://github.com/joneshf/wai-middleware-rollbar#readme@@ -34,12 +34,12 @@                      , Rollbar.Item.Internal.Platform   other-modules:       Paths_wai_middleware_rollbar   build-depends:       base >= 4.7 && < 5-                     , aeson >= 1.0 && < 1.2+                     , aeson >= 1.0 && < 1.3                      , bytestring >= 0.10 && < 0.11                      , case-insensitive >= 1.2 && < 1.3                      , hostname >= 1.0 && < 1.1-                     , http-client >= 0.5 && < 0.6-                     , http-conduit >= 2.2 && < 2.3+                     , http-client >= 0.4 && < 0.6+                     , http-conduit >= 2.1 && < 2.3                      , http-types >= 0.9 && < 0.10                      , network >= 2.6 && < 2.7                      , text >= 1.2 && < 1.3@@ -55,20 +55,25 @@   type:                exitcode-stdio-1.0   hs-source-dirs:      test   main-is:             Main.hs-  other-modules:       Rollbar.Item.Data.Test+  other-modules:       Rollbar.Golden+                     , Rollbar.Item.Data.Test                      , Rollbar.Item.MissingHeaders.Test                      , Rollbar.Item.Request.Test+                     , Rollbar.QuickCheck   build-depends:       base+                     , QuickCheck >= 2.8 && < 2.10                      , aeson                      , bytestring                      , case-insensitive                      , containers >= 0.5 && < 0.6-                     , lens >= 4.15 && < 4.16+                     , hspec >= 2.2 && < 2.5+                     , hspec-golden-aeson >= 0.2 && < 0.3+                     , lens >= 4.14 && < 4.16                      , lens-aeson >= 1.0 && < 1.1-                     , QuickCheck >= 2.9 && < 2.10                      , text                      , wai-middleware-rollbar   default-language:    Haskell2010+  ghc-options:        -Wall  source-repository head   type:     git