content: /*
   * Copyright 2023 Ant Group
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package com.alipay.antchain.bridge.pluginserver;
  
  import cn.hutool.core.collection.ListUtil;
  import cn.hutool.crypto.digest.DigestUtil;
  import com.alipay.antchain.bridge.commons.bbc.AbstractBBCContext;
  import com.alipay.antchain.bridge.commons.bbc.DefaultBBCContext;
  import com.alipay.antchain.bridge.commons.bbc.syscontract.ContractStatusEnum;
  import com.alipay.antchain.bridge.commons.bbc.syscontract.SDPContract;
  import com.alipay.antchain.bridge.pluginserver.server.CrossChainServiceImpl;
  import com.alipay.antchain.bridge.pluginserver.server.ResponseBuilder;
  import com.alipay.antchain.bridge.pluginserver.service.*;
  import com.google.protobuf.ByteString;
  import io.grpc.stub.StreamObserver;
  import org.junit.jupiter.api.Test;
  import org.mockito.Mockito;
  import org.springframework.beans.factory.annotation.Autowired;
  import org.springframework.boot.test.context.SpringBootTest;
  import org.springframework.test.annotation.DirtiesContext;
  
  import java.util.HashMap;
  
  @SpringBootTest(classes = AntChainBridgePluginServerApplication.class, webEnvironment = SpringBootTest.WebEnvironment.NONE)
  class AntChainBridgePluginServerApplicationTests {
  
      private static final String TEST_PRODUCT = "testchain";
      private static final String TEST_PRODUCT1 = "testchain1";
      private static final String TEST_DOMAIN = "domain";
  
      @Autowired
      private CrossChainServiceImpl crossChainService;
  
      private StreamObserver<Response> responseStreamObserver;
  
      @Test
      @DirtiesContext
      public void testHeartbeat() {
          responseStreamObserver = Mockito.mock(StreamObserver.class);
  
          Empty heartbeatReq = Empty.newBuilder().build();
  
          crossChainService.heartbeat(heartbeatReq, responseStreamObserver);
  
          Mockito.verify(responseStreamObserver).onNext(ResponseBuilder.buildHeartbeatSuccessResp(
                  HeartbeatResponse.newBuilder()
                          .addAllDomains(ListUtil.toList())
                          .addAllProducts(ListUtil.toList(TEST_PRODUCT))
          ));
          Mockito.verify(responseStreamObserver).onCompleted();
      }
  
      @Test
      @DirtiesContext
      public void testIfProductSupport(){
          responseStreamObserver = Mockito.mock(StreamObserver.class);
  
          IfProductSupportRequest ifProductSupportRequest = IfProductSupportRequest.newBuilder()
                  .addAllProducts(ListUtil.toList(TEST_PRODUCT, TEST_PRODUCT1)).build();
  
          crossChainService.ifProductSupport(ifProductSupportRequest, responseStreamObserver);
  
          Mockito.verify(responseStreamObserver).onNext(ResponseBuilder.buildIfProductSupportSuccessResp(
                  IfProductSupportResponse.newBuilder().putAllResults(new HashMap<String, Boolean>(){{
                      put(TEST_PRODUCT, true);
                      put(TEST_PRODUCT1, false);
                  }})
          ));
          Mockito.verify(responseStreamObserver).onCompleted();
      }
  
      @Test
      @DirtiesContext
      public void testIfDomainAlive(){
          responseStreamObserver = Mockito.mock(StreamObserver.class);
  
          IfDomainAliveRequest ifDomainAliveRequest = IfDomainAliveRequest.newBuilder()
                          .addAllDomains(ListUtil.toList(TEST_DOMAIN)).build();
  
          crossChainService.ifDomainAlive(ifDomainAliveRequest, responseStreamObserver);
  
          Mockito.verify(responseStreamObserver).onNext(ResponseBuilder.buildIfDomainAliveSuccessResp(
                  IfDomainAliveResponse.newBuilder().putAllResults(new HashMap<String, Boolean>(){{
                      put(TEST_DOMAIN,false);
                  }})
          ));
          Mockito.verify(responseStreamObserver).onCompleted();
      }
  
      @Test
      @DirtiesContext
      public void testBBCCallStartReq() {
          CallBBCRequest callBBCRequest;
  
          AbstractBBCContext mockInitCtx = mockInitCtx();
          AbstractBBCContext mockDeployedCtx = mockDeployedCtx();
  
          // start up (create and startup)
          callBBCRequest = CallBBCRequest.newBuilder()
                  .setProduct(TEST_PRODUCT)
                  .setDomain(TEST_DOMAIN)
                  .setStartUpReq(StartUpRequest.newBuilder().setRawContext(ByteString.copyFrom(mockInitCtx.encodeToBytes()))).build();
          responseStreamObserver = Mockito.mock(StreamObserver.class);
          crossChainService.bbcCall(callBBCRequest, responseStreamObserver);
          Mockito.verify(responseStreamObserver).onNext(ResponseBuilder.buildBBCSuccessResp(CallBBCResponse.newBuilder()));
          Mockito.verify(responseStreamObserver).onCompleted();
      }
  
      @Test
      @DirtiesContext
      public void test_BBCCall_Shutdown(){
          CallBBCRequest callBBCRequest;
  
          // start up (create and startup)
          AbstractBBCContext mockInitCtx = mockInitCtx();
          callBBCRequest = CallBBCRequest.newBuilder()
                  .setProduct(TEST_PRODUCT)
                  .setDomain(TEST_DOMAIN)
                  .setStartUpReq(StartUpRequest.newBuilder().setRawContext(ByteString.copyFrom(mockInitCtx.encodeToBytes()))).build();
          responseStreamObserver = Mockito.mock(StreamObserver.class);
          crossChainService.bbcCall(callBBCRequest, responseStreamObserver);
          Mockito.verify(responseStreamObserver).onNext(ResponseBuilder.buildBBCSuccessResp(CallBBCResponse.newBuilder()));
          Mockito.verify(responseStreamObserver).onCompleted();
  
          // shut down
          callBBCRequest = CallBBCRequest.newBuilder()
                  .setProduct(TEST_PRODUCT)
                  .setDomain(TEST_DOMAIN)
                  .setShutdownReq(ShutdownRequest.newBuilder()).build();
          responseStreamObserver = Mockito.mock(StreamObserver.class);
          crossChainService.bbcCall(callBBCRequest, responseStreamObserver);
          Mockito.verify(responseStreamObserver)
                  .onNext(ResponseBuilder.buildBBCSuccessResp(CallBBCResponse.newBuilder()));
          Mockito.verify(responseStreamObserver).onCompleted();
  
          // start up (startup after shutdowm)
          callBBCRequest = CallBBCRequest.newBuilder()
                  .setProduct(TEST_PRODUCT)
                  .setDomain(TEST_DOMAIN)
                  .setStartUpReq(StartUpRequest.newBuilder().setRawContext(ByteString.copyFrom(mockInitCtx.encodeToBytes()))).build();
          responseStreamObserver = Mockito.mock(StreamObserver.class);
          crossChainService.bbcCall(callBBCRequest, responseStreamObserver);
          Mockito.verify(responseStreamObserver).onNext(ResponseBuilder.buildBBCSuccessResp(CallBBCResponse.newBuilder()));
          Mockito.verify(responseStreamObserver).onCompleted();
      }
  
      @Test
      @DirtiesContext
      public void test_BBCCall_GetContext(){
          CallBBCRequest callBBCRequest;
  
          // start up (create and startup)
          AbstractBBCContext mockInitCtx = mockInitCtx();
          callBBCRequest = CallBBCRequest.newBuilder()
                  .setProduct(TEST_PRODUCT)
                  .setDomain(TEST_DOMAIN)
                  .setStartUpReq(StartUpRequest.newBuilder().setRawContext(ByteString.copyFrom(mockInitCtx.encodeToBytes()))).build();
          responseStreamObserver = Mockito.mock(StreamObserver.class);
          crossChainService.bbcCall(callBBCRequest, responseStreamObserver);
          Mockito.verify(responseStreamObserver).onNext(ResponseBuilder.buildBBCSuccessResp(CallBBCResponse.newBuilder()));
          Mockito.verify(responseStreamObserver).onCompleted();
  
          // get context
          callBBCRequest = CallBBCRequest.newBuilder()
                  .setProduct(TEST_PRODUCT)
                  .setDomain(TEST_DOMAIN)
                  .setGetContextReq(GetContextRequest.newBuilder()).build();
          responseStreamObserver = Mockito.mock(StreamObserver.class);
          crossChainService.bbcCall(callBBCRequest, responseStreamObserver);
          Mockito.verify(responseStreamObserver).onNext(ResponseBuilder.buildBBCSuccessResp(CallBBCResponse.newBuilder()
                  .setGetContextResp(GetContextResponse.newBuilder().setRawContext(ByteString.copyFrom(mockInitCtx.encodeToBytes())))
          ));
          Mockito.verify(responseStreamObserver).onCompleted();
      }
  
      @Test
      @DirtiesContext
      public void test_BBCCall_SetupSDPMessageContract(){
          CallBBCRequest callBBCRequest;
  
          // start up (create and startup)
          AbstractBBCContext mockInitCtx = mockInitCtx();
          callBBCRequest = CallBBCRequest.newBuilder()
                  .setProduct(TEST_PRODUCT)
                  .setDomain(TEST_DOMAIN)
                  .setStartUpReq(StartUpRequest.newBuilder().setRawContext(ByteString.copyFrom(mockInitCtx.encodeToBytes()))).build();
          responseStreamObserver = Mockito.mock(StreamObserver.class);
          crossChainService.bbcCall(callBBCRequest, responseStreamObserver);
          Mockito.verify(responseStreamObserver).onNext(ResponseBuilder.buildBBCSuccessResp(CallBBCResponse.newBuilder()));
          Mockito.verify(responseStreamObserver).onCompleted();
  
          // set up sdp contract
          AbstractBBCContext mockDeployedCtx = mockDeployedCtx();
          callBBCRequest = CallBBCRequest.newBuilder()
                  .setProduct(TEST_PRODUCT)
                  .setDomain(TEST_DOMAIN)
                  .setSetupSDPMessageContractReq(SetupSDPMessageContractRequest.newBuilder()).build();
          responseStreamObserver = Mockito.mock(StreamObserver.class);
          crossChainService.bbcCall(callBBCRequest, responseStreamObserver);
          Mockito.verify(responseStreamObserver).onNext(ResponseBuilder.buildBBCSuccessResp(CallBBCResponse.newBuilder()
                  .setSetupSDPResp(SetupSDPMessageContractResponse.newBuilder()
                          .setSdpContract(
                                  SDPMessageContract.newBuilder()
                                          .setContractAddress(mockDeployedCtx.getSdpContract().getContractAddress())
                                          .setStatusValue(mockDeployedCtx.getSdpContract().getStatus().ordinal())
                          )
                  )
          ));
          Mockito.verify(responseStreamObserver).onCompleted();
      }
  
      @Test
      @DirtiesContext
      public void test_BBCCall_SetupAuthMessageContract(){
          CallBBCRequest callBBCRequest;
  
          // start up (create and startup)
          AbstractBBCContext mockInitCtx = mockInitCtx();
          callBBCRequest = CallBBCRequest.newBuilder()
                  .setProduct(TEST_PRODUCT)
                  .setDomain(TEST_DOMAIN)
                  .setStartUpReq(StartUpRequest.newBuilder().setRawContext(ByteString.copyFrom(mockInitCtx.encodeToBytes()))).build();
          responseStreamObserver = Mockito.mock(StreamObserver.class);
          crossChainService.bbcCall(callBBCRequest, responseStreamObserver);
          Mockito.verify(responseStreamObserver).onNext(ResponseBuilder.buildBBCSuccessResp(CallBBCResponse.newBuilder()));
          Mockito.verify(responseStreamObserver).onCompleted();
  
          // set up am contract
          AbstractBBCContext mockDeployedCtx = mockDeployedCtx();
          callBBCRequest = CallBBCRequest.newBuilder()
                  .setProduct(TEST_PRODUCT)
                  .setDomain(TEST_DOMAIN)
                  .setSetupAuthMessageContractReq(SetupAuthMessageContractRequest.newBuilder()).build();
          responseStreamObserver = Mockito.mock(StreamObserver.class);
          crossChainService.bbcCall(callBBCRequest, responseStreamObserver);
          Mockito.verify(responseStreamObserver).onNext(ResponseBuilder.buildBBCSuccessResp(CallBBCResponse.newBuilder()
                  .setSetupAMResp(SetupAuthMessageContractResponse.newBuilder()
                          .setAmContract(
                                  AuthMessageContract.newBuilder()
                                          .setContractAddress(mockDeployedCtx.getAuthMessageContract().getContractAddress())
                                          .setStatusValue(mockDeployedCtx.getAuthMessageContract().getStatus().ordinal())
                          )
                  )));
          Mockito.verify(responseStreamObserver).onCompleted();
      }
  
      @Test
      @DirtiesContext
      public void test_BBCCall_SetProtocol(){
          CallBBCRequest callBBCRequest;
  
          // start up (create and startup)
          AbstractBBCContext mockInitCtx = mockInitCtx();
          callBBCRequest = CallBBCRequest.newBuilder()
                  .setProduct(TEST_PRODUCT)
                  .setDomain(TEST_DOMAIN)
                  .setStartUpReq(StartUpRequest.newBuilder().setRawContext(ByteString.copyFrom(mockInitCtx.encodeToBytes()))).build();
          responseStreamObserver = Mockito.mock(StreamObserver.class);
          crossChainService.bbcCall(callBBCRequest, responseStreamObserver);
          Mockito.verify(responseStreamObserver).onNext(ResponseBuilder.buildBBCSuccessResp(CallBBCResponse.newBuilder()));
          Mockito.verify(responseStreamObserver).onCompleted();
  
          // set protocol
          callBBCRequest = CallBBCRequest.newBuilder()
                  .setProduct(TEST_PRODUCT)
                  .setDomain(TEST_DOMAIN)
                  .setSetProtocolReq(SetProtocolRequest.newBuilder()).build();
          responseStreamObserver = Mockito.mock(StreamObserver.class);
          crossChainService.bbcCall(callBBCRequest, responseStreamObserver);
          Mockito.verify(responseStreamObserver).onNext(ResponseBuilder.buildBBCSuccessResp(CallBBCResponse.newBuilder()));
          Mockito.verify(responseStreamObserver).onCompleted();
      }
  
      @Test
      @DirtiesContext
      public void test_BBCCall_SetAmContract(){
          CallBBCRequest callBBCRequest;
  
          // start up (create and startup)
          AbstractBBCContext mockInitCtx = mockInitCtx();
          callBBCRequest = CallBBCRequest.newBuilder()
                  .setProduct(TEST_PRODUCT)
                  .setDomain(TEST_DOMAIN)
                  .setStartUpReq(StartUpRequest.newBuilder().setRawContext(ByteString.copyFrom(mockInitCtx.encodeToBytes()))).build();
          responseStreamObserver = Mockito.mock(StreamObserver.class);
          crossChainService.bbcCall(callBBCRequest, responseStreamObserver);
          Mockito.verify(responseStreamObserver).onNext(ResponseBuilder.buildBBCSuccessResp(CallBBCResponse.newBuilder()));
          Mockito.verify(responseStreamObserver).onCompleted();
  
          // set am
          callBBCRequest = CallBBCRequest.newBuilder()
                  .setProduct(TEST_PRODUCT)
                  .setDomain(TEST_DOMAIN)
                  .setSetAmContractReq(SetAmContractRequest.newBuilder()).build();
          responseStreamObserver = Mockito.mock(StreamObserver.class);
          crossChainService.bbcCall(callBBCRequest, responseStreamObserver);
          Mockito.verify(responseStreamObserver).onNext(ResponseBuilder.buildBBCSuccessResp(CallBBCResponse.newBuilder()));
          Mockito.verify(responseStreamObserver).onCompleted();
      }
  
      @Test
      @DirtiesContext
      public void test_BBCCall_RelayAuthMessage(){
          CallBBCRequest callBBCRequest;
  
          // start up (create and startup)
          AbstractBBCContext mockInitCtx = mockInitCtx();
          callBBCRequest = CallBBCRequest.newBuilder()
                  .setProduct(TEST_PRODUCT)
                  .setDomain(TEST_DOMAIN)
                  .setStartUpReq(StartUpRequest.newBuilder().setRawContext(ByteString.copyFrom(mockInitCtx.encodeToBytes()))).build();
          responseStreamObserver = Mockito.mock(StreamObserver.class);
          crossChainService.bbcCall(callBBCRequest, responseStreamObserver);
          Mockito.verify(responseStreamObserver).onNext(ResponseBuilder.buildBBCSuccessResp(CallBBCResponse.newBuilder()));
          Mockito.verify(responseStreamObserver).onCompleted();
  
          // relayer am msg
          callBBCRequest = CallBBCRequest.newBuilder()
                  .setProduct(TEST_PRODUCT)
                  .setDomain(TEST_DOMAIN)
                  .setRelayAuthMessageReq(
                          RelayAuthMessageRequest.newBuilder().setRawMessage(ByteString.copyFrom("msg".getBytes()))
                  ).build();
          responseStreamObserver = Mockito.mock(StreamObserver.class);
          crossChainService.bbcCall(callBBCRequest, responseStreamObserver);
          Mockito.verify(responseStreamObserver).onNext(ResponseBuilder.buildBBCSuccessResp(CallBBCResponse.newBuilder()
                  .setRelayAuthMessageResponse(RelayAuthMessageResponse.newBuilder()
                          .setReceipt(CrossChainMessageReceipt.newBuilder()
                                  .setTxhash(mockRet().getTxhash())
                                  .setConfirmed(mockRet().isConfirmed())
                                  .setSuccessful(mockRet().isSuccessful())
                                  .setErrorMsg(mockRet().getErrorMsg())
                          )
                  )));
          Mockito.verify(responseStreamObserver).onCompleted();
      }
  
      @Test
      @DirtiesContext
      public void test_BBCCall_ReadCrossChainMessageReceipt(){
          CallBBCRequest callBBCRequest;
  
          // start up (create and startup)
          AbstractBBCContext mockInitCtx = mockInitCtx();
          callBBCRequest = CallBBCRequest.newBuilder()
                  .setProduct(TEST_PRODUCT)
                  .setDomain(TEST_DOMAIN)
                  .setStartUpReq(StartUpRequest.newBuilder().setRawContext(ByteString.copyFrom(mockInitCtx.encodeToBytes()))).build();
          responseStreamObserver = Mockito.mock(StreamObserver.class);
          crossChainService.bbcCall(callBBCRequest, responseStreamObserver);
          Mockito.verify(responseStreamObserver).onNext(ResponseBuilder.buildBBCSuccessResp(CallBBCResponse.newBuilder()));
          Mockito.verify(responseStreamObserver).onCompleted();
  
          // read crosschain msg receipt
          callBBCRequest = CallBBCRequest.newBuilder()
                  .setProduct(TEST_PRODUCT)
                  .setDomain(TEST_DOMAIN)
                  .setReadCrossChainMessageReceiptReq(
                          ReadCrossChainMessageReceiptRequest.newBuilder().setTxhash(mockRet().getTxhash())
                  ).build();
          responseStreamObserver = Mockito.mock(StreamObserver.class);
          crossChainService.bbcCall(callBBCRequest, responseStreamObserver);
          Mockito.verify(responseStreamObserver).onNext(ResponseBuilder.buildBBCSuccessResp(CallBBCResponse.newBuilder()
                  .setReadCrossChainMessageReceiptResp(
                          ReadCrossChainMessageReceiptResponse.newBuilder()
                                  .setReceipt(
                                          CrossChainMessageReceipt.newBuilder()
                                                  .setTxhash(mockRet().getTxhash())
                                                  .setConfirmed(mockRet().isConfirmed())
                                                  .setSuccessful(mockRet().isSuccessful())
                                                  .setErrorMsg(mockRet().getErrorMsg())
                                  )
                  )
          ));
          Mockito.verify(responseStreamObserver).onCompleted();
      }
  
  
  
      @Test
      @DirtiesContext
      public void test_BBCCall_ReadCrossChainMessagesByHeight(){
          CallBBCRequest callBBCRequest;
  
          // start up (create and startup)
          AbstractBBCContext mockInitCtx = mockInitCtx();
          callBBCRequest = CallBBCRequest.newBuilder()
                  .setProduct(TEST_PRODUCT)
                  .setDomain(TEST_DOMAIN)
                  .setStartUpReq(StartUpRequest.newBuilder().setRawContext(ByteString.copyFrom(mockInitCtx.encodeToBytes()))).build();
          responseStreamObserver = Mockito.mock(StreamObserver.class);
          crossChainService.bbcCall(callBBCRequest, responseStreamObserver);
          Mockito.verify(responseStreamObserver).onNext(ResponseBuilder.buildBBCSuccessResp(CallBBCResponse.newBuilder()));
          Mockito.verify(responseStreamObserver).onCompleted();
  
          // ReadCrossChainMessagesByHeight
          callBBCRequest = CallBBCRequest.newBuilder()
                  .setProduct(TEST_PRODUCT)
                  .setDomain(TEST_DOMAIN)
                  .setReadCrossChainMessagesByHeightReq(
                          ReadCrossChainMessagesByHeightRequest.newBuilder().setHeight(0)
                  ).build();
          responseStreamObserver = Mockito.mock(StreamObserver.class);
          crossChainService.bbcCall(callBBCRequest, responseStreamObserver);
          Mockito.verify(responseStreamObserver).onNext(Mockito.any());
          Mockito.verify(responseStreamObserver).onCompleted();
      }
  
      @Test
      @DirtiesContext
      public void test_BBCCall_QuerySDPMessageSeq(){
          CallBBCRequest callBBCRequest;
  
          // start up (create and startup)
          AbstractBBCContext mockInitCtx = mockInitCtx();
          callBBCRequest = CallBBCRequest.newBuilder()
                  .setProduct(TEST_PRODUCT)
                  .setDomain(TEST_DOMAIN)
                  .setStartUpReq(StartUpRequest.newBuilder().setRawContext(ByteString.copyFrom(mockInitCtx.encodeToBytes()))).build();
          responseStreamObserver = Mockito.mock(StreamObserver.class);
          crossChainService.bbcCall(callBBCRequest, responseStreamObserver);
          Mockito.verify(responseStreamObserver).onNext(ResponseBuilder.buildBBCSuccessResp(CallBBCResponse.newBuilder()));
          Mockito.verify(responseStreamObserver).onCompleted();
  
          // QuerySDPMessageSeq
          callBBCRequest = CallBBCRequest.newBuilder()
                  .setProduct(TEST_PRODUCT)
                  .setDomain(TEST_DOMAIN)
                  .setQuerySDPMessageSeqReq(QuerySDPMessageSeqRequest.newBuilder()
                  ).build();
          responseStreamObserver = Mockito.mock(StreamObserver.class);
          crossChainService.bbcCall(callBBCRequest, responseStreamObserver);
          Mockito.verify(responseStreamObserver).onNext(ResponseBuilder.buildBBCSuccessResp(CallBBCResponse.newBuilder()
                  .setQuerySDPMsgSeqResp(QuerySDPMessageSeqResponse.newBuilder()
                          .setSequence(0)
                  )
          ));
          Mockito.verify(responseStreamObserver).onCompleted();
      }
  
      @Test
      @DirtiesContext
      public void test_BBCCall_QueryLatestHeightRequest(){
          CallBBCRequest callBBCRequest;
  
          // start up (create and startup)
          AbstractBBCContext mockInitCtx = mockInitCtx();
          callBBCRequest = CallBBCRequest.newBuilder()
                  .setProduct(TEST_PRODUCT)
                  .setDomain(TEST_DOMAIN)
                  .setStartUpReq(StartUpRequest.newBuilder().setRawContext(ByteString.copyFrom(mockInitCtx.encodeToBytes()))).build();
          responseStreamObserver = Mockito.mock(StreamObserver.class);
          crossChainService.bbcCall(callBBCRequest, responseStreamObserver);
          Mockito.verify(responseStreamObserver).onNext(ResponseBuilder.buildBBCSuccessResp(CallBBCResponse.newBuilder()));
          Mockito.verify(responseStreamObserver).onCompleted();
  
          // QueryLatestHeightRequest
          callBBCRequest = CallBBCRequest.newBuilder()
                  .setProduct(TEST_PRODUCT)
                  .setDomain(TEST_DOMAIN)
                  .setQueryLatestHeightReq(QueryLatestHeightRequest.newBuilder()).build();
          responseStreamObserver = Mockito.mock(StreamObserver.class);
          crossChainService.bbcCall(callBBCRequest, responseStreamObserver);
          Mockito.verify(responseStreamObserver).onNext(Mockito.any());
          Mockito.verify(responseStreamObserver).onCompleted();
      }
  
      // mock data ======================================================
      // ================================================================
      // ================================================================
  
      public static AbstractBBCContext mockInitCtx() {
          DefaultBBCContext ctx = new DefaultBBCContext();
  
          com.alipay.antchain.bridge.commons.bbc.syscontract.AuthMessageContract am = new com.alipay.antchain.bridge.commons.bbc.syscontract.AuthMessageContract();
          am.setContractAddress("am");
          am.setStatus(ContractStatusEnum.INIT);
  
          SDPContract sdp = new SDPContract();
          sdp.setContractAddress("sdp");
          sdp.setStatus(ContractStatusEnum.INIT);
  
          ctx.setAuthMessageContract(am);
          ctx.setSdpContract(sdp);
          ctx.setConfForBlockchainClient("bbcConf".getBytes());
          return ctx;
      }
  
      private AbstractBBCContext mockDeployedCtx() {
          DefaultBBCContext ctx = new DefaultBBCContext();
  
          com.alipay.antchain.bridge.commons.bbc.syscontract.AuthMessageContract am = new com.alipay.antchain.bridge.commons.bbc.syscontract.AuthMessageContract();
          am.setContractAddress("am");
          am.setStatus(ContractStatusEnum.CONTRACT_DEPLOYED);
  
          SDPContract sdp = new SDPContract();
          sdp.setContractAddress("sdp");
          sdp.setStatus(ContractStatusEnum.CONTRACT_DEPLOYED);
  
          ctx.setAuthMessageContract(am);
          ctx.setSdpContract(sdp);
          ctx.setConfForBlockchainClient("bbcConf".getBytes());
          return ctx;
      }
  
      private com.alipay.antchain.bridge.commons.core.base.CrossChainMessageReceipt mockRet(){
          com.alipay.antchain.bridge.commons.core.base.CrossChainMessageReceipt ret = new com.alipay.antchain.bridge.commons.core.base.CrossChainMessageReceipt();
          ret.setTxhash(DigestUtil.sha256Hex("txhash"));
          ret.setConfirmed(true);
          ret.setSuccessful(true);
          ret.setErrorMsg("");
          return ret;
      }
  
  }
  