@@ -12,10 +12,15 @@ import Data.Proxy
12
12
(Proxy (.. ))
13
13
import Data.String
14
14
(fromString )
15
+ import qualified Data.Text as T
16
+ import Network.URI
17
+ (unEscapeString )
15
18
import Test.Hspec
16
19
(Expectation , Spec , describe , it , shouldBe )
17
20
18
21
import Servant.API
22
+ import Servant.API.QueryString
23
+ (ToDeepQuery (toDeepQuery ))
19
24
import Servant.Links
20
25
import Servant.Test.ComprehensiveAPI
21
26
(comprehensiveAPIWithoutRaw )
@@ -35,6 +40,9 @@ type TestApi =
35
40
-- UVerb
36
41
:<|> " uverb-example" :> UVerb 'GET '[JSON ] '[WithStatus 200 NoContent ]
37
42
43
+ -- DeepQuery
44
+ :<|> " books" :> DeepQuery " filter" BookQuery :> Get '[JSON ] [Book ]
45
+
38
46
-- All of the verbs
39
47
:<|> " get" :> Get '[JSON ] NoContent
40
48
:<|> " put" :> Put '[JSON ] NoContent
@@ -51,6 +59,18 @@ apiLink :: (IsElem endpoint TestApi, HasLink endpoint)
51
59
=> Proxy endpoint -> MkLink endpoint Link
52
60
apiLink = safeLink (Proxy :: Proxy TestApi )
53
61
62
+ data Book
63
+ data BookQuery = BookQuery
64
+ { author :: String
65
+ , year :: Int
66
+ } deriving (Generic , Show , Eq )
67
+
68
+ instance ToDeepQuery BookQuery where
69
+ toDeepQuery (BookQuery author year) =
70
+ [ ([T. pack " author" ], Just $ toQueryParam author)
71
+ , ([T. pack " year" ], Just $ toQueryParam year)
72
+ ]
73
+
54
74
55
75
newtype QuuxRoutes mode = QuuxRoutes
56
76
{ corge :: mode :- " corge" :> Post '[PlainText ] NoContent
@@ -84,6 +104,10 @@ shouldBeLink :: Link -> String -> Expectation
84
104
shouldBeLink link expected =
85
105
toUrlPiece link `shouldBe` fromString expected
86
106
107
+ shouldBeLinkUnescaped :: Link -> String -> Expectation
108
+ shouldBeLinkUnescaped link expected =
109
+ unEscapeString (T. unpack $ toUrlPiece link) `shouldBe` fromString expected
110
+
87
111
(//) :: a -> (a -> b ) -> b
88
112
x // f = f x
89
113
infixl 1 //
@@ -152,6 +176,11 @@ spec = describe "Servant.Links" $ do
152
176
(fieldLink foo // garply /: " captureme" /: 42 // waldo)
153
177
`shouldBeLink` " foo/garply/captureme/42/waldo"
154
178
179
+ it " generated correct links for DeepQuery" $ do
180
+ let bFilter = Proxy :: Proxy (" books" :> DeepQuery " filter" BookQuery :> Get '[JSON ] [Book ])
181
+ let exampleQuery = BookQuery { author = " Herbert" , year = 1965 }
182
+ apiLink bFilter exampleQuery `shouldBeLinkUnescaped` " books?filter[author]=Herbert&filter[year]=1965"
183
+
155
184
it " Check links from record fields" $ do
156
185
let sub1 = Proxy :: Proxy (" bar" :> Get '[JSON ] NoContent )
157
186
recordApiLink sub1 `shouldBeLink` " bar"
0 commit comments