Last active
December 29, 2018 12:52
-
-
Save Woody88/8f2422987b475889ded5f95450b8c09e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import Data.Argonaut.Core as J | |
| import Data.Argonaut.Decode (class DecodeJson, decodeJson, getField) | |
| import Data.Argonaut.Decode.Generic.Rep (genericDecodeJson) | |
| import Data.Argonaut.Encode (class EncodeJson) | |
| import Data.Argonaut.Encode.Combinators ((:=), (~>)) | |
| import Data.Argonaut.Encode.Generic.Rep (genericEncodeJson) | |
| import Data.Maybe (Maybe(..), fromMaybe) | |
| import Data.Maybe.First (First(..)) | |
| type OauthConnectionProps | |
| = ( access_token :: String | |
| , token_type :: Maybe String | |
| , refresh_token :: Maybe String | |
| , scope :: Maybe String | |
| , state :: Maybe String | |
| , instance_url :: String | |
| , id :: String | |
| , issued_at :: String | |
| , signature :: String | |
| ) | |
| type OAuthConnectionErrorProps | |
| = ( error :: String | |
| , error_description :: Maybe String | |
| , state :: Maybe String | |
| ) | |
| data OAuthResponse | |
| = OAuthConnection { | OauthConnectionProps } | |
| | OAuthConnectionError' { | OAuthConnectionErrorProps } | |
| --- Not Working Approach | |
| instance decodeJsonOAuthResponse :: DecodeJson OAuthResponse where | |
| decodeJson json = do | |
| obj <- decodeJson json | |
| let at = setTagBy setOauthConnectionTag obj "access_token" | |
| er = setTagBy setOauthConnectionErrorTag obj "error" | |
| l = [ First <<< hush $ at | |
| , First <<< hush $ er | |
| ] | |
| First (maybeJson) = foldl (<>) mempty $ l | |
| json' <- "Could not parse. access_token nor error token found." `getJsonWithErr` maybeJson | |
| genericDecodeJson json' | |
| where | |
| setTagBy :: (J.Json -> J.Json) -> Object J.Json -> String -> Either String J.Json | |
| setTagBy f obj t = f <$> getField obj t | |
| getJsonWithErr :: String -> Maybe J.Json -> Either String J.Json | |
| getJsonWithErr err j = case j of | |
| Nothing -> throwError err | |
| Just json' -> pure json' | |
| setOauthConnectionTag = \_ -> ( "tag" := "OAuthConnection" | |
| ~> "values" := J.jsonSingletonArray json | |
| ~> J.jsonEmptyObject | |
| ) | |
| setOauthConnectionErrorTag = \_ -> ( "tag" := "OAuthConnectionError'" | |
| ~> "values" := J.jsonSingletonArray json | |
| ~> J.jsonEmptyObject | |
| ) | |
| --- Working Approach | |
| instance decodeJsonOAuthResponse :: DecodeJson OAuthResponse where | |
| decodeJson json = do | |
| obj <- decodeJson json | |
| let at = setTagBy setOauthConnectionTag obj "access_token" | |
| er = setTagBy setOauthConnectionErrorTag obj "error" | |
| l = [ First <<< hush $ at | |
| , First <<< hush $ er | |
| ] | |
| First (maybeOauthResponse) = foldl (<>) mempty $ l | |
| "Could not parse. access_token nor error token found." `getOauthResponseWithErr` maybeOauthResponse | |
| where | |
| setTagBy :: (Object J.Json -> String -> Either String OAuthResponse) -> Object J.Json -> String -> Either String OAuthResponse | |
| setTagBy f obj t = f obj =<< getField obj t | |
| getOauthResponseWithErr :: String -> Maybe OAuthResponse -> Either String OAuthResponse | |
| getOauthResponseWithErr err j = case j of | |
| Nothing -> throwError err | |
| Just json' -> pure json' | |
| setOauthConnectionTag :: Object J.Json -> String -> Either String OAuthResponse | |
| setOauthConnectionTag obj' = \access_token -> do | |
| state <- getFieldOptional' obj' "state" | |
| token_type <- getFieldOptional' obj' "token_type" | |
| refresh_token <- getFieldOptional' obj' "refresh_token" | |
| scope <- getFieldOptional' obj' "scope" | |
| instance_url <- getField obj' "instance_url" | |
| id <- getField obj' "id" | |
| issued_at <- getField obj' "issued_at" | |
| signature <- getField obj' "signature" | |
| pure $ OAuthConnection {access_token, state, token_type, refresh_token, scope, instance_url, id, issued_at, signature} | |
| setOauthConnectionErrorTag :: Object J.Json -> String -> Either String OAuthResponse | |
| setOauthConnectionErrorTag obj' = \error -> do | |
| error_description <- getFieldOptional' obj' "error_description" | |
| state <- getFieldOptional' obj' "state" | |
| pure $ OAuthConnectionError' {error, error_description, state} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| module OAuthSpec where | |
| import Prelude | |
| import OAuth | |
| import Data.Argonaut.Core as J | |
| import Data.Argonaut.Decode (decodeJson) | |
| import Data.Argonaut.Encode (encodeJson) | |
| import Data.Argonaut.Parser (jsonParser) | |
| import Data.Either (Either(..)) | |
| import Data.Maybe (Maybe(..)) | |
| import Effect.Class.Console (log) | |
| import Test.Spec (Spec, describe, it) | |
| import Test.Spec.Assertions (shouldContain, shouldEqual) | |
| spec :: Spec Unit | |
| spec = do | |
| describe "can decode OauthResponse to JSON from OAuth module" do | |
| it "decodeJson" do | |
| let eitherJson = jsonParser """{ "access_token": "sometoken", "token_type": "Bearer", "refresh_token": "sometoken", "instance_url": "someurl", "id": "someid", "issued_at": "somedate", "signature": "somesig" }""" | |
| u = decodeJson =<< eitherJson | |
| u `shouldEqual` (Right (OAuthConnection expectedConnAuth)) | |
| where | |
| expectedConnAuth = | |
| { access_token : "sometoken" | |
| , token_type : Just "Bearer" | |
| , refresh_token : Just "sometoken" | |
| , scope : Nothing | |
| , state : Nothing | |
| , instance_url : "someurl" | |
| , id : "someid" | |
| , issued_at : "somedate" | |
| , signature : "somesig" | |
| } | |
| --- (Left "When decoding a OAuthConnectionError': 'tag' property is missing") ≠ (Right (OAuthConnection { access_token: "sometoken", id: "someid", instance_url: "someurl", issued_at: "somedate", refresh_token: (Just "sometoken"), scope: Nothing, signature: "somesig", state: Nothing, token_type: (Just "Bearer") })) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment