github.com/mmatczuk/gohan@v0.0.0-20170206152520-30e45d9bdb69/server/resources/resource_management_test.go (about) 1 // Copyright (C) 2015 NTT Innovation Institute, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 // implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 package resources_test 17 18 import ( 19 "fmt" 20 "time" 21 22 "github.com/cloudwan/gohan/extension" 23 "github.com/cloudwan/gohan/extension/otto" 24 "github.com/cloudwan/gohan/schema" 25 "github.com/cloudwan/gohan/server" 26 "github.com/cloudwan/gohan/server/middleware" 27 "github.com/cloudwan/gohan/server/resources" 28 "github.com/cloudwan/gohan/util" 29 . "github.com/onsi/ginkgo" 30 . "github.com/onsi/gomega" 31 "github.com/twinj/uuid" 32 ) 33 34 var _ = Describe("Resource manager", func() { 35 const ( 36 resourceID1 = "6660fbf8-ca60-4cb0-a42e-9a913beafbaf" 37 resourceID2 = "6660fbf8-ca60-4cb0-a42e-9a913beafbae" 38 ) 39 40 var ( 41 manager *schema.Manager 42 adminAuth schema.Authorization 43 memberAuth schema.Authorization 44 auth schema.Authorization 45 context middleware.Context 46 schemaID string 47 path string 48 action string 49 currentSchema *schema.Schema 50 extensions []*schema.Extension 51 env extension.Environment 52 events map[string]string 53 timelimit time.Duration 54 ) 55 56 BeforeEach(func() { 57 manager = schema.GetManager() 58 59 adminAuth = schema.NewAuthorization(adminTenantID, "admin", adminTokenID, []string{"admin"}, nil) 60 memberAuth = schema.NewAuthorization(memberTenantID, "demo", memberTokenID, []string{"Member"}, nil) 61 timelimit = time.Duration(1) * time.Second 62 auth = adminAuth 63 64 context = middleware.Context{} 65 66 events = map[string]string{} 67 }) 68 69 environmentManager := extension.GetManager() 70 71 JustBeforeEach(func() { 72 var ok bool 73 currentSchema, ok = manager.Schema(schemaID) 74 Expect(ok).To(BeTrue()) 75 76 path = currentSchema.GetPluralURL() 77 78 policy, role := manager.PolicyValidate(action, path, auth) 79 Expect(policy).NotTo(BeNil()) 80 context["policy"] = policy 81 context["role"] = role 82 context["tenant_id"] = auth.TenantID() 83 context["tenant_name"] = auth.TenantName() 84 context["auth_token"] = auth.AuthToken() 85 context["catalog"] = auth.Catalog() 86 context["auth"] = auth 87 88 env = otto.NewEnvironment("resource_management_test", 89 testDB, &middleware.FakeIdentity{}, timelimit, testSync) 90 extensions = []*schema.Extension{} 91 for event, javascript := range events { 92 extension, err := schema.NewExtension(map[string]interface{}{ 93 "id": event + "_extension", 94 "code": `gohan_register_handler("` + event + `", function(context) {` + javascript + `});`, 95 "path": path, 96 }) 97 Expect(err).ToNot(HaveOccurred()) 98 extensions = append(extensions, extension) 99 } 100 Expect(env.LoadExtensionsForPath(extensions, path)).To(Succeed()) 101 environmentManager.RegisterEnvironment(schemaID, env) 102 }) 103 104 AfterEach(func() { 105 tx, err := testDB.Begin() 106 Expect(err).ToNot(HaveOccurred(), "Failed to create transaction.") 107 environmentManager.UnRegisterEnvironment(schemaID) 108 defer tx.Close() 109 for _, schema := range schema.GetManager().Schemas() { 110 if whitelist[schema.ID] { 111 continue 112 } 113 err = clearTable(tx, schema) 114 Expect(err).ToNot(HaveOccurred(), "Failed to clear table.") 115 } 116 err = tx.Commit() 117 Expect(err).ToNot(HaveOccurred(), "Failed to commite transaction.") 118 }) 119 120 Describe("Getting a schema", func() { 121 BeforeEach(func() { 122 schemaID = "schema" 123 action = "read" 124 }) 125 126 Context("As an admin", func() { 127 It("Should always return the full schema", func() { 128 for _, currentSchema := range manager.OrderedSchemas() { 129 if currentSchema.IsAbstract() { 130 continue 131 } 132 trimmedSchema, err := server.GetSchema(currentSchema, auth) 133 Expect(err).NotTo(HaveOccurred()) 134 rawSchema := currentSchema.JSON() 135 fullSchema, err := schema.NewResource(currentSchema, rawSchema) 136 Expect(err).ToNot(HaveOccurred()) 137 Expect(trimmedSchema).To(util.MatchAsJSON(fullSchema)) 138 } 139 }) 140 }) 141 142 Context("As a member", func() { 143 BeforeEach(func() { 144 auth = memberAuth 145 }) 146 147 It("Should return full schema when appropriate", func() { 148 By("Fetching the schema") 149 schemaSchema, ok := manager.Schema("schema") 150 Expect(ok).To(BeTrue()) 151 By("The schema being equal to the full schema") 152 trimmedSchema, err := server.GetSchema(currentSchema, auth) 153 Expect(err).NotTo(HaveOccurred()) 154 Expect(trimmedSchema).NotTo(BeNil()) 155 rawSchema := schemaSchema.JSON() 156 fullSchema, err := schema.NewResource(currentSchema, rawSchema) 157 Expect(err).ToNot(HaveOccurred()) 158 Expect(trimmedSchema).To(util.MatchAsJSON(fullSchema)) 159 }) 160 161 It("Should return trimmed schema when appropriate", func() { 162 By("Fetching the schema") 163 networkSchema, ok := manager.Schema("network") 164 Expect(ok).To(BeTrue()) 165 trimmedSchema, err := server.GetSchema(networkSchema, auth) 166 Expect(err).NotTo(HaveOccurred()) 167 Expect(trimmedSchema).NotTo(BeNil()) 168 theSchema, ok := trimmedSchema.Get("schema").(map[string]interface{}) 169 Expect(ok).To(BeTrue()) 170 properties, ok := theSchema["properties"].(map[string]interface{}) 171 Expect(ok).To(BeTrue()) 172 173 By("Leaving allowed properties") 174 _, ok = properties["id"] 175 Expect(ok).To(BeTrue()) 176 _, ok = properties["name"] 177 Expect(ok).To(BeTrue()) 178 _, ok = properties["description"] 179 Expect(ok).To(BeTrue()) 180 _, ok = properties["tenant_id"] 181 Expect(ok).To(BeTrue()) 182 183 By("Removing other properties") 184 _, ok = properties["providor_networks"] 185 Expect(ok).To(BeFalse()) 186 _, ok = properties["route_targets"] 187 Expect(ok).To(BeFalse()) 188 _, ok = properties["shared"] 189 Expect(ok).To(BeFalse()) 190 }) 191 192 It("Should return no schema when appropriate", func() { 193 By("Not fetching the schema") 194 testSchema, ok := manager.Schema("admin_only") 195 Expect(ok).To(BeTrue()) 196 trimmedSchema, err := server.GetSchema(testSchema, auth) 197 Expect(err).NotTo(HaveOccurred()) 198 Expect(trimmedSchema).To(BeNil()) 199 }) 200 }) 201 }) 202 203 Describe("Listing resources", func() { 204 BeforeEach(func() { 205 schemaID = "test" 206 action = "read" 207 }) 208 209 Describe("When there are no resources in the database", func() { 210 It("Should return an empty list", func() { 211 err := resources.GetMultipleResources( 212 context, testDB, currentSchema, map[string][]string{}) 213 result, _ := context["response"].(map[string]interface{}) 214 number := context["total"].(uint64) 215 Expect(err).NotTo(HaveOccurred()) 216 Expect(err).NotTo(HaveOccurred()) 217 Expect(number).To(Equal(uint64(0))) 218 Expect(result).To(HaveKeyWithValue("tests", BeEmpty())) 219 }) 220 221 Describe("With extensions", func() { 222 Context("Only pre_list", func() { 223 BeforeEach(func() { 224 events["pre_list"] = `context["response"] = {"respondo": "bona"};` 225 }) 226 227 It("Should run the extension", func() { 228 err := resources.GetMultipleResources( 229 context, testDB, currentSchema, map[string][]string{}) 230 result, _ := context["response"].(map[string]interface{}) 231 number, _ := context["total"].(uint64) 232 233 Expect(err).NotTo(HaveOccurred()) 234 Expect(number).To(Equal(uint64(0))) 235 Expect(result).To(HaveKeyWithValue("respondo", "bona")) 236 }) 237 }) 238 239 Context("Only pre_list_in_transaction", func() { 240 BeforeEach(func() { 241 events["pre_list_in_transaction"] = `throw new CustomException("malbona", 390);` 242 }) 243 244 It("Should run the extension", func() { 245 err := resources.GetMultipleResources( 246 context, testDB, currentSchema, map[string][]string{}) 247 Expect(err).To(HaveOccurred()) 248 extErr, ok := err.(extension.Error) 249 Expect(ok).To(BeTrue()) 250 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("name", "CustomException")) 251 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("message", "malbona")) 252 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("code", int64(390))) 253 }) 254 }) 255 256 Context("Only post_list_in_transaction", func() { 257 BeforeEach(func() { 258 events["post_list_in_transaction"] = `throw new CustomException("tre malbona", 390);` 259 }) 260 261 It("Should run the extension", func() { 262 err := resources.GetMultipleResources( 263 context, testDB, currentSchema, map[string][]string{}) 264 Expect(err).To(HaveOccurred()) 265 extErr, ok := err.(extension.Error) 266 Expect(ok).To(BeTrue()) 267 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("name", "CustomException")) 268 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("message", "tre malbona")) 269 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("code", int64(390))) 270 }) 271 }) 272 273 Context("Only post_list", func() { 274 BeforeEach(func() { 275 events["post_list"] = `context["response"] = {"respondo": "tre bona"};` 276 }) 277 278 It("Should run the extension", func() { 279 err := resources.GetMultipleResources( 280 context, testDB, currentSchema, map[string][]string{}) 281 result := context["response"].(map[string]interface{}) 282 number := context["total"].(uint64) 283 Expect(err).NotTo(HaveOccurred()) 284 Expect(number).To(Equal(uint64(0))) 285 Expect(result).To(HaveKeyWithValue("respondo", "tre bona")) 286 }) 287 }) 288 289 Context("With pre_list throwing exception", func() { 290 BeforeEach(func() { 291 events["pre_list"] = `throw new CustomException("malbona", 390);` 292 }) 293 294 It("Should run the extension", func() { 295 err := resources.GetMultipleResources( 296 context, testDB, currentSchema, map[string][]string{}) 297 Expect(err).To(HaveOccurred()) 298 extErr, ok := err.(extension.Error) 299 Expect(ok).To(BeTrue()) 300 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("name", "CustomException")) 301 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("message", "malbona")) 302 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("code", int64(390))) 303 }) 304 }) 305 306 Context("With post_list throwing exception", func() { 307 BeforeEach(func() { 308 events["post_list"] = `throw new CustomException("tre malbona", 390);` 309 }) 310 311 It("Should run the extension", func() { 312 err := resources.GetMultipleResources( 313 context, testDB, currentSchema, map[string][]string{}) 314 Expect(err).To(HaveOccurred()) 315 extErr, ok := err.(extension.Error) 316 Expect(ok).To(BeTrue()) 317 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("name", "CustomException")) 318 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("message", "tre malbona")) 319 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("code", int64(390))) 320 }) 321 }) 322 323 Context("With pre_list returning invalid JSON", func() { 324 BeforeEach(func() { 325 events["pre_list"] = `context["response"] = "erara";` 326 }) 327 328 It("Should run the extension", func() { 329 err := resources.GetMultipleResources( 330 context, testDB, currentSchema, map[string][]string{}) 331 Expect(err).To(MatchError(HavePrefix("extension returned invalid JSON:"))) 332 }) 333 }) 334 335 Context("With post_list returning invalid JSON", func() { 336 BeforeEach(func() { 337 events["post_list"] = `context["response"] = "erara";` 338 }) 339 340 It("Should run the extension", func() { 341 err := resources.GetMultipleResources( 342 context, testDB, currentSchema, map[string][]string{}) 343 Expect(err).To(MatchError(HavePrefix("extension returned invalid JSON:"))) 344 }) 345 }) 346 347 Context("With post_list returning no response", func() { 348 BeforeEach(func() { 349 events["post_list"] = `delete context["response"];` 350 }) 351 352 It("Should run the extension", func() { 353 err := resources.GetMultipleResources( 354 context, testDB, currentSchema, map[string][]string{}) 355 Expect(err).To(MatchError("No response")) 356 }) 357 }) 358 }) 359 }) 360 361 Describe("When there are resources in the database", func() { 362 var ( 363 adminResourceData, memberResourceData map[string]interface{} 364 ) 365 366 BeforeEach(func() { 367 adminResourceData = map[string]interface{}{ 368 "id": resourceID1, 369 "tenant_id": adminTenantID, 370 "test_string": "Steloj estas en ordo.", 371 "test_bool": false, 372 } 373 memberResourceData = map[string]interface{}{ 374 "id": resourceID2, 375 "tenant_id": powerUserTenantID, 376 "test_string": "Mi estas la pordo, mi estas la sxlosilo.", 377 "test_bool": false, 378 } 379 }) 380 381 JustBeforeEach(func() { 382 adminResource, err := manager.LoadResource(currentSchema.ID, adminResourceData) 383 Expect(err).NotTo(HaveOccurred()) 384 memberResource, err := manager.LoadResource(currentSchema.ID, memberResourceData) 385 Expect(err).NotTo(HaveOccurred()) 386 transaction, err := testDB.Begin() 387 Expect(err).NotTo(HaveOccurred()) 388 defer transaction.Close() 389 Expect(transaction.Create(adminResource)).To(Succeed()) 390 Expect(transaction.Create(memberResource)).To(Succeed()) 391 Expect(transaction.Commit()).To(Succeed()) 392 }) 393 394 Context("As an admin", func() { 395 It("Should return a filled list", func() { 396 err := resources.GetMultipleResources( 397 context, testDB, currentSchema, map[string][]string{}) 398 result := context["response"].(map[string]interface{}) 399 number := context["total"].(uint64) 400 Expect(err).NotTo(HaveOccurred()) 401 Expect(number).To(Equal(uint64(2))) 402 Expect(result).To(HaveKeyWithValue("tests", ConsistOf(adminResourceData, memberResourceData))) 403 }) 404 }) 405 406 Context("As a member", func() { 407 BeforeEach(func() { 408 auth = memberAuth 409 }) 410 411 It("Should return a only owned resources", func() { 412 err := resources.GetMultipleResources( 413 context, testDB, currentSchema, map[string][]string{}) 414 415 result := context["response"].(map[string]interface{}) 416 number := context["total"].(uint64) 417 Expect(err).NotTo(HaveOccurred()) 418 Expect(number).To(Equal(uint64(1))) 419 Expect(result).To(HaveKeyWithValue("tests", ConsistOf(adminResourceData))) 420 }) 421 }) 422 }) 423 }) 424 425 Describe("Showing a resource", func() { 426 BeforeEach(func() { 427 schemaID = "test" 428 action = "read" 429 }) 430 431 Describe("When there are no resources in the database", func() { 432 It("Should return an informative error", func() { 433 err := resources.GetSingleResource( 434 context, testDB, currentSchema, resourceID1) 435 Expect(err).To(HaveOccurred()) 436 _, ok := err.(resources.ResourceError) 437 Expect(ok).To(BeTrue()) 438 }) 439 440 Describe("With extensions", func() { 441 Context("Only pre_show", func() { 442 BeforeEach(func() { 443 events["pre_show"] = `context["response"] = {"respondo": "bona"};` 444 }) 445 446 It("Should run the extension", func() { 447 err := resources.GetSingleResource( 448 context, testDB, currentSchema, resourceID1) 449 result := context["response"].(map[string]interface{}) 450 Expect(err).NotTo(HaveOccurred()) 451 Expect(result).To(HaveKeyWithValue("respondo", "bona")) 452 }) 453 }) 454 455 Context("Only pre_show_in_transaction", func() { 456 BeforeEach(func() { 457 events["pre_show_in_transaction"] = `throw new CustomException("malbona", 390);` 458 }) 459 460 It("Should run the extension", func() { 461 err := resources.GetSingleResource( 462 context, testDB, currentSchema, resourceID1) 463 Expect(err).To(HaveOccurred()) 464 extErr, ok := err.(extension.Error) 465 Expect(ok).To(BeTrue()) 466 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("name", "CustomException")) 467 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("message", "malbona")) 468 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("code", int64(390))) 469 }) 470 }) 471 472 Context("Only post_show_in_transaction", func() { 473 BeforeEach(func() { 474 events["post_show_in_transaction"] = `throw new CustomException("tre malbona", 390);` 475 }) 476 477 It("Should not run the extension", func() { 478 err := resources.GetSingleResource( 479 context, testDB, currentSchema, resourceID1) 480 Expect(err).To(HaveOccurred()) 481 _, ok := err.(resources.ResourceError) 482 Expect(ok).To(BeTrue()) 483 }) 484 }) 485 486 Context("Only post_show", func() { 487 BeforeEach(func() { 488 events["post_show"] = `context["response"] = {"respondo": "tre bona"};` 489 }) 490 491 It("Should not run the extension", func() { 492 err := resources.GetSingleResource( 493 context, testDB, currentSchema, resourceID1) 494 Expect(err).To(HaveOccurred()) 495 _, ok := err.(resources.ResourceError) 496 Expect(ok).To(BeTrue()) 497 }) 498 }) 499 500 Context("With pre_show throwing exception", func() { 501 BeforeEach(func() { 502 events["pre_show"] = `throw new CustomException("malbona", 390);` 503 }) 504 505 It("Should run the extension", func() { 506 err := resources.GetSingleResource( 507 context, testDB, currentSchema, resourceID1) 508 Expect(err).To(HaveOccurred()) 509 extErr, ok := err.(extension.Error) 510 Expect(ok).To(BeTrue()) 511 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("name", "CustomException")) 512 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("message", "malbona")) 513 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("code", int64(390))) 514 }) 515 }) 516 517 }) 518 }) 519 520 Describe("When there are resources in the database", func() { 521 var ( 522 adminResourceData, memberResourceData map[string]interface{} 523 ) 524 525 BeforeEach(func() { 526 adminResourceData = map[string]interface{}{ 527 "id": resourceID1, 528 "tenant_id": adminTenantID, 529 "test_string": "Steloj estas en ordo.", 530 "test_bool": false, 531 } 532 memberResourceData = map[string]interface{}{ 533 "id": resourceID2, 534 "tenant_id": powerUserTenantID, 535 "test_string": "Mi estas la pordo, mi estas la sxlosilo.", 536 "test_bool": false, 537 } 538 }) 539 540 JustBeforeEach(func() { 541 adminResource, err := manager.LoadResource(currentSchema.ID, adminResourceData) 542 Expect(err).NotTo(HaveOccurred()) 543 memberResource, err := manager.LoadResource(currentSchema.ID, memberResourceData) 544 Expect(err).NotTo(HaveOccurred()) 545 transaction, err := testDB.Begin() 546 Expect(err).NotTo(HaveOccurred()) 547 defer transaction.Close() 548 Expect(transaction.Create(adminResource)).To(Succeed()) 549 Expect(transaction.Create(memberResource)).To(Succeed()) 550 Expect(transaction.Commit()).To(Succeed()) 551 }) 552 553 Context("As an admin", func() { 554 It("Should return owned resource", func() { 555 err := resources.GetSingleResource( 556 context, testDB, currentSchema, resourceID1) 557 result := context["response"].(map[string]interface{}) 558 Expect(err).NotTo(HaveOccurred()) 559 Expect(result).To(HaveKeyWithValue(schemaID, util.MatchAsJSON(adminResourceData))) 560 }) 561 562 It("Should return not owned resource", func() { 563 err := resources.GetSingleResource( 564 context, testDB, currentSchema, resourceID2) 565 result := context["response"].(map[string]interface{}) 566 Expect(err).NotTo(HaveOccurred()) 567 Expect(result).To(HaveKeyWithValue(schemaID, util.MatchAsJSON(memberResourceData))) 568 }) 569 }) 570 571 Context("As a member", func() { 572 BeforeEach(func() { 573 auth = memberAuth 574 }) 575 576 It("Should return owned resource", func() { 577 err := resources.GetSingleResource( 578 context, testDB, currentSchema, resourceID1) 579 result := context["response"].(map[string]interface{}) 580 Expect(err).NotTo(HaveOccurred()) 581 Expect(result).To(HaveKeyWithValue(schemaID, util.MatchAsJSON(adminResourceData))) 582 }) 583 584 It("Should not return not owned resource", func() { 585 err := resources.GetSingleResource( 586 context, testDB, currentSchema, resourceID2) 587 Expect(err).To(HaveOccurred()) 588 _, ok := err.(resources.ResourceError) 589 Expect(ok).To(BeTrue()) 590 }) 591 }) 592 593 Describe("With extensions", func() { 594 Context("Only pre_show", func() { 595 BeforeEach(func() { 596 events["pre_show"] = `context["response"] = {"respondo": "bona"};` 597 }) 598 599 It("Should run the extension", func() { 600 err := resources.GetSingleResource( 601 context, testDB, currentSchema, resourceID1) 602 result := context["response"].(map[string]interface{}) 603 Expect(err).NotTo(HaveOccurred()) 604 Expect(result).To(HaveKeyWithValue("respondo", "bona")) 605 }) 606 }) 607 608 Context("Only pre_show_in_transaction", func() { 609 BeforeEach(func() { 610 events["pre_show_in_transaction"] = `throw new CustomException("malbona", 390);` 611 }) 612 613 It("Should run the extension", func() { 614 err := resources.GetSingleResource( 615 context, testDB, currentSchema, resourceID1) 616 Expect(err).To(HaveOccurred()) 617 extErr, ok := err.(extension.Error) 618 Expect(ok).To(BeTrue()) 619 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("name", "CustomException")) 620 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("message", "malbona")) 621 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("code", int64(390))) 622 }) 623 }) 624 625 Context("Only post_show_in_transaction", func() { 626 BeforeEach(func() { 627 events["post_show_in_transaction"] = `throw new CustomException("tre malbona", 390);` 628 }) 629 630 It("Should run the extension", func() { 631 err := resources.GetSingleResource( 632 context, testDB, currentSchema, resourceID1) 633 Expect(err).To(HaveOccurred()) 634 extErr, ok := err.(extension.Error) 635 Expect(ok).To(BeTrue()) 636 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("name", "CustomException")) 637 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("message", "tre malbona")) 638 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("code", int64(390))) 639 }) 640 }) 641 642 Context("Only post_show", func() { 643 BeforeEach(func() { 644 events["post_show"] = `context["response"] = {"respondo": "tre bona"};` 645 }) 646 647 It("Should run the extension", func() { 648 err := resources.GetSingleResource( 649 context, testDB, currentSchema, resourceID1) 650 result := context["response"].(map[string]interface{}) 651 Expect(err).NotTo(HaveOccurred()) 652 Expect(result).To(HaveKeyWithValue("respondo", "tre bona")) 653 }) 654 }) 655 656 Context("With pre_show throwing exception", func() { 657 BeforeEach(func() { 658 events["pre_show"] = `throw new CustomException("malbona", 390);` 659 }) 660 661 It("Should run the extension", func() { 662 err := resources.GetSingleResource( 663 context, testDB, currentSchema, resourceID1) 664 Expect(err).To(HaveOccurred()) 665 extErr, ok := err.(extension.Error) 666 Expect(ok).To(BeTrue()) 667 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("name", "CustomException")) 668 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("message", "malbona")) 669 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("code", int64(390))) 670 }) 671 }) 672 673 Context("With post_show throwing exception", func() { 674 BeforeEach(func() { 675 events["post_show"] = `throw new CustomException("tre malbona", 390);` 676 }) 677 678 It("Should run the extension", func() { 679 err := resources.GetSingleResource( 680 context, testDB, currentSchema, resourceID1) 681 Expect(err).To(HaveOccurred()) 682 extErr, ok := err.(extension.Error) 683 Expect(ok).To(BeTrue()) 684 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("name", "CustomException")) 685 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("message", "tre malbona")) 686 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("code", int64(390))) 687 }) 688 }) 689 690 }) 691 }) 692 }) 693 694 Describe("Deleting a resource", func() { 695 BeforeEach(func() { 696 schemaID = "test" 697 action = "delete" 698 }) 699 700 Describe("When there are no resources in the database", func() { 701 It("Should return an informative error", func() { 702 err := resources.DeleteResource( 703 context, testDB, currentSchema, resourceID1) 704 Expect(err).To(HaveOccurred()) 705 _, ok := err.(resources.ResourceError) 706 Expect(ok).To(BeTrue()) 707 }) 708 709 Describe("With extensions", func() { 710 Context("Only pre_delete", func() { 711 BeforeEach(func() { 712 events["pre_delete"] = `throw new CustomException("bona", 390);` 713 }) 714 715 It("Should run the extension", func() { 716 err := resources.DeleteResource( 717 context, testDB, currentSchema, resourceID1) 718 Expect(err).To(HaveOccurred()) 719 extErr, ok := err.(extension.Error) 720 Expect(ok).To(BeTrue()) 721 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("name", "CustomException")) 722 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("message", "bona")) 723 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("code", int64(390))) 724 }) 725 }) 726 727 Context("Only pre_delete_in_transaction", func() { 728 BeforeEach(func() { 729 events["pre_delete_in_transaction"] = `throw new CustomException("malbona", 390);` 730 }) 731 732 It("Should not run the extension", func() { 733 err := resources.DeleteResource( 734 context, testDB, currentSchema, resourceID1) 735 Expect(err).To(HaveOccurred()) 736 _, ok := err.(resources.ResourceError) 737 Expect(ok).To(BeTrue()) 738 }) 739 }) 740 741 Context("Only post_delete_in_transaction", func() { 742 BeforeEach(func() { 743 events["post_delete_in_transaction"] = `throw new CustomException("tre malbona", 390);` 744 }) 745 746 It("Should not run the extension", func() { 747 err := resources.DeleteResource( 748 context, testDB, currentSchema, resourceID1) 749 Expect(err).To(HaveOccurred()) 750 _, ok := err.(resources.ResourceError) 751 Expect(ok).To(BeTrue()) 752 }) 753 }) 754 755 Context("Only post_delete", func() { 756 BeforeEach(func() { 757 events["post_delete"] = `throw new CustomException("tre bona", 390);` 758 }) 759 760 It("Should not run the extension", func() { 761 err := resources.DeleteResource( 762 context, testDB, currentSchema, resourceID1) 763 Expect(err).To(HaveOccurred()) 764 _, ok := err.(resources.ResourceError) 765 Expect(ok).To(BeTrue()) 766 }) 767 }) 768 }) 769 }) 770 771 Describe("When there are resources in the database", func() { 772 var ( 773 adminResourceData, memberResourceData map[string]interface{} 774 ) 775 776 BeforeEach(func() { 777 adminResourceData = map[string]interface{}{ 778 "id": resourceID1, 779 "tenant_id": adminTenantID, 780 "test_string": "Steloj estas en ordo.", 781 "test_bool": false, 782 } 783 memberResourceData = map[string]interface{}{ 784 "id": resourceID2, 785 "tenant_id": powerUserTenantID, 786 "test_string": "Mi estas la pordo, mi estas la sxlosilo.", 787 "test_bool": false, 788 } 789 }) 790 791 JustBeforeEach(func() { 792 adminResource, err := manager.LoadResource(currentSchema.ID, adminResourceData) 793 Expect(err).NotTo(HaveOccurred()) 794 memberResource, err := manager.LoadResource(currentSchema.ID, memberResourceData) 795 Expect(err).NotTo(HaveOccurred()) 796 transaction, err := testDB.Begin() 797 Expect(err).NotTo(HaveOccurred()) 798 defer transaction.Close() 799 Expect(transaction.Create(adminResource)).To(Succeed()) 800 Expect(transaction.Create(memberResource)).To(Succeed()) 801 Expect(transaction.Commit()).To(Succeed()) 802 }) 803 804 Context("As an admin", func() { 805 It("Should delete owned resource", func() { 806 Expect(resources.DeleteResource( 807 context, testDB, currentSchema, resourceID1)).To(Succeed()) 808 }) 809 810 It("Should delete not owned resource", func() { 811 Expect(resources.DeleteResource( 812 context, testDB, currentSchema, resourceID1)).To(Succeed()) 813 }) 814 }) 815 816 Context("As a member", func() { 817 BeforeEach(func() { 818 auth = memberAuth 819 }) 820 821 It("Should delete owned resource", func() { 822 Expect(resources.DeleteResource( 823 context, testDB, currentSchema, resourceID1)).To(Succeed()) 824 }) 825 826 It("Should not delete not owned resource", func() { 827 err := resources.DeleteResource( 828 context, testDB, currentSchema, resourceID2) 829 Expect(err).To(HaveOccurred()) 830 _, ok := err.(resources.ResourceError) 831 Expect(ok).To(BeTrue()) 832 }) 833 }) 834 835 Describe("With extensions", func() { 836 Context("Only pre_delete", func() { 837 BeforeEach(func() { 838 events["pre_delete"] = `throw new CustomException("bona", 390);` 839 }) 840 841 It("Should run the extension", func() { 842 err := resources.DeleteResource( 843 context, testDB, currentSchema, resourceID1) 844 Expect(err).To(HaveOccurred()) 845 extErr, ok := err.(extension.Error) 846 Expect(ok).To(BeTrue()) 847 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("name", "CustomException")) 848 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("message", "bona")) 849 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("code", int64(390))) 850 }) 851 }) 852 853 Context("Only pre_delete_in_transaction", func() { 854 BeforeEach(func() { 855 events["pre_delete_in_transaction"] = `throw new CustomException("malbona", 390);` 856 }) 857 858 It("Should run the extension", func() { 859 err := resources.DeleteResource( 860 context, testDB, currentSchema, resourceID1) 861 Expect(err).To(HaveOccurred()) 862 extErr, ok := err.(extension.Error) 863 Expect(ok).To(BeTrue()) 864 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("name", "CustomException")) 865 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("message", "malbona")) 866 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("code", int64(390))) 867 }) 868 }) 869 870 Context("Only post_delete_in_transaction", func() { 871 BeforeEach(func() { 872 events["post_delete_in_transaction"] = `throw new CustomException("tre malbona", 390);` 873 }) 874 875 It("Should run the extension", func() { 876 err := resources.DeleteResource( 877 context, testDB, currentSchema, resourceID1) 878 Expect(err).To(HaveOccurred()) 879 extErr, ok := err.(extension.Error) 880 Expect(ok).To(BeTrue()) 881 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("name", "CustomException")) 882 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("message", "tre malbona")) 883 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("code", int64(390))) 884 }) 885 }) 886 887 Context("Only post_delete", func() { 888 BeforeEach(func() { 889 events["post_delete"] = `throw new CustomException("tre bona", 390);` 890 }) 891 892 It("Should run the extension", func() { 893 err := resources.DeleteResource( 894 context, testDB, currentSchema, resourceID1) 895 Expect(err).To(HaveOccurred()) 896 extErr, ok := err.(extension.Error) 897 Expect(ok).To(BeTrue()) 898 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("name", "CustomException")) 899 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("message", "tre bona")) 900 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("code", int64(390))) 901 }) 902 }) 903 }) 904 }) 905 }) 906 907 Describe("Creating a resource", func() { 908 var ( 909 adminResourceData, memberResourceData map[string]interface{} 910 fakeIdentity middleware.IdentityService 911 ) 912 913 BeforeEach(func() { 914 schemaID = "test" 915 action = "create" 916 adminResourceData = map[string]interface{}{ 917 "id": resourceID1, 918 "tenant_id": adminTenantID, 919 "test_string": "Steloj estas en ordo.", 920 "test_bool": false, 921 } 922 memberResourceData = map[string]interface{}{ 923 "id": resourceID2, 924 "tenant_id": powerUserTenantID, 925 "test_string": "Mi estas la pordo, mi estas la sxlosilo.", 926 "test_bool": false, 927 } 928 fakeIdentity = &middleware.FakeIdentity{} 929 }) 930 931 Describe("When there are no resources in the database", func() { 932 Context("As an admin", func() { 933 It("Should create own resource", func() { 934 err := resources.CreateResource( 935 context, testDB, fakeIdentity, currentSchema, adminResourceData) 936 937 result := context["response"].(map[string]interface{}) 938 Expect(err).NotTo(HaveOccurred()) 939 Expect(result).To(HaveKeyWithValue(schemaID, util.MatchAsJSON(adminResourceData))) 940 }) 941 942 It("Should create not own resource", func() { 943 err := resources.CreateResource( 944 context, testDB, fakeIdentity, currentSchema, memberResourceData) 945 result := context["response"].(map[string]interface{}) 946 Expect(err).NotTo(HaveOccurred()) 947 Expect(result).To(HaveKeyWithValue(schemaID, util.MatchAsJSON(memberResourceData))) 948 }) 949 950 It("Should fill in an id", func() { 951 err := resources.CreateResource( 952 context, testDB, fakeIdentity, currentSchema, map[string]interface{}{"tenant_id": adminTenantID}) 953 Expect(err).NotTo(HaveOccurred()) 954 result := context["response"].(map[string]interface{}) 955 theResource, ok := result[schemaID] 956 Expect(ok).To(BeTrue()) 957 Expect(theResource).To(HaveKeyWithValue("tenant_id", adminTenantID)) 958 Expect(theResource).To(HaveKey("id")) 959 }) 960 961 It("Should fill in the tenant_id", func() { 962 err := resources.CreateResource( 963 context, testDB, fakeIdentity, currentSchema, map[string]interface{}{"id": resourceID1}) 964 result := context["response"].(map[string]interface{}) 965 Expect(err).NotTo(HaveOccurred()) 966 theResource, ok := result[schemaID] 967 Expect(ok).To(BeTrue()) 968 Expect(theResource).To(HaveKeyWithValue("tenant_id", adminTenantID)) 969 Expect(theResource).To(HaveKeyWithValue("id", resourceID1)) 970 }) 971 972 It("Should fill in id and tenant_id", func() { 973 err := resources.CreateResource( 974 context, testDB, fakeIdentity, currentSchema, map[string]interface{}{}) 975 Expect(err).NotTo(HaveOccurred()) 976 result := context["response"].(map[string]interface{}) 977 theResource, ok := result[schemaID] 978 Expect(ok).To(BeTrue()) 979 Expect(theResource).To(HaveKeyWithValue("tenant_id", adminTenantID)) 980 Expect(theResource).To(HaveKey("id")) 981 }) 982 983 It("Should replace empty id", func() { 984 err := resources.CreateResource( 985 context, testDB, fakeIdentity, currentSchema, map[string]interface{}{ 986 "id": "", 987 }) 988 Expect(err).NotTo(HaveOccurred()) 989 result := context["response"].(map[string]interface{}) 990 theResource, ok := result[schemaID] 991 resource := theResource.(map[string]interface{}) 992 Expect(ok).To(BeTrue()) 993 Expect(resource).To(HaveKeyWithValue("tenant_id", adminTenantID)) 994 Expect(resource).To(HaveKey("id")) 995 _, err = uuid.Parse(resource["id"].(string)) 996 Expect(err).ToNot(HaveOccurred()) 997 }) 998 }) 999 1000 Context("As a member", func() { 1001 BeforeEach(func() { 1002 auth = memberAuth 1003 }) 1004 1005 It("Should create own resource", func() { 1006 err := resources.CreateResource( 1007 context, testDB, fakeIdentity, currentSchema, adminResourceData) 1008 result := context["response"].(map[string]interface{}) 1009 Expect(err).NotTo(HaveOccurred()) 1010 Expect(result).To(HaveKeyWithValue(schemaID, util.MatchAsJSON(adminResourceData))) 1011 }) 1012 1013 It("Should not create not own resource", func() { 1014 err := resources.CreateResource( 1015 context, testDB, fakeIdentity, currentSchema, memberResourceData) 1016 Expect(err).To(HaveOccurred()) 1017 _, ok := err.(resources.ResourceError) 1018 Expect(ok).To(BeTrue()) 1019 }) 1020 }) 1021 1022 Describe("With extensions", func() { 1023 Context("Only pre_create", func() { 1024 BeforeEach(func() { 1025 events["pre_create"] = `throw new CustomException("bona", 390);` 1026 }) 1027 1028 It("Should run the extension", func() { 1029 err := resources.CreateResource( 1030 context, testDB, fakeIdentity, currentSchema, adminResourceData) 1031 Expect(err).To(HaveOccurred()) 1032 extErr, ok := err.(extension.Error) 1033 Expect(ok).To(BeTrue()) 1034 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("name", "CustomException")) 1035 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("message", "bona")) 1036 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("code", int64(390))) 1037 }) 1038 }) 1039 1040 Context("Only pre_create_in_transaction", func() { 1041 BeforeEach(func() { 1042 events["pre_create_in_transaction"] = `throw new CustomException("malbona", 390);` 1043 }) 1044 1045 It("Should run the extension", func() { 1046 err := resources.CreateResource( 1047 context, testDB, fakeIdentity, currentSchema, adminResourceData) 1048 Expect(err).To(HaveOccurred()) 1049 extErr, ok := err.(extension.Error) 1050 Expect(ok).To(BeTrue()) 1051 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("name", "CustomException")) 1052 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("message", "malbona")) 1053 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("code", int64(390))) 1054 }) 1055 }) 1056 1057 Context("Only post_create_in_transaction", func() { 1058 BeforeEach(func() { 1059 events["post_create_in_transaction"] = `throw new CustomException("tre malbona", 390);` 1060 }) 1061 1062 It("Should run the extension", func() { 1063 err := resources.CreateResource( 1064 context, testDB, fakeIdentity, currentSchema, adminResourceData) 1065 Expect(err).To(HaveOccurred()) 1066 extErr, ok := err.(extension.Error) 1067 Expect(ok).To(BeTrue()) 1068 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("name", "CustomException")) 1069 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("message", "tre malbona")) 1070 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("code", int64(390))) 1071 }) 1072 }) 1073 1074 Context("Only post_create", func() { 1075 BeforeEach(func() { 1076 events["post_create"] = `throw new CustomException("tre bona", 390);` 1077 }) 1078 1079 It("Should run the extension", func() { 1080 err := resources.CreateResource( 1081 context, testDB, fakeIdentity, currentSchema, adminResourceData) 1082 Expect(err).To(HaveOccurred()) 1083 extErr, ok := err.(extension.Error) 1084 Expect(ok).To(BeTrue()) 1085 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("name", "CustomException")) 1086 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("message", "tre bona")) 1087 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("code", int64(390))) 1088 }) 1089 }) 1090 1091 }) 1092 }) 1093 1094 Describe("When there are resources in the database", func() { 1095 JustBeforeEach(func() { 1096 adminResource, err := manager.LoadResource(currentSchema.ID, adminResourceData) 1097 Expect(err).NotTo(HaveOccurred()) 1098 memberResource, err := manager.LoadResource(currentSchema.ID, memberResourceData) 1099 Expect(err).NotTo(HaveOccurred()) 1100 transaction, err := testDB.Begin() 1101 Expect(err).NotTo(HaveOccurred()) 1102 defer transaction.Close() 1103 Expect(transaction.Create(adminResource)).To(Succeed()) 1104 Expect(transaction.Create(memberResource)).To(Succeed()) 1105 Expect(transaction.Commit()).To(Succeed()) 1106 }) 1107 1108 It("Should not create duplicate resource", func() { 1109 err := resources.CreateResource( 1110 context, testDB, fakeIdentity, currentSchema, adminResourceData) 1111 Expect(err).To(HaveOccurred()) 1112 _, ok := err.(resources.ResourceError) 1113 Expect(ok).To(BeTrue()) 1114 }) 1115 }) 1116 }) 1117 1118 Describe("Updating a resource", func() { 1119 var ( 1120 adminResourceData, memberResourceData map[string]interface{} 1121 fakeIdentity middleware.IdentityService 1122 ) 1123 1124 BeforeEach(func() { 1125 schemaID = "test" 1126 action = "create" 1127 adminResourceData = map[string]interface{}{ 1128 "id": resourceID1, 1129 "tenant_id": adminTenantID, 1130 "test_string": "Steloj estas en ordo.", 1131 "test_bool": false, 1132 } 1133 memberResourceData = map[string]interface{}{ 1134 "id": resourceID2, 1135 "tenant_id": powerUserTenantID, 1136 "test_string": "Mi estas la pordo, mi estas la sxlosilo.", 1137 "test_bool": false, 1138 } 1139 fakeIdentity = &middleware.FakeIdentity{} 1140 }) 1141 1142 Describe("When there are no resources in the database", func() { 1143 It("Should return an informative error", func() { 1144 err := resources.UpdateResource( 1145 context, testDB, fakeIdentity, currentSchema, resourceID1, adminResourceData) 1146 Expect(err).To(HaveOccurred()) 1147 _, ok := err.(resources.ResourceError) 1148 Expect(ok).To(BeTrue()) 1149 }) 1150 1151 Describe("With extensions", func() { 1152 Context("Only pre_update", func() { 1153 BeforeEach(func() { 1154 events["pre_update"] = `throw new CustomException("bona", 390);` 1155 }) 1156 1157 It("Should run the extension", func() { 1158 err := resources.UpdateResource( 1159 context, testDB, fakeIdentity, currentSchema, resourceID1, adminResourceData) 1160 Expect(err).To(HaveOccurred()) 1161 extErr, ok := err.(extension.Error) 1162 Expect(ok).To(BeTrue()) 1163 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("name", "CustomException")) 1164 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("message", "bona")) 1165 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("code", int64(390))) 1166 }) 1167 }) 1168 1169 Context("Only pre_update_in_transaction", func() { 1170 BeforeEach(func() { 1171 events["pre_update_in_transaction"] = `throw new CustomException("malbona", 390);` 1172 }) 1173 1174 It("Should not run the extension", func() { 1175 err := resources.UpdateResource( 1176 context, testDB, fakeIdentity, currentSchema, resourceID1, adminResourceData) 1177 Expect(err).To(HaveOccurred()) 1178 _, ok := err.(resources.ResourceError) 1179 Expect(ok).To(BeTrue()) 1180 }) 1181 }) 1182 1183 Context("Only post_update_in_transaction", func() { 1184 BeforeEach(func() { 1185 events["post_update_in_transaction"] = `throw new CustomException("tre malbona", 390);` 1186 }) 1187 1188 It("Should not run the extension", func() { 1189 err := resources.UpdateResource( 1190 context, testDB, fakeIdentity, currentSchema, resourceID1, adminResourceData) 1191 Expect(err).To(HaveOccurred()) 1192 _, ok := err.(resources.ResourceError) 1193 Expect(ok).To(BeTrue()) 1194 }) 1195 }) 1196 1197 Context("Only post_update", func() { 1198 BeforeEach(func() { 1199 events["post_update"] = `throw new CustomException("tre bona", 390);` 1200 }) 1201 1202 It("Should not run the extension", func() { 1203 err := resources.UpdateResource( 1204 context, testDB, fakeIdentity, currentSchema, resourceID1, adminResourceData) 1205 Expect(err).To(HaveOccurred()) 1206 _, ok := err.(resources.ResourceError) 1207 Expect(ok).To(BeTrue()) 1208 }) 1209 }) 1210 }) 1211 }) 1212 1213 Describe("When there are resources in the database", func() { 1214 JustBeforeEach(func() { 1215 adminResource, err := manager.LoadResource(currentSchema.ID, adminResourceData) 1216 Expect(err).NotTo(HaveOccurred()) 1217 memberResource, err := manager.LoadResource(currentSchema.ID, memberResourceData) 1218 Expect(err).NotTo(HaveOccurred()) 1219 transaction, err := testDB.Begin() 1220 Expect(err).NotTo(HaveOccurred()) 1221 defer transaction.Close() 1222 Expect(transaction.Create(adminResource)).To(Succeed()) 1223 Expect(transaction.Create(memberResource)).To(Succeed()) 1224 Expect(transaction.Commit()).To(Succeed()) 1225 }) 1226 1227 Context("As an admin", func() { 1228 It("Should update own resource", func() { 1229 err := resources.UpdateResource( 1230 context, testDB, fakeIdentity, currentSchema, resourceID1, 1231 map[string]interface{}{"test_string": "Steloj ne estas en ordo."}) 1232 result := context["response"].(map[string]interface{}) 1233 Expect(err).NotTo(HaveOccurred()) 1234 theResource, ok := result[schemaID] 1235 Expect(ok).To(BeTrue()) 1236 Expect(theResource).To(HaveKeyWithValue("test_string", "Steloj ne estas en ordo.")) 1237 }) 1238 1239 It("Should update not own resource", func() { 1240 err := resources.UpdateResource( 1241 context, testDB, fakeIdentity, currentSchema, resourceID1, 1242 map[string]interface{}{"test_string": "Ia, ia, HJPEV fhtang!"}) 1243 result := context["response"].(map[string]interface{}) 1244 Expect(err).NotTo(HaveOccurred()) 1245 theResource, ok := result[schemaID] 1246 Expect(ok).To(BeTrue()) 1247 Expect(theResource).To(HaveKeyWithValue("test_string", "Ia, ia, HJPEV fhtang!")) 1248 }) 1249 }) 1250 1251 Context("As a member", func() { 1252 BeforeEach(func() { 1253 auth = memberAuth 1254 }) 1255 1256 It("Should update own resource", func() { 1257 err := resources.UpdateResource( 1258 context, testDB, fakeIdentity, currentSchema, resourceID1, 1259 map[string]interface{}{"test_string": "Steloj ne estas en ordo."}) 1260 result := context["response"].(map[string]interface{}) 1261 Expect(err).NotTo(HaveOccurred()) 1262 theResource, ok := result[schemaID] 1263 Expect(ok).To(BeTrue()) 1264 Expect(theResource).To(HaveKeyWithValue("test_string", "Steloj ne estas en ordo.")) 1265 }) 1266 1267 It("Should not update not own resource", func() { 1268 err := resources.UpdateResource( 1269 context, testDB, fakeIdentity, currentSchema, resourceID2, 1270 map[string]interface{}{"test_string": "Ia, ia, HWCBN fhtang!"}) 1271 resource, _ := context["response"].(map[string]interface{}) 1272 Expect(resource).To(BeNil()) 1273 Expect(err).To(HaveOccurred()) 1274 _, ok := err.(resources.ResourceError) 1275 Expect(ok).To(BeTrue()) 1276 }) 1277 }) 1278 1279 Describe("With extensions", func() { 1280 Context("Only pre_update", func() { 1281 BeforeEach(func() { 1282 events["pre_update"] = `throw new CustomException("bona", 390);` 1283 }) 1284 1285 It("Should run the extension", func() { 1286 err := resources.UpdateResource( 1287 context, testDB, fakeIdentity, currentSchema, resourceID1, 1288 map[string]interface{}{"test_string": "Steloj ne estas en ordo."}) 1289 Expect(err).To(HaveOccurred()) 1290 extErr, ok := err.(extension.Error) 1291 Expect(ok).To(BeTrue()) 1292 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("name", "CustomException")) 1293 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("message", "bona")) 1294 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("code", int64(390))) 1295 }) 1296 }) 1297 1298 Context("Only pre_update_in_transaction", func() { 1299 BeforeEach(func() { 1300 events["pre_update_in_transaction"] = `throw new CustomException("malbona", 390);` 1301 }) 1302 1303 It("Should run the extension", func() { 1304 err := resources.UpdateResource( 1305 context, testDB, fakeIdentity, currentSchema, resourceID1, 1306 map[string]interface{}{"test_string": "Steloj ne estas en ordo."}) 1307 Expect(err).To(HaveOccurred()) 1308 extErr, ok := err.(extension.Error) 1309 Expect(ok).To(BeTrue()) 1310 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("name", "CustomException")) 1311 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("message", "malbona")) 1312 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("code", int64(390))) 1313 }) 1314 }) 1315 1316 Context("Only post_update_in_transaction", func() { 1317 BeforeEach(func() { 1318 events["post_update_in_transaction"] = `throw new CustomException("tre malbona", 390);` 1319 }) 1320 1321 It("Should run the extension", func() { 1322 err := resources.UpdateResource( 1323 context, testDB, fakeIdentity, currentSchema, resourceID1, 1324 map[string]interface{}{"test_string": "Steloj ne estas en ordo."}) 1325 Expect(err).To(HaveOccurred()) 1326 extErr, ok := err.(extension.Error) 1327 Expect(ok).To(BeTrue()) 1328 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("name", "CustomException")) 1329 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("message", "tre malbona")) 1330 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("code", int64(390))) 1331 }) 1332 }) 1333 1334 Context("Only post_update", func() { 1335 BeforeEach(func() { 1336 events["post_update"] = `throw new CustomException("tre bona", 390);` 1337 }) 1338 1339 It("Should run the extension", func() { 1340 err := resources.UpdateResource( 1341 context, testDB, fakeIdentity, currentSchema, resourceID1, 1342 map[string]interface{}{"test_string": "Steloj ne estas en ordo."}) 1343 Expect(err).To(HaveOccurred()) 1344 extErr, ok := err.(extension.Error) 1345 Expect(ok).To(BeTrue()) 1346 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("name", "CustomException")) 1347 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("message", "tre bona")) 1348 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("code", int64(390))) 1349 }) 1350 }) 1351 1352 }) 1353 }) 1354 }) 1355 1356 Describe("Running an action on a resource", func() { 1357 var ( 1358 adminResourceData map[string]interface{} 1359 fakeIdentity middleware.IdentityService 1360 fakeAction schema.Action 1361 fakeActionWithoutInput schema.Action 1362 ) 1363 1364 BeforeEach(func() { 1365 schemaID = "test" 1366 action = "create" 1367 adminResourceData = map[string]interface{}{ 1368 "id": resourceID1, 1369 "tenant_id": adminTenantID, 1370 "test_string": "Steloj estas en ordo.", 1371 "test_bool": false, 1372 } 1373 fakeIdentity = &middleware.FakeIdentity{} 1374 inputSchema := map[string]interface{}{ 1375 "type": "object", 1376 "properties": map[string]interface{}{ 1377 "message": map[string]interface{}{ 1378 "type": "string", 1379 }, 1380 "delay": map[string]interface{}{ 1381 "type": "string", 1382 }, 1383 }, 1384 } 1385 fakeAction = schema.NewAction("fake_action", "GET", "/:id/whatever", inputSchema, nil) 1386 fakeActionWithoutInput = schema.NewAction("fake_action", "GET", "/:id/whatever", nil, nil) 1387 }) 1388 1389 // Actions do not care resource existence or tenant ownership 1390 Describe("With extension", func() { 1391 BeforeEach(func() { 1392 events["fake_action"] = `throw new CustomException("malbona", 390);` 1393 }) 1394 1395 It("Should run the extension", func() { 1396 err := resources.ActionResource( 1397 context, testDB, fakeIdentity, currentSchema, fakeAction, resourceID1, 1398 map[string]interface{}{"test_string": "Steloj ne estas en ordo."}) 1399 Expect(err).To(HaveOccurred()) 1400 extErr, ok := err.(extension.Error) 1401 Expect(ok).To(BeTrue()) 1402 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("name", "CustomException")) 1403 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("message", "malbona")) 1404 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("code", int64(390))) 1405 }) 1406 1407 Context("Without input shcema", func() { 1408 It("Should run the extension", func() { 1409 err := resources.ActionResource( 1410 context, testDB, fakeIdentity, currentSchema, fakeActionWithoutInput, resourceID1, 1411 map[string]interface{}{"test_string": "Steloj ne estas en ordo."}) 1412 Expect(err).To(HaveOccurred()) 1413 extErr, ok := err.(extension.Error) 1414 Expect(ok).To(BeTrue()) 1415 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("name", "CustomException")) 1416 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("message", "malbona")) 1417 Expect(extErr.ExceptionInfo).To(HaveKeyWithValue("code", int64(390))) 1418 }) 1419 }) 1420 }) 1421 }) 1422 1423 Describe("Executing a sequence of operations", func() { 1424 var ( 1425 adminResourceData, memberResourceData map[string]interface{} 1426 listContext, showContext, deleteContext, createContext, updateContext middleware.Context 1427 fakeIdentity middleware.IdentityService 1428 ) 1429 1430 BeforeEach(func() { 1431 schemaID = "test" 1432 action = "list" 1433 adminResourceData = map[string]interface{}{ 1434 "id": resourceID1, 1435 "tenant_id": adminTenantID, 1436 "test_string": "Steloj estas en ordo.", 1437 "test_bool": false, 1438 } 1439 memberResourceData = map[string]interface{}{ 1440 "id": resourceID2, 1441 "tenant_id": powerUserTenantID, 1442 "test_string": "Mi estas la pordo, mi estas la sxlosilo.", 1443 "test_bool": false, 1444 } 1445 listContext = middleware.Context{} 1446 showContext = middleware.Context{} 1447 deleteContext = middleware.Context{} 1448 createContext = middleware.Context{} 1449 updateContext = middleware.Context{} 1450 fakeIdentity = &middleware.FakeIdentity{} 1451 }) 1452 1453 JustBeforeEach(func() { 1454 policy, role := manager.PolicyValidate("list", path, auth) 1455 Expect(policy).NotTo(BeNil()) 1456 listContext["policy"] = policy 1457 listContext["role"] = role 1458 listContext["tenant_id"] = auth.TenantID() 1459 listContext["tenant_name"] = auth.TenantName() 1460 listContext["auth_token"] = auth.AuthToken() 1461 listContext["catalog"] = auth.Catalog() 1462 listContext["auth"] = auth 1463 policy, role = manager.PolicyValidate("show", path, auth) 1464 Expect(policy).NotTo(BeNil()) 1465 showContext["policy"] = policy 1466 showContext["role"] = role 1467 showContext["tenant_id"] = auth.TenantID() 1468 showContext["tenant_name"] = auth.TenantName() 1469 showContext["auth_token"] = auth.AuthToken() 1470 showContext["catalog"] = auth.Catalog() 1471 showContext["auth"] = auth 1472 policy, role = manager.PolicyValidate("delete", path, auth) 1473 Expect(policy).NotTo(BeNil()) 1474 deleteContext["policy"] = policy 1475 deleteContext["role"] = role 1476 deleteContext["tenant_id"] = auth.TenantID() 1477 deleteContext["tenant_name"] = auth.TenantName() 1478 deleteContext["auth_token"] = auth.AuthToken() 1479 deleteContext["catalog"] = auth.Catalog() 1480 deleteContext["auth"] = auth 1481 policy, role = manager.PolicyValidate("create", path, auth) 1482 Expect(policy).NotTo(BeNil()) 1483 createContext["policy"] = policy 1484 createContext["role"] = role 1485 createContext["tenant_id"] = auth.TenantID() 1486 createContext["tenant_name"] = auth.TenantName() 1487 createContext["auth_token"] = auth.AuthToken() 1488 createContext["catalog"] = auth.Catalog() 1489 createContext["auth"] = auth 1490 policy, role = manager.PolicyValidate("update", path, auth) 1491 Expect(policy).NotTo(BeNil()) 1492 updateContext["policy"] = policy 1493 updateContext["role"] = role 1494 updateContext["tenant_id"] = auth.TenantID() 1495 updateContext["tenant_name"] = auth.TenantName() 1496 updateContext["auth_token"] = auth.AuthToken() 1497 updateContext["catalog"] = auth.Catalog() 1498 updateContext["auth"] = auth 1499 }) 1500 1501 It("Should behave as expected", func() { 1502 By("Showing nothing in an empty database") 1503 err := resources.GetMultipleResources( 1504 listContext, testDB, currentSchema, map[string][]string{}) 1505 1506 result, _ := listContext["response"].(map[string]interface{}) 1507 number, _ := listContext["total"].(uint64) 1508 Expect(err).NotTo(HaveOccurred()) 1509 Expect(number).To(Equal(uint64(0))) 1510 Expect(result).To(HaveKeyWithValue("tests", BeEmpty())) 1511 delete(listContext, "response") 1512 1513 By("Successfully adding a resource to the database") 1514 err = resources.CreateResource( 1515 createContext, testDB, fakeIdentity, currentSchema, adminResourceData) 1516 result = createContext["response"].(map[string]interface{}) 1517 Expect(err).NotTo(HaveOccurred()) 1518 Expect(result).To(HaveKeyWithValue(schemaID, util.MatchAsJSON(adminResourceData))) 1519 1520 By("Listing the added resource") 1521 err = resources.GetMultipleResources( 1522 listContext, testDB, currentSchema, map[string][]string{}) 1523 result = listContext["response"].(map[string]interface{}) 1524 number = listContext["total"].(uint64) 1525 1526 Expect(err).NotTo(HaveOccurred()) 1527 Expect(number).To(Equal(uint64(1))) 1528 Expect(result).To(HaveKeyWithValue("tests", ConsistOf(util.MatchAsJSON(adminResourceData)))) 1529 1530 By("Updating the resource") 1531 err = resources.UpdateResource( 1532 updateContext, testDB, fakeIdentity, currentSchema, resourceID1, 1533 map[string]interface{}{"test_string": "Steloj ne estas en ordo."}) 1534 result = updateContext["response"].(map[string]interface{}) 1535 Expect(err).NotTo(HaveOccurred()) 1536 Expect(result).To(HaveKeyWithValue(schemaID, HaveKeyWithValue("test_string", "Steloj ne estas en ordo."))) 1537 1538 By("Showing the updated resource") 1539 err = resources.GetSingleResource( 1540 showContext, testDB, currentSchema, resourceID1) 1541 result = showContext["response"].(map[string]interface{}) 1542 By(fmt.Sprintf("%s", result)) 1543 Expect(err).NotTo(HaveOccurred()) 1544 Expect(result).To(HaveKeyWithValue(schemaID, HaveKeyWithValue("test_string", "Steloj ne estas en ordo."))) 1545 1546 By("Deleting the resource") 1547 By(resourceID1) 1548 Expect(resources.DeleteResource( 1549 deleteContext, testDB, currentSchema, resourceID1)).To(Succeed()) 1550 1551 By("Again showing nothing in an empty database") 1552 delete(listContext, "response") 1553 err = resources.GetMultipleResources( 1554 listContext, testDB, currentSchema, map[string][]string{}) 1555 result = listContext["response"].(map[string]interface{}) 1556 By(fmt.Sprintf("%s", result)) 1557 number = listContext["total"].(uint64) 1558 Expect(err).NotTo(HaveOccurred()) 1559 Expect(number).To(Equal(uint64(0))) 1560 Expect(result).To(HaveKeyWithValue("tests", BeEmpty())) 1561 }) 1562 }) 1563 })