github.com/ccrossley/goa@v1.3.1/design/apidsl/resource_test.go (about) 1 package apidsl_test 2 3 import ( 4 . "github.com/goadesign/goa/design" 5 . "github.com/goadesign/goa/design/apidsl" 6 "github.com/goadesign/goa/dslengine" 7 . "github.com/onsi/ginkgo" 8 . "github.com/onsi/gomega" 9 ) 10 11 var _ = Describe("Resource", func() { 12 var name string 13 var dsl func() 14 15 var res *ResourceDefinition 16 17 BeforeEach(func() { 18 dslengine.Reset() 19 name = "" 20 dsl = nil 21 }) 22 23 JustBeforeEach(func() { 24 res = Resource(name, dsl) 25 dslengine.Run() 26 }) 27 28 Context("with no dsl and no name", func() { 29 It("produces an invalid resource definition", func() { 30 Ω(res).ShouldNot(BeNil()) 31 Ω(res.Validate()).Should(HaveOccurred()) 32 }) 33 }) 34 35 Context("with no dsl", func() { 36 BeforeEach(func() { 37 name = "foo" 38 }) 39 40 It("produces a valid resource definition and defaults the media type to text/plain", func() { 41 Ω(res).ShouldNot(BeNil()) 42 Ω(res.Validate()).ShouldNot(HaveOccurred()) 43 Ω(res.MediaType).Should(Equal("text/plain")) 44 }) 45 }) 46 47 Context("with a description", func() { 48 const description = "desc" 49 50 BeforeEach(func() { 51 name = "foo" 52 dsl = func() { 53 Description(description) 54 } 55 }) 56 57 It("sets the description", func() { 58 Ω(res).ShouldNot(BeNil()) 59 Ω(res.Validate()).ShouldNot(HaveOccurred()) 60 Ω(res.Description).Should(Equal(description)) 61 }) 62 }) 63 64 Context("with a parent resource that does not exist", func() { 65 const parent = "parent" 66 67 BeforeEach(func() { 68 name = "foo" 69 dsl = func() { 70 Parent(parent) 71 } 72 }) 73 74 It("sets the parent and produces an invalid resource definition", func() { 75 Ω(res).ShouldNot(BeNil()) 76 Ω(res.ParentName).Should(Equal(parent)) 77 Ω(res.Validate()).Should(HaveOccurred()) 78 }) 79 }) 80 81 Context("with actions", func() { 82 const actionName = "action" 83 84 BeforeEach(func() { 85 name = "foo" 86 dsl = func() { 87 Action(actionName, func() { Routing(PUT(":/id")) }) 88 } 89 }) 90 91 It("sets the actions", func() { 92 Ω(res).ShouldNot(BeNil()) 93 Ω(res.Validate()).ShouldNot(HaveOccurred()) 94 Ω(res.Actions).Should(HaveLen(1)) 95 Ω(res.Actions).Should(HaveKey(actionName)) 96 }) 97 }) 98 99 Context("with metadata and actions", func() { 100 const actionName = "action" 101 102 BeforeEach(func() { 103 name = "foo" 104 dsl = func() { 105 Metadata("swagger:generate", "false") 106 Action(actionName, func() { Routing(PUT(":/id")) }) 107 } 108 }) 109 110 It("sets the actions", func() { 111 Ω(res).ShouldNot(BeNil()) 112 Ω(res.Finalize).ShouldNot(Panic()) 113 Ω(res.Validate()).ShouldNot(HaveOccurred()) 114 Ω(res.Actions).Should(HaveLen(1)) 115 Ω(res.Actions).Should(HaveKey(actionName)) 116 }) 117 }) 118 119 Context("with metadata and files", func() { 120 BeforeEach(func() { 121 name = "foo" 122 dsl = func() { 123 Metadata("swagger:generate", "false") 124 Files("path", "filename") 125 } 126 }) 127 128 It("sets the files", func() { 129 Ω(res).ShouldNot(BeNil()) 130 Ω(res.Finalize).ShouldNot(Panic()) 131 Ω(res.Validate()).ShouldNot(HaveOccurred()) 132 Ω(res.FileServers).Should(HaveLen(1)) 133 }) 134 }) 135 136 Context("with a canonical action that does not exist", func() { 137 const can = "can" 138 139 BeforeEach(func() { 140 name = "foo" 141 dsl = func() { 142 CanonicalActionName(can) 143 } 144 }) 145 146 It("sets the canonical action and produces an invalid resource definition", func() { 147 Ω(res).ShouldNot(BeNil()) 148 Ω(res.CanonicalActionName).Should(Equal(can)) 149 Ω(res.Validate()).Should(HaveOccurred()) 150 }) 151 }) 152 153 Context("with a canonical action that does exist", func() { 154 const can = "can" 155 156 BeforeEach(func() { 157 name = "foo" 158 dsl = func() { 159 Action(can, func() { Routing(PUT(":/id")) }) 160 CanonicalActionName(can) 161 } 162 }) 163 164 It("sets the canonical action and produces a valid resource definition", func() { 165 Ω(res).ShouldNot(BeNil()) 166 Ω(res.CanonicalActionName).Should(Equal(can)) 167 Ω(res.Validate()).ShouldNot(HaveOccurred()) 168 }) 169 }) 170 171 Context("with a base path", func() { 172 const basePath = "basePath" 173 174 BeforeEach(func() { 175 name = "foo" 176 dsl = func() { 177 BasePath(basePath) 178 } 179 }) 180 181 It("sets the base path", func() { 182 Ω(res).ShouldNot(BeNil()) 183 Ω(res.Validate()).ShouldNot(HaveOccurred()) 184 Ω(res.BasePath).Should(Equal(basePath)) 185 }) 186 }) 187 188 Context("with base params", func() { 189 const basePath = "basePath/:paramID" 190 191 BeforeEach(func() { 192 name = "foo" 193 dsl = func() { 194 BasePath(basePath) 195 Params(func() { 196 Param("paramID") 197 }) 198 } 199 }) 200 201 It("sets the base path and params", func() { 202 Ω(res).ShouldNot(BeNil()) 203 Ω(res.Validate()).ShouldNot(HaveOccurred()) 204 Ω(res.BasePath).Should(Equal(basePath)) 205 Ω(res.Params).ShouldNot(BeNil()) 206 Ω(res.Params.Type).ShouldNot(BeNil()) 207 Ω(res.Params.Type.ToObject()).Should(HaveKey("paramID")) 208 }) 209 }) 210 211 Context("with a media type name", func() { 212 const mediaType = "application/mt" 213 214 BeforeEach(func() { 215 name = "foo" 216 dsl = func() { 217 DefaultMedia(mediaType) 218 } 219 }) 220 221 It("sets the media type", func() { 222 Ω(res).ShouldNot(BeNil()) 223 Ω(res.Validate()).ShouldNot(HaveOccurred()) 224 Ω(res.MediaType).Should(Equal(mediaType)) 225 }) 226 }) 227 228 Context("with a view name", func() { 229 const mediaType = "application/mt" 230 231 BeforeEach(func() { 232 name = "foo" 233 dsl = func() { 234 DefaultMedia(mediaType, "compact") 235 } 236 }) 237 238 It("sets the media type", func() { 239 Ω(res).ShouldNot(BeNil()) 240 Ω(res.Validate()).ShouldNot(HaveOccurred()) 241 Ω(res.MediaType).Should(Equal(mediaType)) 242 Ω(res.DefaultViewName).Should(Equal("compact")) 243 }) 244 }) 245 246 Context("with an invalid media type", func() { 247 var mediaType = &MediaTypeDefinition{Identifier: "application/foo"} 248 249 BeforeEach(func() { 250 name = "foo" 251 dsl = func() { 252 DefaultMedia(mediaType) 253 } 254 }) 255 256 It("fails", func() { 257 Ω(dslengine.Errors).Should(HaveOccurred()) 258 }) 259 }) 260 261 Context("with a valid media type", func() { 262 const typeName = "typeName" 263 const identifier = "application/vnd.raphael.goa.test" 264 265 var mediaType = &MediaTypeDefinition{ 266 UserTypeDefinition: &UserTypeDefinition{ 267 TypeName: typeName, 268 }, 269 Identifier: identifier, 270 } 271 272 BeforeEach(func() { 273 name = "foo" 274 dsl = func() { 275 DefaultMedia(mediaType) 276 } 277 }) 278 279 It("sets the media type", func() { 280 Ω(res).ShouldNot(BeNil()) 281 Ω(res.Validate()).ShouldNot(HaveOccurred()) 282 Ω(res.MediaType).Should(Equal(identifier)) 283 }) 284 }) 285 286 Context("with a valid media type using a modifier", func() { 287 const typeName = "typeName" 288 const identifier = "application/vnd.raphael.goa.test+json" 289 290 var mediaType = &MediaTypeDefinition{ 291 UserTypeDefinition: &UserTypeDefinition{ 292 TypeName: typeName, 293 }, 294 Identifier: identifier, 295 } 296 297 BeforeEach(func() { 298 name = "foo" 299 dsl = func() { 300 DefaultMedia(mediaType) 301 } 302 }) 303 304 It("sets the media type and keeps the modifier", func() { 305 Ω(res).ShouldNot(BeNil()) 306 Ω(res.Validate()).ShouldNot(HaveOccurred()) 307 Ω(res.MediaType).Should(Equal(identifier)) 308 }) 309 }) 310 311 Context("with a trait that does not exist", func() { 312 BeforeEach(func() { 313 name = "foo" 314 dsl = func() { UseTrait("Authenticated") } 315 }) 316 317 It("returns an error", func() { 318 Ω(dslengine.Errors).Should(HaveOccurred()) 319 }) 320 }) 321 322 Context("with a trait that exists", func() { 323 const description = "desc" 324 const traitName = "descTrait" 325 326 BeforeEach(func() { 327 name = "foo" 328 dsl = func() { UseTrait(traitName) } 329 API("test", func() { 330 Trait(traitName, func() { 331 Description(description) 332 }) 333 }) 334 }) 335 336 It("runs the trait", func() { 337 Ω(res).ShouldNot(BeNil()) 338 Ω(res.Validate()).ShouldNot(HaveOccurred()) 339 Ω(res.Description).Should(Equal(description)) 340 }) 341 }) 342 })