/*
   * testSMSCost - Testa se o calculo do envio de SMS é bem feito
   */
  public void testSMSCost() {
    // Arrange
    SMSDTO dto = new SMSDTO(CELLPHONE2, CELLPHONE1, MSG);
    SendSMSService sendService = new SendSMSService(dto);
    ReceiveSMSService receiveService = new ReceiveSMSService(dto);

    boolean committed = false;

    SMSDTO dto2 = new SMSDTO(CELLPHONE3, CELLPHONE1, MSG);
    SendSMSService sendService2 = new SendSMSService(dto2);
    ReceiveSMSService receiveService2 = new ReceiveSMSService(dto2);

    // Act
    try {
      Transaction.begin();

      // envio de SMS inter-operadoras
      sendService.dispatch();
      receiveService.dispatch();
      // envio de SMS intra-operadoras
      sendService2.dispatch();
      receiveService2.dispatch();

      Transaction.commit();
      committed = true;
    } catch (AnaComException e) {
      fail("Saldos devem ser calculados sem lançar excepção");
    }
    if (!committed) {
      Transaction.abort();
    }

    // Assert
    assertEquals(
        "Custo de envio de SMS entre duas operadoras diferentes mal calculado",
        EXPECTED_BALANCE2,
        getPhoneBalance(CELLPHONE2));

    assertEquals(
        "Custo de envio de SMS entre a mesma operadora mal calculado",
        EXPECTED_BALANCE,
        getPhoneBalance(CELLPHONE3));
  }
  /** Test without balance. */
  public void testWithoutBalance() {

    // Arrange
    SMSDTO dto = new SMSDTO(CELLPHONE_BALANCE_BROKE_ON_2G, CELLPHONE1, MSG);
    SendSMSService sendService = new SendSMSService(dto);
    ReceiveSMSService receiveService = new ReceiveSMSService(dto);

    boolean committed = false;

    // Act
    try {
      Transaction.begin();

      sendService.dispatch();
      receiveService.dispatch();

      Transaction.commit();
      committed = true;
    } catch (NotEnoughBalanceException e) {

    } catch (AnaComException e) {
      fail("A Excepção " + e.getMessage() + " não deveria estar a ser mandada");
    }

    if (!committed) {
      Transaction.abort();
    }

    // Assert
    assertEquals(
        "Comunicação fica registada no Telefone de origem",
        0,
        checkMadeCommunication(OPERATOR_1_NAME, CELLPHONE_BALANCE_BROKE_ON_2G));

    assertEquals(
        "Comunicação fica registada no Telefone de destino",
        0,
        checkReceivedCommunication(OPERATOR_1_NAME, CELLPHONE1));

    assertEquals(
        "Saldo do telemóvel de origem foi modificado",
        BROKE_BALANCE,
        getPhoneBalance(CELLPHONE_BALANCE_BROKE_ON_2G));

    // assertEquals("Excepção não está a ser bem lançada",
    // new NotEnoughBalanceException("Saldo Insuficiente"), ex);

  }
  /** Test mode busy. */
  public void testModeBUSY() {
    SMSDTO dto = new SMSDTO(CELLPHONE1, CELLPHONE2, MSG);
    SendSMSService sendService = new SendSMSService(dto);
    ReceiveSMSService receiveService = new ReceiveSMSService(dto);

    boolean committed = false;

    // Act
    try {
      changeCellPhoneMode(OPERATOR_1_NAME, CELLPHONE1, CellPhoneMode.BUSY);

      Transaction.begin();

      sendService.dispatch();
      receiveService.dispatch();

      Transaction.commit();
      committed = true;
    } catch (IncompatibleModeException e) {

    } catch (Exception e) {
      fail("A Excepção " + e.getMessage() + " não deveria estar a ser mandada");
    }

    if (!committed) {
      Transaction.abort();
    }
    // Assert

    assertEquals(
        "Comunicação fica registada no Telefone de origem",
        0,
        checkMadeCommunication(OPERATOR_1_NAME, CELLPHONE1));

    assertEquals(
        "Comunicação fica registada no Telefone de destino",
        0,
        checkReceivedCommunication(OPERATOR_2_NAME, CELLPHONE2));

    assertEquals(
        "Saldo do telemóvel de origem foi modificado",
        INITIAL_BALANCE,
        getPhoneBalance(CELLPHONE1));

    // assertEquals("Excepção não está a ser bem lançada",
    // new IncompatibleModeForCommunicationException(), ex);
  }
  /** Test source mobile with mode off. */
  public void testModeOFFDestination() {
    // Arrange
    SMSDTO dto = new SMSDTO(CELLPHONE2, CELLPHONE1, MSG);
    SendSMSService sendService = new SendSMSService(dto);
    ReceiveSMSService receiveService = new ReceiveSMSService(dto);

    boolean committed = false;

    // Act
    try {
      Transaction.begin();

      sendService.dispatch();
      receiveService.dispatch();

      Transaction.commit();
      committed = true;
    } catch (Exception e) {
      fail("A Excepção " + e.getMessage() + " não deveria estar a ser mandada");
    }
    if (!committed) {
      Transaction.abort();
    }

    // Assert
    assertEquals(
        "Comunicação nãofica registada no Telefone de destino",
        1,
        checkMadeCommunication(OPERATOR_2_NAME, CELLPHONE2));
    assertEquals(
        "Comunicação não fica registada no Telefone de origem",
        1,
        checkReceivedCommunication(OPERATOR_1_NAME, CELLPHONE1));

    assertEquals(
        "Saldo do telemóvel de origem não foi modificado",
        EXPECTED_BALANCE2,
        getPhoneBalance(CELLPHONE2));
  }
  /** Testar se o telemovel de destino não existe */
  public void testDestinationPhoneNotExists() {
    // Arrange
    // Destino é um número em operador válido mas sem este número
    final SMSDTO dto = new SMSDTO(CELLPHONE1, CELLPHONENOTEXISTS, MSG);
    final SendSMSService sendService = new SendSMSService(dto);
    final ReceiveSMSService receiveService = new ReceiveSMSService(dto);

    boolean committed = false;

    // Act
    try {
      Transaction.begin();

      sendService.dispatch();
      receiveService.dispatch();

      Transaction.commit();
      committed = true;

    } catch (CellPhoneNotExistsException e) {
      // lançou a excepção correctamente
    } catch (Exception e) {
      fail("A Excepção " + e.getMessage() + " não deveria estar a ser mandada");
    }
    if (!committed) {
      Transaction.abort();
    }

    // Assert
    assertEquals(
        "Comunicação fica registada no Telefone de origem",
        0,
        checkMadeCommunication(OPERATOR_1_NAME, CELLPHONE1));
    assertEquals(
        "Saldo do telemóvel de origem foi modificado",
        INITIAL_BALANCE,
        getPhoneBalance(CELLPHONE1));
  }
  /** Teste sms logs. */
  public void testSMSLogs() {
    // Arrange
    SMSDTO dto1 = new SMSDTO(CELLPHONE1, CELLPHONE2, MSG);
    SendSMSService sendService1 = new SendSMSService(dto1);
    ReceiveSMSService receiveService1 = new ReceiveSMSService(dto1);

    SMSDTO dto2 = new SMSDTO(CELLPHONE1, CELLPHONE3, MSG);
    SendSMSService sendService2 = new SendSMSService(dto2);
    ReceiveSMSService receiveService2 = new ReceiveSMSService(dto2);

    SMSDTO dto3 = new SMSDTO(CELLPHONE2, CELLPHONE3, MSG);
    SendSMSService sendService3 = new SendSMSService(dto3);
    ReceiveSMSService receiveService3 = new ReceiveSMSService(dto3);

    boolean committed = false;

    // Act
    try {
      Transaction.begin();

      sendService1.dispatch();
      receiveService1.dispatch();

      sendService2.dispatch();
      receiveService2.dispatch();

      sendService3.dispatch();
      receiveService3.dispatch();

      Transaction.commit();
      committed = true;
    } catch (AnaComException e) {
      fail("SMS's devem ser enviadas sem lançar excepção");
    }
    if (!committed) {
      Transaction.abort();
    }
    // Assert
    assertEquals(
        "Registo de SMS enviados não está a funcionar bem",
        2,
        checkMadeCommunication(OPERATOR_1_NAME, CELLPHONE1));

    assertEquals(
        "Registo de SMS enviados não está a funcionar bem",
        1,
        checkMadeCommunication(OPERATOR_2_NAME, CELLPHONE2));

    assertEquals(
        "Registo de SMS enviados não está a funcionar bem",
        0,
        checkMadeCommunication(OPERATOR_1_NAME, CELLPHONE3));

    assertEquals(
        "Registo de SMS recebidos não está a funcionar bem",
        0,
        checkReceivedCommunication(OPERATOR_1_NAME, CELLPHONE1));

    assertEquals(
        "Registo de SMS recebidos não está a funcionar bem",
        1,
        checkReceivedCommunication(OPERATOR_2_NAME, CELLPHONE2));

    assertEquals(
        "Registo de SMS recebidos não está a funcionar bem",
        2,
        checkReceivedCommunication(OPERATOR_1_NAME, CELLPHONE3));
  }