@@ -2427,6 +2427,89 @@ def testDispatchBadAccept(self):
24272427 json_dict = json .loads (b2s (results ))
24282428 self .assertIn ('Unable to parse Accept Header. Invalid param: foo. Acceptable types: */*, application/json' , json_dict ['error' ]['msg' ])
24292429
2430+ def testBadJson (self ):
2431+ '''Run some JSON we don't accept through the wringer
2432+ '''
2433+ body = b'{ "title": "Joe Doe has problems", \
2434+ "nosy": [ "1", "3" ], \
2435+ "assignedto": "2", \
2436+ "abool": true, \
2437+ "afloat": 2.3, \
2438+ "anint": Infinity }'
2439+
2440+ expected = { "error" :
2441+ {"status" : 400 ,
2442+ "msg" : ("Unacceptable number: Infinity. JSON is: "
2443+ + b2s (body )),
2444+ }
2445+ }
2446+
2447+ env = { "CONTENT_TYPE" : "application/json" ,
2448+ "CONTENT_LENGTH" : len (body ),
2449+ "REQUEST_METHOD" : "PUT"
2450+ }
2451+ self .server .client .env .update (env )
2452+ headers = {"accept" : "application/zot; version=1; q=0.5" ,
2453+ "content-type" : env ['CONTENT_TYPE' ],
2454+ "content-length" : env ['CONTENT_LENGTH' ],
2455+ }
2456+
2457+ self .headers = headers
2458+ # we need to generate a FieldStorage the looks like
2459+ # FieldStorage(None, None, 'string') rather than
2460+ # FieldStorage(None, None, [])
2461+ body_file = BytesIO (body ) # FieldStorage needs a file
2462+ form = client .BinaryFieldStorage (body_file ,
2463+ headers = headers ,
2464+ environ = env )
2465+ self .server .client .request .headers .get = self .get_header
2466+ results = self .server .dispatch (env ["REQUEST_METHOD" ],
2467+ "/rest/data/issue/1" ,
2468+ form )
2469+
2470+ self .assertEqual (json .loads (results ), expected )
2471+
2472+ body = b'{ "title": "Joe Doe has problems", \
2473+ nosy: [ "1", "3" ], \
2474+ "assignedto": "2", \
2475+ "abool": true, \
2476+ "afloat": 2.3, \
2477+ "anint": Infinity }'
2478+ self .maxDiff = None
2479+ expected = { "error" :
2480+ {"status" : 400 ,
2481+ "msg" : ("Expecting property name enclosed in double "
2482+ "quotes: line 1 column 53 (char 52). JSON is: "
2483+ + b2s (body )),
2484+ }
2485+ }
2486+
2487+ env = { "CONTENT_TYPE" : "application/json" ,
2488+ "CONTENT_LENGTH" : len (body ),
2489+ "REQUEST_METHOD" : "PUT"
2490+ }
2491+ self .server .client .env .update (env )
2492+ headers = {"accept" : "application/zot; version=1; q=0.5" ,
2493+ "content-type" : env ['CONTENT_TYPE' ],
2494+ "content-length" : env ['CONTENT_LENGTH' ],
2495+ }
2496+
2497+ self .headers = headers
2498+ # we need to generate a FieldStorage the looks like
2499+ # FieldStorage(None, None, 'string') rather than
2500+ # FieldStorage(None, None, [])
2501+ body_file = BytesIO (body ) # FieldStorage needs a file
2502+ form = client .BinaryFieldStorage (body_file ,
2503+ headers = headers ,
2504+ environ = env )
2505+ self .server .client .request .headers .get = self .get_header
2506+ results = self .server .dispatch (env ["REQUEST_METHOD" ],
2507+ "/rest/data/issue/1" ,
2508+ form )
2509+
2510+ self .assertEqual (json .loads (results ), expected )
2511+
2512+
24302513 def testStatsGen (self ):
24312514 # check stats being returned by put and get ops
24322515 # using dispatch which parses the @stats query param
@@ -2835,27 +2918,20 @@ def testDispatch(self):
28352918 etag = calculate_etag (self .db .issue .getnode ("1" ),
28362919 self .db .config ['WEB_SECRET_KEY' ])
28372920 etagb = etag .strip ('"' )
2838- env = {"CONTENT_TYPE" : "application/json" ,
2839- "CONTENT_LEN" : 0 ,
2840- "REQUEST_METHOD" : "DELETE" }
2921+ env = {"REQUEST_METHOD" : "DELETE" }
28412922 self .server .client .env .update (env )
28422923 # use text/plain header and request json output by appending
28432924 # .json to the url.
28442925 headers = {"accept" : "text/plain" ,
2845- "content-type" : env ['CONTENT_TYPE' ],
28462926 "if-match" : '"%s"' % etagb ,
28472927 "content-length" : 0 ,
28482928 }
28492929 self .headers = headers
2850- body_file = BytesIO (b'' ) # FieldStorage needs a file
2851- form = client .BinaryFieldStorage (body_file ,
2852- headers = headers ,
2853- environ = env )
28542930 self .server .client .request .headers .get = self .get_header
28552931 self .db .setCurrentUser ('admin' ) # must be admin to delete issue
28562932 results = self .server .dispatch ('DELETE' ,
28572933 "/rest/data/issue/1.json" ,
2858- form )
2934+ self . empty_form )
28592935 self .assertEqual (self .server .client .response_code , 200 )
28602936 print (results )
28612937 json_dict = json .loads (b2s (results ))
@@ -3213,14 +3289,15 @@ def testMethodOverride(self):
32133289 "CONTENT_LENGTH" : len (body ),
32143290 "REQUEST_METHOD" : "POST"
32153291 }
3216- body_file = BytesIO (body ) # FieldStorage needs a file
32173292 self .server .client .request .headers .get = self .get_header
32183293 for method in ( "GET" , "PUT" , "PATCH" ):
32193294 headers = {"accept" : "application/json; version=1" ,
32203295 "content-type" : env ['CONTENT_TYPE' ],
32213296 "content-length" : len (body ),
32223297 "x-http-method-override" : "DElETE" ,
32233298 }
3299+ body_file = BytesIO (body ) # FieldStorage needs a file
3300+
32243301 self .headers = headers
32253302 form = client .BinaryFieldStorage (body_file ,
32263303 headers = headers ,
0 commit comments