web_service_test.go 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. package restful
  2. import (
  3. "net/http"
  4. "net/http/httptest"
  5. "testing"
  6. )
  7. const (
  8. pathGetFriends = "/get/{userId}/friends"
  9. )
  10. func TestParameter(t *testing.T) {
  11. p := &Parameter{&ParameterData{Name: "name", Description: "desc"}}
  12. p.AllowMultiple(true)
  13. p.DataType("int")
  14. p.Required(true)
  15. values := map[string]string{"a": "b"}
  16. p.AllowableValues(values)
  17. p.bePath()
  18. ws := new(WebService)
  19. ws.Param(p)
  20. if ws.pathParameters[0].Data().Name != "name" {
  21. t.Error("path parameter (or name) invalid")
  22. }
  23. }
  24. func TestWebService_CanCreateParameterKinds(t *testing.T) {
  25. ws := new(WebService)
  26. if ws.BodyParameter("b", "b").Kind() != BodyParameterKind {
  27. t.Error("body parameter expected")
  28. }
  29. if ws.PathParameter("p", "p").Kind() != PathParameterKind {
  30. t.Error("path parameter expected")
  31. }
  32. if ws.QueryParameter("q", "q").Kind() != QueryParameterKind {
  33. t.Error("query parameter expected")
  34. }
  35. }
  36. func TestCapturePanic(t *testing.T) {
  37. tearDown()
  38. Add(newPanicingService())
  39. httpRequest, _ := http.NewRequest("GET", "http://here.com/fire", nil)
  40. httpRequest.Header.Set("Accept", "*/*")
  41. httpWriter := httptest.NewRecorder()
  42. DefaultContainer.dispatch(httpWriter, httpRequest)
  43. if 500 != httpWriter.Code {
  44. t.Error("500 expected on fire")
  45. }
  46. }
  47. func TestCapturePanicWithEncoded(t *testing.T) {
  48. tearDown()
  49. Add(newPanicingService())
  50. DefaultContainer.EnableContentEncoding(true)
  51. httpRequest, _ := http.NewRequest("GET", "http://here.com/fire", nil)
  52. httpRequest.Header.Set("Accept", "*/*")
  53. httpRequest.Header.Set("Accept-Encoding", "gzip")
  54. httpWriter := httptest.NewRecorder()
  55. DefaultContainer.dispatch(httpWriter, httpRequest)
  56. if 500 != httpWriter.Code {
  57. t.Error("500 expected on fire, got", httpWriter.Code)
  58. }
  59. }
  60. func TestNotFound(t *testing.T) {
  61. tearDown()
  62. httpRequest, _ := http.NewRequest("GET", "http://here.com/missing", nil)
  63. httpRequest.Header.Set("Accept", "*/*")
  64. httpWriter := httptest.NewRecorder()
  65. DefaultContainer.dispatch(httpWriter, httpRequest)
  66. if 404 != httpWriter.Code {
  67. t.Error("404 expected on missing")
  68. }
  69. }
  70. func TestMethodNotAllowed(t *testing.T) {
  71. tearDown()
  72. Add(newGetOnlyService())
  73. httpRequest, _ := http.NewRequest("POST", "http://here.com/get", nil)
  74. httpRequest.Header.Set("Accept", "*/*")
  75. httpWriter := httptest.NewRecorder()
  76. DefaultContainer.dispatch(httpWriter, httpRequest)
  77. if 405 != httpWriter.Code {
  78. t.Error("405 expected method not allowed")
  79. }
  80. }
  81. func TestSelectedRoutePath_Issue100(t *testing.T) {
  82. tearDown()
  83. Add(newSelectedRouteTestingService())
  84. httpRequest, _ := http.NewRequest("GET", "http://here.com/get/232452/friends", nil)
  85. httpRequest.Header.Set("Accept", "*/*")
  86. httpWriter := httptest.NewRecorder()
  87. DefaultContainer.dispatch(httpWriter, httpRequest)
  88. if http.StatusOK != httpWriter.Code {
  89. t.Error(http.StatusOK, "expected,", httpWriter.Code, "received.")
  90. }
  91. }
  92. func TestContentType415_Issue170(t *testing.T) {
  93. tearDown()
  94. Add(newGetOnlyJsonOnlyService())
  95. httpRequest, _ := http.NewRequest("GET", "http://here.com/get", nil)
  96. httpWriter := httptest.NewRecorder()
  97. DefaultContainer.dispatch(httpWriter, httpRequest)
  98. if 200 != httpWriter.Code {
  99. t.Errorf("Expected 200, got %d", httpWriter.Code)
  100. }
  101. }
  102. func TestNoContentTypePOST(t *testing.T) {
  103. tearDown()
  104. Add(newPostNoConsumesService())
  105. httpRequest, _ := http.NewRequest("POST", "http://here.com/post", nil)
  106. httpWriter := httptest.NewRecorder()
  107. DefaultContainer.dispatch(httpWriter, httpRequest)
  108. if 204 != httpWriter.Code {
  109. t.Errorf("Expected 204, got %d", httpWriter.Code)
  110. }
  111. }
  112. func TestContentType415_POST_Issue170(t *testing.T) {
  113. tearDown()
  114. Add(newPostOnlyJsonOnlyService())
  115. httpRequest, _ := http.NewRequest("POST", "http://here.com/post", nil)
  116. httpRequest.Header.Set("Content-Type", "application/json")
  117. httpWriter := httptest.NewRecorder()
  118. DefaultContainer.dispatch(httpWriter, httpRequest)
  119. if 200 != httpWriter.Code {
  120. t.Errorf("Expected 200, got %d", httpWriter.Code)
  121. }
  122. }
  123. // go test -v -test.run TestContentType406PlainJson ...restful
  124. func TestContentType406PlainJson(t *testing.T) {
  125. tearDown()
  126. TraceLogger(testLogger{t})
  127. Add(newGetPlainTextOrJsonService())
  128. httpRequest, _ := http.NewRequest("GET", "http://here.com/get", nil)
  129. httpRequest.Header.Set("Accept", "text/plain")
  130. httpWriter := httptest.NewRecorder()
  131. DefaultContainer.dispatch(httpWriter, httpRequest)
  132. if got, want := httpWriter.Code, 200; got != want {
  133. t.Errorf("got %v, want %v", got, want)
  134. }
  135. }
  136. func TestRemoveRoute(t *testing.T) {
  137. tearDown()
  138. TraceLogger(testLogger{t})
  139. ws := newGetPlainTextOrJsonService()
  140. Add(ws)
  141. httpRequest, _ := http.NewRequest("GET", "http://here.com/get", nil)
  142. httpRequest.Header.Set("Accept", "text/plain")
  143. httpWriter := httptest.NewRecorder()
  144. DefaultContainer.dispatch(httpWriter, httpRequest)
  145. if got, want := httpWriter.Code, 200; got != want {
  146. t.Errorf("got %v, want %v", got, want)
  147. }
  148. // dynamic apis are disabled, should error and do nothing
  149. if err := ws.RemoveRoute("/get", "GET"); err == nil {
  150. t.Error("unexpected non-error")
  151. }
  152. httpWriter = httptest.NewRecorder()
  153. DefaultContainer.dispatch(httpWriter, httpRequest)
  154. if got, want := httpWriter.Code, 200; got != want {
  155. t.Errorf("got %v, want %v", got, want)
  156. }
  157. ws.SetDynamicRoutes(true)
  158. if err := ws.RemoveRoute("/get", "GET"); err != nil {
  159. t.Errorf("unexpected error %v", err)
  160. }
  161. httpWriter = httptest.NewRecorder()
  162. DefaultContainer.dispatch(httpWriter, httpRequest)
  163. if got, want := httpWriter.Code, 404; got != want {
  164. t.Errorf("got %v, want %v", got, want)
  165. }
  166. }
  167. func TestRemoveLastRoute(t *testing.T) {
  168. tearDown()
  169. TraceLogger(testLogger{t})
  170. ws := newGetPlainTextOrJsonServiceMultiRoute()
  171. Add(ws)
  172. httpRequest, _ := http.NewRequest("GET", "http://here.com/get", nil)
  173. httpRequest.Header.Set("Accept", "text/plain")
  174. httpWriter := httptest.NewRecorder()
  175. DefaultContainer.dispatch(httpWriter, httpRequest)
  176. if got, want := httpWriter.Code, 200; got != want {
  177. t.Errorf("got %v, want %v", got, want)
  178. }
  179. // dynamic apis are disabled, should error and do nothing
  180. if err := ws.RemoveRoute("/get", "GET"); err == nil {
  181. t.Error("unexpected non-error")
  182. }
  183. httpWriter = httptest.NewRecorder()
  184. DefaultContainer.dispatch(httpWriter, httpRequest)
  185. if got, want := httpWriter.Code, 200; got != want {
  186. t.Errorf("got %v, want %v", got, want)
  187. }
  188. ws.SetDynamicRoutes(true)
  189. if err := ws.RemoveRoute("/get", "GET"); err != nil {
  190. t.Errorf("unexpected error %v", err)
  191. }
  192. httpWriter = httptest.NewRecorder()
  193. DefaultContainer.dispatch(httpWriter, httpRequest)
  194. if got, want := httpWriter.Code, 404; got != want {
  195. t.Errorf("got %v, want %v", got, want)
  196. }
  197. }
  198. // go test -v -test.run TestContentTypeOctet_Issue170 ...restful
  199. func TestContentTypeOctet_Issue170(t *testing.T) {
  200. tearDown()
  201. Add(newGetConsumingOctetStreamService())
  202. // with content-type
  203. httpRequest, _ := http.NewRequest("GET", "http://here.com/get", nil)
  204. httpRequest.Header.Set("Content-Type", MIME_OCTET)
  205. httpWriter := httptest.NewRecorder()
  206. DefaultContainer.dispatch(httpWriter, httpRequest)
  207. if 200 != httpWriter.Code {
  208. t.Errorf("Expected 200, got %d", httpWriter.Code)
  209. }
  210. // without content-type
  211. httpRequest, _ = http.NewRequest("GET", "http://here.com/get", nil)
  212. httpWriter = httptest.NewRecorder()
  213. DefaultContainer.dispatch(httpWriter, httpRequest)
  214. if 200 != httpWriter.Code {
  215. t.Errorf("Expected 200, got %d", httpWriter.Code)
  216. }
  217. }
  218. func newPanicingService() *WebService {
  219. ws := new(WebService).Path("")
  220. ws.Route(ws.GET("/fire").To(doPanic))
  221. return ws
  222. }
  223. func newGetOnlyService() *WebService {
  224. ws := new(WebService).Path("")
  225. ws.Route(ws.GET("/get").To(doPanic))
  226. return ws
  227. }
  228. func newPostOnlyJsonOnlyService() *WebService {
  229. ws := new(WebService).Path("")
  230. ws.Consumes("application/json")
  231. ws.Route(ws.POST("/post").To(doNothing))
  232. return ws
  233. }
  234. func newGetOnlyJsonOnlyService() *WebService {
  235. ws := new(WebService).Path("")
  236. ws.Consumes("application/json")
  237. ws.Route(ws.GET("/get").To(doNothing))
  238. return ws
  239. }
  240. func newGetPlainTextOrJsonService() *WebService {
  241. ws := new(WebService).Path("")
  242. ws.Produces("text/plain", "application/json")
  243. ws.Route(ws.GET("/get").To(doNothing))
  244. return ws
  245. }
  246. func newGetPlainTextOrJsonServiceMultiRoute() *WebService {
  247. ws := new(WebService).Path("")
  248. ws.Produces("text/plain", "application/json")
  249. ws.Route(ws.GET("/get").To(doNothing))
  250. ws.Route(ws.GET("/status").To(doNothing))
  251. return ws
  252. }
  253. func newGetConsumingOctetStreamService() *WebService {
  254. ws := new(WebService).Path("")
  255. ws.Consumes("application/octet-stream")
  256. ws.Route(ws.GET("/get").To(doNothing))
  257. return ws
  258. }
  259. func newPostNoConsumesService() *WebService {
  260. ws := new(WebService).Path("")
  261. ws.Route(ws.POST("/post").To(return204))
  262. return ws
  263. }
  264. func newSelectedRouteTestingService() *WebService {
  265. ws := new(WebService).Path("")
  266. ws.Route(ws.GET(pathGetFriends).To(selectedRouteChecker))
  267. return ws
  268. }
  269. func selectedRouteChecker(req *Request, resp *Response) {
  270. if req.SelectedRoutePath() != pathGetFriends {
  271. resp.InternalServerError()
  272. }
  273. }
  274. func doPanic(req *Request, resp *Response) {
  275. println("lightning...")
  276. panic("fire")
  277. }
  278. func doNothing(req *Request, resp *Response) {
  279. }
  280. func return204(req *Request, resp *Response) {
  281. resp.WriteHeader(204)
  282. }