package moe.tristan.easyfxml.model.awt.integrations;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import moe.tristan.easyfxml.spring.application.FxSpringContext;
import io.vavr.control.Try;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.awt.MenuItem;
import java.awt.TrayIcon;
import java.awt.event.ActionListener;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;

import static java.util.concurrent.TimeUnit.SECONDS;
import static org.assertj.core.api.Assertions.assertThat;

/**
 * This test is wholly incomplete. Consider it absent for now.
 */
@ContextConfiguration(classes = FxSpringContext.class)
@RunWith(SpringRunner.class)
public class SystemTraySupportTest {

    private static final String TRAY_LABEL = "TEST_LABEL";
    private static final URL TRAY_ICON_URL = getTrayIcon();

    @Autowired
    private ApplicationContext applicationContext;

    @Test
    public void register_system_tray_icon() throws ExecutionException, InterruptedException, TimeoutException {
        final SystemTraySupport systemTraySupport = this.applicationContext.getBean(SystemTraySupport.class);

        final MenuItem testItem = new MenuItem("DISABLED_ON_CLICK");
        final ActionListener disableOnClick = e -> testItem.setEnabled(false);

        final Map<MenuItem, ActionListener> menuItems = new HashMap<>();
        menuItems.put(testItem, disableOnClick);

        final SystemTrayIcon trayIcon = this.systemTrayIconWith(menuItems);
        final CompletionStage<Try<TrayIcon>> asyncRegistrationRes = systemTraySupport.registerTrayIcon(trayIcon);
        final Try<TrayIcon> registrationRes = asyncRegistrationRes.toCompletableFuture().get(5, SECONDS);

        assertThat(registrationRes.isSuccess()).isTrue();
        assertThat(systemTraySupport.getTrayIcons()).containsExactly(registrationRes.get());

        final CompletionStage<Void> asyncRemove = systemTraySupport.removeTrayIcon(registrationRes.get());
        asyncRemove.toCompletableFuture().get(5, SECONDS);

        assertThat(systemTraySupport.getTrayIcons()).doesNotContain(registrationRes.get());
    }

    private SystemTrayIcon systemTrayIconWith(final Map<MenuItem, ActionListener> menuItems) {
        return new SystemTrayIcon() {
            @Override
            public String getLabel() {
                return TRAY_LABEL;
            }

            @Override
            public URL getIcon() {
                return TRAY_ICON_URL;
            }

            @Override
            public Map<MenuItem, ActionListener> getMenuItems() {
                return menuItems;
            }
        };
    }

    private static URL getTrayIcon() {
        return SystemTraySupportTest.class.getClassLoader().getResource("images/duke.jpg");
    }
}

@@ -284,24 +284,92 @@
 ringRunner;%0A
+import moe.tristan.easyfxml.model.awt.objects.OnMouseClickListener;%0A
 import moe.t
@@ -505,16 +505,115 @@
 nWith;%0A%0A
+import javafx.beans.property.BooleanProperty;%0Aimport javafx.beans.property.SimpleBooleanProperty;%0A%0A
 import j
@@ -690,24 +690,61 @@
 onListener;%0A
+import java.awt.event.MouseListener;%0A
 import java.
@@ -1361,24 +1361,105 @@
 rayIcon();%0A%0A
+    private BooleanProperty clickRegistered = new SimpleBooleanProperty(false);%0A%0A
     @Autowir
@@ -2047,17 +2047,20 @@
 rayIcon 
-t
+sysT
 rayIcon 
@@ -2200,17 +2200,20 @@
 rayIcon(
-t
+sysT
 rayIcon)
@@ -2469,24 +2469,428 @@
 es.get());%0A%0A
+        registrationRes.map(trayIcon -%3E %7B%0A            assertThat(trayIcon.getMouseListeners()).hasSize(1);%0A            return trayIcon.getMouseListeners()%5B0%5D;%0A        %7D).andThenTry(mouseListener -%3E %7B%0A            assertThat(mouseListener).isSameAs(sysTrayIcon.onMouseClickListener());%0A            mouseListener.mousePressed(null);%0A            assertThat(clickRegistered.getValue()).isTrue();%0A        %7D);%0A%0A
         fina
@@ -3234,24 +3234,140 @@
 enuItems) %7B%0A
+%0A        final MouseListener onMouseClickListener = new OnMouseClickListener(e -%3E clickRegistered.setValue(true));%0A%0A
         retu
@@ -3748,16 +3748,156 @@
        %7D
+%0A%0A            @Override%0A            public MouseListener onMouseClickListener() %7B%0A                return onMouseClickListener;%0A            %7D
 %0A       

Add testing for convenience methods for mouse listening.