/** Testet das Auswählen, Anhören und Löschen eines Klingeltons. */
  @Test
  public final void testSoundSelection() {
    controller.setDialogStage(mockedDialogStage);

    // Alarm vorgeben
    final Alarm alarm =
        new Alarm(DateTimeUtil.getLocalDateTimeForString("01.01.1970 00:00:00"), "Bla");
    controller.setAlarm(alarm);
    FXTestUtils.awaitEvents();

    // Sound setzen
    controller.setRingtone("Sound");
    FXTestUtils.awaitEvents();

    assertFalse(alarmNoSoundButton.isDisabled());
    assertFalse(alarmPlaySoundButton.isDisabled());

    // Sound-Abspielen-Schaltfläche betätigen
    final AudioPlayer player = mock(AudioPlayer.class);
    controller.getGuiHelper().setAudioPlayer(player);
    click(alarmPlaySoundButton);
    waitForThreads();
    verify(player)
        .playInThread(
            isA(ThreadHelper.class), eq("Sound"), isA(Thread.UncaughtExceptionHandler.class));

    // Sound-Löschen-Schaltfläche betätigen
    click(alarmNoSoundButton);
    waitForThreads();

    // sicherstellen, dass nicht Dialog geschlossen worden wäre
    verify(mockedDialogStage, never()).close();

    assertEquals("kein Klingelton gewählt", alarmSelectSoundButton.getText());
  }
  /** Testet Anzeige der Fehlermeldung bei leerem Datum. */
  @Test
  public final void testErrorDateEmpty() {
    controller.setDialogStage(mockedDialogStage);

    controller.setExistingAlarms(Arrays.asList(new Alarm()));

    // Alarm vorgeben
    controller.setAlarm(new Alarm());
    FXTestUtils.awaitEvents();

    // Datum leeren
    Platform.runLater(
        new Runnable() {
          public void run() {
            alarmDatePicker.setValue(null);
          }
        });
    FXTestUtils.awaitEvents();

    final MessageHelper messageHelper = mock(MessageHelper.class);
    controller.getGuiHelper().setMessageHelper(messageHelper);

    // Speichern-Schaltfläche betätigen
    click(alarmSaveButton);
    waitForThreads();

    // sicherstellen, dass nicht Dialog geschlossen worden wäre
    verify(mockedDialogStage, never()).close();

    // sicherstellen, dass Fehlermeldung erscheint
    verify(messageHelper)
        .showDialogMessage(
            anyString(), eq("Ein Datum muss angegeben werden.\n"), isA(ResourceBundle.class));
  }
  /** Testet Anzeige bzw. Ausbleiben von Fehlermeldungen beim Speichern eines Alarms. */
  @Test
  public final void testErrorWhenSavingAlarm() {
    final List<DataErrors> testCases = new Vector<>();

    // Anlegen/Bearbeiten eines Alarms mit Zeitstempel in Vergangenheit
    testCases.add(
        new DataErrors(
            1,
            "Der Alarm-Zeitpunkt muss in der Zukunft liegen.\n",
            null,
            new Alarm(DateTimeUtil.getLocalDateTimeForString("01.01.1970 00:00:00"), "Alarm")));
    // Anlegen/Bearbeiten eines Alarms mit Zeitstempel in Zukunft
    testCases.add(
        new DataErrors(
            0,
            null,
            null,
            new Alarm(DateTimeUtil.getLocalDateTimeForString("01.01.2050 00:00:00"), "Alarm")));
    // Anlegen/Bearbeiten eines inaktiven Alarms mit Zeitstempel in Vergangenheit
    testCases.add(
        new DataErrors(
            0,
            null,
            null,
            new Alarm(
                DateTimeUtil.getLocalDateTimeForString("01.01.1970 00:00:00"),
                "Alarm",
                null,
                false)));
    // Anlegen/Bearbeiten eines inaktiven Alarms mit Zeitstempel in Zukunft
    testCases.add(
        new DataErrors(
            0,
            null,
            null,
            new Alarm(
                DateTimeUtil.getLocalDateTimeForString("01.01.2050 00:00:00"),
                "Alarm",
                null,
                false)));

    // Anlegen eines Alarms mit identischem Zeitstempel
    testCases.add(
        new DataErrors(
            1,
            "Ein anderer Alarm mit demselben Zeitpunkt existiert bereits.\n",
            Arrays.asList(
                new Alarm(DateTimeUtil.getLocalDateTimeForString("01.01.2050 00:00:00"), "Alarm1")),
            new Alarm(DateTimeUtil.getLocalDateTimeForString("01.01.2050 00:00:00"), "Alarm2")));
    // Anlegen eines Alarms mit unterschiedlichem Zeitstempel
    testCases.add(
        new DataErrors(
            0,
            null,
            Arrays.asList(
                new Alarm(DateTimeUtil.getLocalDateTimeForString("01.01.2050 00:00:00"), "Alarm1")),
            new Alarm(DateTimeUtil.getLocalDateTimeForString("11.11.2160 00:00:00"), "Alarm2")));
    // Bearbeiten eines Alarms ohne Änderung des Zeitstempels
    final Alarm alarm =
        new Alarm(
            DateTimeUtil.getLocalDateTimeForString("01.01.2050 00:00:00"),
            "Alarm1"); // genau ein Objekt
    testCases.add(new DataErrors(0, null, Arrays.asList(alarm), alarm));

    for (final DataErrors testCase : testCases) {
      reset(mockedDialogStage);
      controller.setDialogStage(mockedDialogStage);

      controller.setExistingAlarms(testCase.existingAlarms);
      controller.setAlarm(testCase.alarm);
      FXTestUtils.awaitEvents();

      final MessageHelper messageHelper = mock(MessageHelper.class);
      controller.getGuiHelper().setMessageHelper(messageHelper);

      // Speichern-Schaltfläche betätigen
      click(alarmSaveButton);
      waitForThreads();

      // sicherstellen, dass nicht Dialog geschlossen worden wäre
      verify(mockedDialogStage, testCase.numberOfCalls > 0 ? never() : times(1)).close();

      // sicherstellen, dass Fehlermeldung erscheint bzw. nicht
      verify(messageHelper, times(testCase.numberOfCalls))
          .showDialogMessage(
              anyString(),
              testCase.errorMessage == null ? anyString() : eq(testCase.errorMessage),
              isA(ResourceBundle.class));
    }
  }