github.com/kisexp/xdchain@v0.0.0-20211206025815-490d6b732aa7/private/engine/tessera/tessera_test.go (about) 1 package tessera 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io/ioutil" 7 "net/http" 8 "net/http/httptest" 9 "net/url" 10 "os" 11 "strings" 12 "testing" 13 14 "github.com/kisexp/xdchain/common" 15 "github.com/kisexp/xdchain/private/engine" 16 testifyassert "github.com/stretchr/testify/assert" 17 ) 18 19 var ( 20 emptyHash = common.EncryptedPayloadHash{} 21 arbitraryHash = common.BytesToEncryptedPayloadHash([]byte("arbitrary")) 22 arbitraryHash1 = common.BytesToEncryptedPayloadHash([]byte("arbitrary1")) 23 arbitraryNotFoundHash = common.BytesToEncryptedPayloadHash([]byte("not found")) 24 arbitraryHashNoPrivateMetadata = common.BytesToEncryptedPayloadHash([]byte("no private extra data")) 25 arbitraryPrivatePayload = []byte("arbitrary private payload") 26 arbitraryFrom = "arbitraryFrom" 27 arbitraryTo = []string{"arbitraryTo1", "arbitraryTo2"} 28 arbitraryMandatory = []string{"arbitraryTo2"} 29 arbitraryPrivacyFlag = engine.PrivacyFlagPartyProtection 30 arbitraryExtra = &engine.ExtraMetadata{ 31 ACHashes: Must(common.Base64sToEncryptedPayloadHashes([]string{arbitraryHash.ToBase64()})).(common.EncryptedPayloadHashes), 32 ACMerkleRoot: common.StringToHash("arbitrary root hash"), 33 PrivacyFlag: arbitraryPrivacyFlag, 34 } 35 arbitraryExtraWithMandatoryFor = &engine.ExtraMetadata{ 36 ACHashes: Must(common.Base64sToEncryptedPayloadHashes([]string{arbitraryHash.ToBase64()})).(common.EncryptedPayloadHashes), 37 PrivacyFlag: engine.PrivacyFlagMandatoryRecipients, 38 MandatoryRecipients: arbitraryMandatory, 39 } 40 41 testServer *httptest.Server 42 testObject *tesseraPrivateTxManager 43 44 sendRequestCaptor = make(chan *capturedRequest) 45 receiveRequestCaptor = make(chan *capturedRequest) 46 sendSignedTxRequestCaptor = make(chan *capturedRequest) 47 sendSignedTxOctetStreamRequestCaptor = make(chan *capturedRequest) 48 getMandatoryRequestCaptor = make(chan *capturedRequest) 49 ) 50 51 type capturedRequest struct { 52 err error 53 request interface{} 54 header http.Header 55 } 56 57 func TestMain(m *testing.M) { 58 setup() 59 retCode := m.Run() 60 teardown() 61 os.Exit(retCode) 62 } 63 64 func Must(o interface{}, err error) interface{} { 65 if err != nil { 66 panic(fmt.Sprintf("%s", err)) 67 } 68 return o 69 } 70 71 func setup() { 72 mux := http.NewServeMux() 73 mux.HandleFunc("/send", MockSendAPIHandlerFunc) 74 mux.HandleFunc("/transaction/", MockTransactionAPIHandlerFunc) 75 mux.HandleFunc("/sendsignedtx", MockSendSignedTxAPIHandlerFunc) 76 mux.HandleFunc("/groups/resident", MockGroupsAPIHandlerFunc) 77 78 testServer = httptest.NewServer(mux) 79 80 testObject = New(&engine.Client{ 81 HttpClient: &http.Client{}, 82 BaseURL: testServer.URL, 83 }, []byte("2.0.0")) 84 } 85 86 func MockGroupsAPIHandlerFunc(response http.ResponseWriter, request *http.Request) { 87 var data []byte 88 data, _ = json.Marshal([]engine.PrivacyGroup{ 89 { 90 Type: "RESIDENT", 91 Name: "RG1", 92 PrivacyGroupId: "RG1", 93 Description: "Resident Group 1", 94 From: "", 95 Members: []string{"AAA", "BBB"}, 96 }, 97 { 98 Type: "LEGACY", 99 Name: "LEGACY1", 100 PrivacyGroupId: "LEGACY1", 101 Description: "Legacy Group 1", 102 From: "", 103 Members: []string{"LEG1", "LEG2"}, 104 }, 105 { 106 Type: "PANTHEON", 107 Name: "P1", 108 PrivacyGroupId: "P1", 109 Description: "Pantheon Group 1", 110 From: "", 111 Members: []string{"P1", "P2"}, 112 }, 113 }) 114 response.Write(data) 115 } 116 117 func MockSendAPIHandlerFunc(response http.ResponseWriter, request *http.Request) { 118 actualRequest := new(sendRequest) 119 if err := json.NewDecoder(request.Body).Decode(actualRequest); err != nil { 120 go func(o *capturedRequest) { sendRequestCaptor <- o }(&capturedRequest{err: err}) 121 } else { 122 go func(o *capturedRequest) { sendRequestCaptor <- o }(&capturedRequest{request: actualRequest, header: request.Header}) 123 data, _ := json.Marshal(&sendResponse{ 124 Key: arbitraryHash.ToBase64(), 125 ManagedParties: []string{"ArbitraryPublicKey"}, 126 }) 127 response.Write(data) 128 } 129 } 130 131 func MockTransactionAPIHandlerFunc(response http.ResponseWriter, request *http.Request) { 132 if strings.HasSuffix(request.RequestURI, "/mandatory") { 133 MockGetMandatoryAPIHandlerFunc(response, request) 134 } else { 135 MockReceiveAPIHandlerFunc(response, request) 136 } 137 } 138 139 func MockGetMandatoryAPIHandlerFunc(response http.ResponseWriter, request *http.Request) { 140 actualRequest, err := url.PathUnescape(strings.TrimSuffix(strings.TrimPrefix(request.RequestURI, "/transaction/"), "/mandatory")) 141 if err != nil { 142 go func(o *capturedRequest) { getMandatoryRequestCaptor <- o }(&capturedRequest{err: err}) 143 } else { 144 go func(o *capturedRequest) { 145 getMandatoryRequestCaptor <- o 146 }(&capturedRequest{request: actualRequest, header: request.Header}) 147 if actualRequest == arbitraryNotFoundHash.ToBase64() { 148 response.WriteHeader(http.StatusNotFound) 149 } else { 150 response.Write([]byte(strings.Join(arbitraryMandatory, ","))) 151 } 152 } 153 } 154 155 func MockReceiveAPIHandlerFunc(response http.ResponseWriter, request *http.Request) { 156 path := string([]byte(request.RequestURI)[:strings.LastIndex(request.RequestURI, "?")]) 157 actualRequest, err := url.PathUnescape(strings.TrimPrefix(path, "/transaction/")) 158 if err != nil { 159 go func(o *capturedRequest) { sendRequestCaptor <- o }(&capturedRequest{err: err}) 160 } else { 161 go func(o *capturedRequest) { 162 receiveRequestCaptor <- o 163 }(&capturedRequest{request: actualRequest, header: request.Header}) 164 if actualRequest == arbitraryNotFoundHash.ToBase64() { 165 response.WriteHeader(http.StatusNotFound) 166 } else { 167 var data []byte 168 if actualRequest == arbitraryHashNoPrivateMetadata.ToBase64() { 169 data, _ = json.Marshal(&receiveResponse{ 170 Payload: arbitraryPrivatePayload, 171 ManagedParties: []string{"ArbitraryPublicKey"}, 172 }) 173 } else { 174 data, _ = json.Marshal(&receiveResponse{ 175 Payload: arbitraryPrivatePayload, 176 ExecHash: arbitraryExtra.ACMerkleRoot.ToBase64(), 177 AffectedContractTransactions: arbitraryExtra.ACHashes.ToBase64s(), 178 PrivacyFlag: arbitraryPrivacyFlag, 179 ManagedParties: []string{"ArbitraryPublicKey"}, 180 }) 181 } 182 response.Write(data) 183 } 184 } 185 } 186 187 func MockSendSignedTxAPIHandlerFunc(response http.ResponseWriter, request *http.Request) { 188 actualRequest := new(sendSignedTxRequest) 189 if err := json.NewDecoder(request.Body).Decode(actualRequest); err != nil { 190 go func(o *capturedRequest) { sendSignedTxRequestCaptor <- o }(&capturedRequest{err: err}) 191 } else { 192 go func(o *capturedRequest) { sendSignedTxRequestCaptor <- o }(&capturedRequest{request: actualRequest, header: request.Header}) 193 data, _ := json.Marshal(&sendSignedTxResponse{ 194 Key: arbitraryHash.ToBase64(), 195 }) 196 response.Write(data) 197 } 198 } 199 200 func MockSendSignedTxOctetStreamAPIHandlerFunc(response http.ResponseWriter, request *http.Request) { 201 actualRequest := new(sendSignedTxRequest) 202 reqHash, err := ioutil.ReadAll(request.Body) 203 if err != nil { 204 go func(o *capturedRequest) { sendSignedTxOctetStreamRequestCaptor <- o }(&capturedRequest{err: err}) 205 return 206 } 207 actualRequest.Hash = reqHash 208 actualRequest.To = strings.Split(request.Header["C11n-To"][0], ",") 209 210 go func(o *capturedRequest) { sendSignedTxOctetStreamRequestCaptor <- o }(&capturedRequest{request: actualRequest, header: request.Header}) 211 response.Write([]byte(common.BytesToEncryptedPayloadHash(reqHash).ToBase64())) 212 } 213 214 func teardown() { 215 testServer.Close() 216 } 217 218 func verifyRequestHeader(h http.Header, t *testing.T) { 219 if h.Get("Content-type") != "application/json" { 220 t.Errorf("expected Content-type header is application/json") 221 } 222 223 if h.Get("Accept") != "application/json" { 224 t.Errorf("expected Accept header is application/json") 225 } 226 } 227 228 func verifyRequestHeaderMultiTenancy(h http.Header, t *testing.T) { 229 if h.Get("Content-type") != "application/vnd.tessera-2.1+json" { 230 t.Errorf("expected Content-type header is application/vnd.tessera-2.1+json") 231 } 232 233 if h.Get("Accept") != "application/vnd.tessera-2.1+json" { 234 t.Errorf("expected Accept header is application/vnd.tessera-2.1+json") 235 } 236 } 237 238 func verifyRequestHeaderMandatoryRecipients(h http.Header, t *testing.T) { 239 if h.Get("Content-type") != "application/vnd.tessera-4.0+json" { 240 t.Errorf("expected Content-type header is application/vnd.tessera-4.0+json") 241 } 242 243 if h.Get("Accept") != "application/vnd.tessera-4.0+json" { 244 t.Errorf("expected Accept header is application/vnd.tessera-4.0+json") 245 } 246 } 247 248 func TestSend_groups(t *testing.T) { 249 assert := testifyassert.New(t) 250 251 groups, err := testObject.Groups() 252 if err != nil { 253 t.Fatalf("%s", err) 254 } 255 256 assert.Len(groups, 3, "There should be three groups") 257 258 assert.Equal(groups[0].Name, "RG1") 259 assert.Equal(groups[0].PrivacyGroupId, "RG1") 260 assert.Equal(groups[0].Type, "RESIDENT") 261 assert.Exactly(groups[0].Members, []string{"AAA", "BBB"}) 262 263 assert.Equal(groups[1].Name, "LEGACY1") 264 assert.Equal(groups[1].PrivacyGroupId, "LEGACY1") 265 assert.Equal(groups[1].Type, "LEGACY") 266 assert.Exactly(groups[1].Members, []string{"LEG1", "LEG2"}) 267 268 assert.Equal(groups[2].Name, "P1") 269 assert.Equal(groups[2].PrivacyGroupId, "P1") 270 assert.Equal(groups[2].Type, "PANTHEON") 271 assert.Exactly(groups[2].Members, []string{"P1", "P2"}) 272 273 } 274 275 func TestSend_whenTypical(t *testing.T) { 276 assert := testifyassert.New(t) 277 278 _, _, actualHash, err := testObject.Send(arbitraryPrivatePayload, arbitraryFrom, arbitraryTo, arbitraryExtra) 279 if err != nil { 280 t.Fatalf("%s", err) 281 } 282 capturedRequest := <-sendRequestCaptor 283 284 if capturedRequest.err != nil { 285 t.Fatalf("%s", capturedRequest.err) 286 } 287 288 verifyRequestHeader(capturedRequest.header, t) 289 290 actualRequest := capturedRequest.request.(*sendRequest) 291 292 assert.Equal(arbitraryPrivatePayload, actualRequest.Payload, "request.payload") 293 assert.Equal(arbitraryFrom, actualRequest.From, "request.from") 294 assert.Equal(arbitraryTo, actualRequest.To, "request.to") 295 assert.Equal(arbitraryPrivacyFlag, actualRequest.PrivacyFlag, "request.privacyFlag") 296 assert.Equal(arbitraryExtra.ACHashes.ToBase64s(), actualRequest.AffectedContractTransactions, "request.affectedContractTransactions") 297 assert.Equal(arbitraryExtra.ACMerkleRoot.ToBase64(), actualRequest.ExecHash, "request.execHash") 298 assert.Equal(arbitraryHash, actualHash, "returned hash") 299 } 300 301 func TestSend_whenTypical_MultiTenancy(t *testing.T) { 302 assert := testifyassert.New(t) 303 304 testObjectWithMT := New(&engine.Client{ 305 HttpClient: &http.Client{}, 306 BaseURL: testServer.URL, 307 }, []byte("2.1")) 308 309 _, _, actualHash, err := testObjectWithMT.Send(arbitraryPrivatePayload, arbitraryFrom, arbitraryTo, arbitraryExtra) 310 if err != nil { 311 t.Fatalf("%s", err) 312 } 313 capturedRequest := <-sendRequestCaptor 314 315 if capturedRequest.err != nil { 316 t.Fatalf("%s", capturedRequest.err) 317 } 318 319 verifyRequestHeaderMultiTenancy(capturedRequest.header, t) 320 321 actualRequest := capturedRequest.request.(*sendRequest) 322 323 assert.Equal(arbitraryPrivatePayload, actualRequest.Payload, "request.payload") 324 assert.Equal(arbitraryFrom, actualRequest.From, "request.from") 325 assert.Equal(arbitraryTo, actualRequest.To, "request.to") 326 assert.Equal(arbitraryPrivacyFlag, actualRequest.PrivacyFlag, "request.privacyFlag") 327 assert.Equal(arbitraryExtra.ACHashes.ToBase64s(), actualRequest.AffectedContractTransactions, "request.affectedContractTransactions") 328 assert.Equal(arbitraryExtra.ACMerkleRoot.ToBase64(), actualRequest.ExecHash, "request.execHash") 329 assert.Equal(arbitraryHash, actualHash, "returned hash") 330 } 331 332 func TestSend_whenTesseraVersionDoesNotSupportPrivacyEnhancements(t *testing.T) { 333 assert := testifyassert.New(t) 334 335 testObjectNoPE := New(&engine.Client{ 336 HttpClient: &http.Client{}, 337 BaseURL: testServer.URL, 338 }, []byte("0.10-SNAPSHOT")) 339 340 assert.False(testObjectNoPE.HasFeature(engine.PrivacyEnhancements), "the supplied version does not support privacy enhancements") 341 342 // trying to send a party protection transaction 343 _, _, _, err := testObjectNoPE.Send(arbitraryPrivatePayload, arbitraryFrom, arbitraryTo, arbitraryExtra) 344 if err != engine.ErrPrivateTxManagerDoesNotSupportPrivacyEnhancements { 345 t.Fatal("Expecting send to raise ErrPrivateTxManagerDoesNotSupportPrivacyEnhancements") 346 } 347 } 348 349 func TestSend_whenTypical_MandatoryRecipients(t *testing.T) { 350 assert := testifyassert.New(t) 351 352 testObjectWithMR := New(&engine.Client{ 353 HttpClient: &http.Client{}, 354 BaseURL: testServer.URL, 355 }, []byte("4.0")) 356 357 _, _, actualHash, err := testObjectWithMR.Send(arbitraryPrivatePayload, arbitraryFrom, arbitraryTo, arbitraryExtraWithMandatoryFor) 358 if err != nil { 359 t.Fatalf("%s", err) 360 } 361 capturedRequest := <-sendRequestCaptor 362 363 if capturedRequest.err != nil { 364 t.Fatalf("%s", capturedRequest.err) 365 } 366 367 verifyRequestHeaderMandatoryRecipients(capturedRequest.header, t) 368 369 actualRequest := capturedRequest.request.(*sendRequest) 370 371 assert.Equal(arbitraryPrivatePayload, actualRequest.Payload, "request.payload") 372 assert.Equal(arbitraryFrom, actualRequest.From, "request.from") 373 assert.Equal(arbitraryTo, actualRequest.To, "request.to") 374 assert.Equal(engine.PrivacyFlagMandatoryRecipients, actualRequest.PrivacyFlag, "request.privacyFlag") 375 assert.Equal(arbitraryExtraWithMandatoryFor.ACHashes.ToBase64s(), actualRequest.AffectedContractTransactions, "request.affectedContractTransactions") 376 assert.Equal(arbitraryHash, actualHash, "returned hash") 377 assert.Equal(arbitraryMandatory, actualRequest.MandatoryRecipients, "request.mandatoryRecipients") 378 } 379 380 func TestSend_whenTesseraSupportEnhancedPrivacyButNotMandatoryRecipients(t *testing.T) { 381 assert := testifyassert.New(t) 382 383 testObjectNoMR := New(&engine.Client{ 384 HttpClient: &http.Client{}, 385 BaseURL: testServer.URL, 386 }, []byte("3.0")) 387 388 assert.True(testObjectNoMR.HasFeature(engine.MultiTenancy)) 389 assert.True(testObjectNoMR.HasFeature(engine.MultiplePrivateStates)) 390 assert.False(testObjectNoMR.HasFeature(engine.MandatoryRecipients), "the supplied version does not support mandatory recipients") 391 392 // trying to send a mandatory recipients transaction 393 _, _, _, err := testObjectNoMR.Send(arbitraryPrivatePayload, arbitraryFrom, arbitraryTo, arbitraryExtraWithMandatoryFor) 394 if err != engine.ErrPrivateTxManagerDoesNotSupportMandatoryRecipients { 395 t.Fatal("Expecting send to raise ErrPrivateTxManagerDoesNotSupportMandatoryRecipients") 396 } 397 } 398 399 func TestSendRaw_whenTesseraVersionDoesNotSupportPrivacyEnhancements(t *testing.T) { 400 assert := testifyassert.New(t) 401 402 mux := http.NewServeMux() 403 mux.HandleFunc("/send", MockSendAPIHandlerFunc) 404 mux.HandleFunc("/transaction/", MockReceiveAPIHandlerFunc) 405 mux.HandleFunc("/sendsignedtx", MockSendSignedTxOctetStreamAPIHandlerFunc) 406 407 testServerNoPE := httptest.NewServer(mux) 408 defer testServerNoPE.Close() 409 410 testObjectNoPE := New(&engine.Client{ 411 HttpClient: &http.Client{}, 412 BaseURL: testServerNoPE.URL, 413 }, []byte("0.10-SNAPSHOT")) 414 415 assert.False(testObjectNoPE.HasFeature(engine.PrivacyEnhancements), "the supplied version does not support privacy enhancements") 416 417 // trying to send a party protection transaction 418 _, _, _, err := testObjectNoPE.SendSignedTx(arbitraryHash, arbitraryTo, arbitraryExtra) 419 if err != engine.ErrPrivateTxManagerDoesNotSupportPrivacyEnhancements { 420 t.Fatal("Expecting send to raise ErrPrivateTxManagerDoesNotSupportPrivacyEnhancements") 421 } 422 423 // send a standard private transaction and check that the old version of the /sendsignedtx is used (using octetstream content type) 424 425 // caching incomplete item 426 _, _, _, err = testObjectNoPE.ReceiveRaw(arbitraryHashNoPrivateMetadata) 427 if err != nil { 428 t.Fatalf("%s", err) 429 } 430 <-receiveRequestCaptor 431 432 // caching complete item 433 _, _, _, err = testObjectNoPE.SendSignedTx(arbitraryHashNoPrivateMetadata, arbitraryTo, &engine.ExtraMetadata{ 434 PrivacyFlag: engine.PrivacyFlagStandardPrivate}) 435 if err != nil { 436 t.Fatalf("%s", err) 437 } 438 req := <-sendSignedTxOctetStreamRequestCaptor 439 assert.Equal("application/octet-stream", req.header["Content-Type"][0]) 440 441 _, _, _, actualExtra, err := testObjectNoPE.Receive(arbitraryHashNoPrivateMetadata) 442 if err != nil { 443 t.Fatalf("%s", err) 444 } 445 assert.Equal(engine.PrivacyFlagStandardPrivate, actualExtra.PrivacyFlag, "cached privacy flag") 446 447 } 448 449 func TestReceive_whenTypical(t *testing.T) { 450 assert := testifyassert.New(t) 451 452 _, _, _, actualExtra, err := testObject.Receive(arbitraryHash1) 453 if err != nil { 454 t.Fatalf("%s", err) 455 } 456 capturedRequest := <-receiveRequestCaptor 457 458 if capturedRequest.err != nil { 459 t.Fatalf("%s", capturedRequest.err) 460 } 461 462 verifyRequestHeader(capturedRequest.header, t) 463 464 actualRequest := capturedRequest.request.(string) 465 466 assert.Equal(arbitraryHash1.ToBase64(), actualRequest, "requested hash") 467 assert.Equal(arbitraryExtra.ACHashes, actualExtra.ACHashes, "returned affected contract transaction hashes") 468 assert.Equal(arbitraryExtra.ACMerkleRoot, actualExtra.ACMerkleRoot, "returned merkle root") 469 assert.Equal(arbitraryExtra.PrivacyFlag, actualExtra.PrivacyFlag, "returned privacy flag") 470 } 471 472 func TestReceive_whenTypical_Multitenancy(t *testing.T) { 473 assert := testifyassert.New(t) 474 475 testObjectWithMT := New(&engine.Client{ 476 HttpClient: &http.Client{}, 477 BaseURL: testServer.URL, 478 }, []byte("2.1")) 479 480 _, _, _, actualExtra, err := testObjectWithMT.Receive(arbitraryHash1) 481 if err != nil { 482 t.Fatalf("%s", err) 483 } 484 capturedRequest := <-receiveRequestCaptor 485 486 if capturedRequest.err != nil { 487 t.Fatalf("%s", capturedRequest.err) 488 } 489 490 verifyRequestHeaderMultiTenancy(capturedRequest.header, t) 491 492 actualRequest := capturedRequest.request.(string) 493 494 assert.Equal(arbitraryHash1.ToBase64(), actualRequest, "requested hash") 495 assert.Equal(arbitraryExtra.ACHashes, actualExtra.ACHashes, "returned affected contract transaction hashes") 496 assert.Equal(arbitraryExtra.ACMerkleRoot, actualExtra.ACMerkleRoot, "returned merkle root") 497 assert.Equal(arbitraryExtra.PrivacyFlag, actualExtra.PrivacyFlag, "returned privacy flag") 498 } 499 500 func TestReceive_whenPayloadNotFound(t *testing.T) { 501 assert := testifyassert.New(t) 502 503 _, _, data, _, err := testObject.Receive(arbitraryNotFoundHash) 504 if err != nil { 505 t.Fatalf("%s", err) 506 } 507 capturedRequest := <-receiveRequestCaptor 508 509 if capturedRequest.err != nil { 510 t.Fatalf("%s", capturedRequest.err) 511 } 512 513 verifyRequestHeader(capturedRequest.header, t) 514 515 actualRequest := capturedRequest.request.(string) 516 517 assert.Equal(arbitraryNotFoundHash.ToBase64(), actualRequest, "requested hash") 518 assert.Nil(data, "returned payload when not found") 519 } 520 521 func TestReceive_whenEncryptedPayloadHashIsEmpty(t *testing.T) { 522 assert := testifyassert.New(t) 523 524 _, _, data, _, err := testObject.Receive(emptyHash) 525 if err != nil { 526 t.Fatalf("%s", err) 527 } 528 assert.Empty(receiveRequestCaptor, "no request is actually sent") 529 assert.Nil(data, "returned payload when not found") 530 } 531 532 func TestReceive_whenHavingPayloadButNoPrivateExtraMetadata(t *testing.T) { 533 assert := testifyassert.New(t) 534 535 _, _, _, actualExtra, err := testObject.Receive(arbitraryHashNoPrivateMetadata) 536 if err != nil { 537 t.Fatalf("%s", err) 538 } 539 capturedRequest := <-receiveRequestCaptor 540 541 if capturedRequest.err != nil { 542 t.Fatalf("%s", capturedRequest.err) 543 } 544 545 verifyRequestHeader(capturedRequest.header, t) 546 547 actualRequest := capturedRequest.request.(string) 548 549 assert.Equal(arbitraryHashNoPrivateMetadata.ToBase64(), actualRequest, "requested hash") 550 assert.Empty(actualExtra.ACHashes, "returned affected contract transaction hashes") 551 assert.True(common.EmptyHash(actualExtra.ACMerkleRoot), "returned merkle root") 552 } 553 554 func TestSendSignedTx_whenTypical(t *testing.T) { 555 assert := testifyassert.New(t) 556 557 _, _, _, err := testObject.SendSignedTx(arbitraryHash, arbitraryTo, arbitraryExtra) 558 if err != nil { 559 t.Fatalf("%s", err) 560 } 561 capturedRequest := <-sendSignedTxRequestCaptor 562 563 if capturedRequest.err != nil { 564 t.Fatalf("%s", capturedRequest.err) 565 } 566 567 verifyRequestHeader(capturedRequest.header, t) 568 569 actualRequest := capturedRequest.request.(*sendSignedTxRequest) 570 571 assert.Equal(arbitraryTo, actualRequest.To, "request.to") 572 assert.Equal(arbitraryExtra.ACHashes.ToBase64s(), actualRequest.AffectedContractTransactions, "request.affectedContractTransactions") 573 assert.Equal(arbitraryExtra.ACMerkleRoot.ToBase64(), actualRequest.ExecHash, "request.execHash") 574 } 575 576 func TestSendSignedTx_whenTypical_MandatoryRecipients(t *testing.T) { 577 assert := testifyassert.New(t) 578 579 testObjectWithMR := New(&engine.Client{ 580 HttpClient: &http.Client{}, 581 BaseURL: testServer.URL, 582 }, []byte("4.0")) 583 584 _, _, _, err := testObjectWithMR.SendSignedTx(arbitraryHash, arbitraryTo, arbitraryExtraWithMandatoryFor) 585 if err != nil { 586 t.Fatalf("%s", err) 587 } 588 capturedRequest := <-sendSignedTxRequestCaptor 589 590 if capturedRequest.err != nil { 591 t.Fatalf("%s", capturedRequest.err) 592 } 593 594 verifyRequestHeaderMandatoryRecipients(capturedRequest.header, t) 595 596 actualRequest := capturedRequest.request.(*sendSignedTxRequest) 597 598 assert.Equal(arbitraryTo, actualRequest.To, "request.to") 599 assert.Equal(arbitraryExtraWithMandatoryFor.ACHashes.ToBase64s(), actualRequest.AffectedContractTransactions, "request.affectedContractTransactions") 600 assert.Equal(engine.PrivacyFlagMandatoryRecipients, actualRequest.PrivacyFlag, "request.privacyFlag") 601 assert.Equal(arbitraryExtraWithMandatoryFor.MandatoryRecipients, actualRequest.MandatoryRecipients, "request.mandatoryRecipients") 602 } 603 604 func TestSendSignedTx_whenTesseraDoesNotSupportMandatoryRecipients(t *testing.T) { 605 assert := testifyassert.New(t) 606 607 testObjectNoMR := New(&engine.Client{ 608 HttpClient: &http.Client{}, 609 BaseURL: testServer.URL, 610 }, []byte("3.0")) 611 612 assert.True(testObjectNoMR.HasFeature(engine.MultiTenancy)) 613 assert.True(testObjectNoMR.HasFeature(engine.MultiplePrivateStates)) 614 assert.False(testObjectNoMR.HasFeature(engine.MandatoryRecipients), "the supplied version does not support mandatory recipients") 615 616 // trying to send a mandatory recipients transaction 617 _, _, _, err := testObjectNoMR.SendSignedTx(arbitraryHash, arbitraryTo, arbitraryExtraWithMandatoryFor) 618 if err != engine.ErrPrivateTxManagerDoesNotSupportMandatoryRecipients { 619 t.Fatal("Expecting send to raise ErrPrivateTxManagerDoesNotSupportMandatoryRecipients") 620 } 621 } 622 623 func TestReceive_whenCachingRawPayload(t *testing.T) { 624 assert := testifyassert.New(t) 625 626 // caching incomplete item 627 _, _, _, err := testObject.ReceiveRaw(arbitraryHashNoPrivateMetadata) 628 if err != nil { 629 t.Fatalf("%s", err) 630 } 631 <-receiveRequestCaptor 632 633 // caching complete item 634 _, _, _, err = testObject.SendSignedTx(arbitraryHashNoPrivateMetadata, arbitraryTo, arbitraryExtra) 635 if err != nil { 636 t.Fatalf("%s", err) 637 } 638 <-sendSignedTxRequestCaptor 639 640 _, _, _, actualExtra, err := testObject.Receive(arbitraryHashNoPrivateMetadata) 641 if err != nil { 642 t.Fatalf("%s", err) 643 } 644 645 assert.Equal(arbitraryExtra.ACHashes, actualExtra.ACHashes, "cached affected contract transaction hashes") 646 assert.Equal(arbitraryExtra.ACMerkleRoot, actualExtra.ACMerkleRoot, "cached merkle root") 647 assert.Equal(arbitraryExtra.PrivacyFlag, actualExtra.PrivacyFlag, "cached privacy flag") 648 } 649 650 func TestGetMandatory_valid(t *testing.T) { 651 assert := testifyassert.New(t) 652 653 mandatoryRecipients, _ := testObject.GetMandatory(arbitraryHash) 654 655 assert.Equal(arbitraryMandatory, mandatoryRecipients) 656 } 657 658 func TestGetMandatory_notFound(t *testing.T) { 659 assert := testifyassert.New(t) 660 661 _, err := testObject.GetMandatory(arbitraryNotFoundHash) 662 663 assert.Error(err, "Non-200 status code") 664 }