Ignore the Range header when the method is different than GET
fix: bug when using Range header on PATCH/DELETE - Fix the "message": "syntax error at or near \"RETURNING\"" error - Fix doing a limited update/delete when an order query parameter was present breaking: The Range header is now only considered on GET requests and is ignored for any other method - Other methods should use the `limit/offset` query parameters for sub-ranges - PUT requests no longer return an error when this header is present
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
module Feature.Query.RangeSpec where
|
||||
|
||||
import qualified Data.ByteString.Lazy as BL
|
||||
|
||||
import Network.Wai (Application)
|
||||
import Network.Wai.Test (SResponse (simpleHeaders, simpleStatus))
|
||||
|
||||
@@ -13,36 +11,29 @@ import Test.Hspec.Wai.JSON
|
||||
import Protolude hiding (get)
|
||||
import SpecHelper
|
||||
|
||||
defaultRange :: BL.ByteString
|
||||
defaultRange = [json| { "min": 0, "max": 15 } |]
|
||||
|
||||
emptyRange :: BL.ByteString
|
||||
emptyRange = [json| { "min": 2, "max": 2 } |]
|
||||
|
||||
spec :: SpecWith ((), Application)
|
||||
spec = do
|
||||
describe "POST /rpc/getitemrange" $ do
|
||||
describe "GET /rpc/getitemrange" $ do
|
||||
context "without range headers" $ do
|
||||
context "with response under server size limit" $
|
||||
it "returns whole range with status 200" $
|
||||
post "/rpc/getitemrange" defaultRange `shouldRespondWith` 200
|
||||
get "/rpc/getitemrange?min=0&max=15" `shouldRespondWith` 200
|
||||
|
||||
context "when I don't want the count" $ do
|
||||
it "returns range Content-Range with */* for empty range" $
|
||||
request methodPost "/rpc/getitemrange" [] emptyRange
|
||||
get "/rpc/getitemrange?min=2&max=2"
|
||||
`shouldRespondWith` [json| [] |] {matchHeaders = ["Content-Range" <:> "*/*"]}
|
||||
|
||||
it "returns range Content-Range with range/*" $
|
||||
post "/rpc/getitemrange?order=id"
|
||||
defaultRange
|
||||
get "/rpc/getitemrange?order=id&min=0&max=15"
|
||||
`shouldRespondWith`
|
||||
[json| [{"id":1},{"id":2},{"id":3},{"id":4},{"id":5},{"id":6},{"id":7},{"id":8},{"id":9},{"id":10},{"id":11},{"id":12},{"id":13},{"id":14},{"id":15}] |]
|
||||
{ matchHeaders = ["Content-Range" <:> "0-14/*"] }
|
||||
|
||||
context "of invalid range" $ do
|
||||
it "refuses a range with nonzero start when there are no items" $
|
||||
request methodPost "/rpc/getitemrange?offset=1"
|
||||
[("Prefer", "count=exact")] emptyRange
|
||||
request methodGet "/rpc/getitemrange?offset=1&min=2&max=2"
|
||||
[("Prefer", "count=exact")] mempty
|
||||
`shouldRespondWith`
|
||||
[json| {
|
||||
"message":"Requested range not satisfiable",
|
||||
@@ -55,8 +46,8 @@ spec = do
|
||||
}
|
||||
|
||||
it "refuses a range requesting start past last item" $
|
||||
request methodPost "/rpc/getitemrange?offset=100"
|
||||
[("Prefer", "count=exact")] defaultRange
|
||||
request methodGet "/rpc/getitemrange?offset=100&min=0&max=15"
|
||||
[("Prefer", "count=exact")] mempty
|
||||
`shouldRespondWith`
|
||||
[json| {
|
||||
"message":"Requested range not satisfiable",
|
||||
@@ -71,37 +62,37 @@ spec = do
|
||||
context "with range headers" $ do
|
||||
context "of acceptable range" $ do
|
||||
it "succeeds with partial content" $ do
|
||||
r <- request methodPost "/rpc/getitemrange"
|
||||
(rangeHdrs $ ByteRangeFromTo 0 1) defaultRange
|
||||
r <- request methodGet "/rpc/getitemrange?min=0&max=15"
|
||||
(rangeHdrs $ ByteRangeFromTo 0 1) mempty
|
||||
liftIO $ do
|
||||
simpleHeaders r `shouldSatisfy`
|
||||
matchHeader "Content-Range" "0-1/*"
|
||||
simpleStatus r `shouldBe` ok200
|
||||
|
||||
it "understands open-ended ranges" $
|
||||
request methodPost "/rpc/getitemrange"
|
||||
(rangeHdrs $ ByteRangeFrom 0) defaultRange
|
||||
request methodGet "/rpc/getitemrange?min=0&max=15"
|
||||
(rangeHdrs $ ByteRangeFrom 0) mempty
|
||||
`shouldRespondWith` 200
|
||||
|
||||
it "returns an empty body when there are no results" $
|
||||
request methodPost "/rpc/getitemrange"
|
||||
(rangeHdrs $ ByteRangeFromTo 0 1) emptyRange
|
||||
request methodGet "/rpc/getitemrange?min=2&max=2"
|
||||
(rangeHdrs $ ByteRangeFromTo 0 1) mempty
|
||||
`shouldRespondWith` "[]"
|
||||
{ matchStatus = 200
|
||||
, matchHeaders = ["Content-Range" <:> "*/*"]
|
||||
}
|
||||
|
||||
it "allows one-item requests" $ do
|
||||
r <- request methodPost "/rpc/getitemrange"
|
||||
(rangeHdrs $ ByteRangeFromTo 0 0) defaultRange
|
||||
r <- request methodGet "/rpc/getitemrange?min=0&max=15"
|
||||
(rangeHdrs $ ByteRangeFromTo 0 0) mempty
|
||||
liftIO $ do
|
||||
simpleHeaders r `shouldSatisfy`
|
||||
matchHeader "Content-Range" "0-0/*"
|
||||
simpleStatus r `shouldBe` ok200
|
||||
|
||||
it "handles ranges beyond collection length via truncation" $ do
|
||||
r <- request methodPost "/rpc/getitemrange"
|
||||
(rangeHdrs $ ByteRangeFromTo 10 100) defaultRange
|
||||
r <- request methodGet "/rpc/getitemrange?min=0&max=15"
|
||||
(rangeHdrs $ ByteRangeFromTo 10 100) mempty
|
||||
liftIO $ do
|
||||
simpleHeaders r `shouldSatisfy`
|
||||
matchHeader "Content-Range" "10-14/*"
|
||||
@@ -109,8 +100,8 @@ spec = do
|
||||
|
||||
context "of invalid range" $ do
|
||||
it "fails with 416 for offside range" $
|
||||
request methodPost "/rpc/getitemrange"
|
||||
(rangeHdrs $ ByteRangeFromTo 1 0) emptyRange
|
||||
request methodGet "/rpc/getitemrange?min=2&max=2"
|
||||
(rangeHdrs $ ByteRangeFromTo 1 0) mempty
|
||||
`shouldRespondWith`
|
||||
[json| {
|
||||
"message":"Requested range not satisfiable",
|
||||
@@ -121,8 +112,8 @@ spec = do
|
||||
{ matchStatus = 416 }
|
||||
|
||||
it "refuses a range with nonzero start when there are no items" $
|
||||
request methodPost "/rpc/getitemrange"
|
||||
(rangeHdrsWithCount $ ByteRangeFromTo 1 2) emptyRange
|
||||
request methodGet "/rpc/getitemrange?min=2&max=2"
|
||||
(rangeHdrsWithCount $ ByteRangeFromTo 1 2) mempty
|
||||
`shouldRespondWith`
|
||||
[json| {
|
||||
"message":"Requested range not satisfiable",
|
||||
@@ -135,8 +126,8 @@ spec = do
|
||||
}
|
||||
|
||||
it "refuses a range requesting start past last item" $
|
||||
request methodPost "/rpc/getitemrange"
|
||||
(rangeHdrsWithCount $ ByteRangeFromTo 100 199) defaultRange
|
||||
request methodGet "/rpc/getitemrange?min=0&max=15"
|
||||
(rangeHdrsWithCount $ ByteRangeFromTo 100 199) mempty
|
||||
`shouldRespondWith`
|
||||
[json| {
|
||||
"message":"Requested range not satisfiable",
|
||||
|
||||
Reference in New Issue
Block a user