package com.jenzz.appstate.internal;

import android.app.Application;
import android.app.Application.ActivityLifecycleCallbacks;
import android.content.ComponentCallbacks2;
import android.content.Intent;
import com.jenzz.appstate.AppStateListener;
import com.jenzz.appstate.dummies.DummyAppStateListener;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;

import static android.content.ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
import static android.content.Intent.ACTION_SCREEN_OFF;
import static org.assertj.core.api.Java6Assertions.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.MockitoAnnotations.initMocks;

public class AppStateRecognizerTest {

  @Mock Application mockApplication;
  @Mock AppStateListener mockAppStateListener;

  @Captor ArgumentCaptor<ComponentCallbacks2> componentCallbacksCaptor;

  private final AppStateRecognizer appStateRecognizer = new AppStateRecognizer();

  @Before
  public void setUp() {
    initMocks(this);
  }

  @Test
  public void registerCallbacks() {
    appStateRecognizer.start(mockApplication, new DummyAppStateListener());

    verify(mockApplication).registerActivityLifecycleCallbacks(any(ActivityLifecycleCallbacks.class));
    verify(mockApplication).registerComponentCallbacks(any(ComponentCallbacks2.class));
  }

  @Test
  public void unregistersCallbacks() {
    appStateRecognizer.stop(mockApplication);

    verify(mockApplication).unregisterActivityLifecycleCallbacks(any(ActivityLifecycleCallbacks.class));
    verify(mockApplication).unregisterComponentCallbacks(any(ComponentCallbacks2.class));
  }

  @Test
  public void doesNotReturnNullAppStateByDefault() {
    assertThat(appStateRecognizer.getAppState()).isNotNull();
  }

  @Test
  public void doesNotEmitBackgroundWhenScreenOffAndAppMonitoringJustStarted() {
    appStateRecognizer.start(mockApplication, mockAppStateListener);

    mockApplication.sendBroadcast(new Intent(ACTION_SCREEN_OFF));

    verify(mockAppStateListener, never()).onAppDidEnterBackground();
  }

  @Test
  public void doesNotEmitBackgroundWhenScreenOffAndAppAlreadyOnBackground() {
    appStateRecognizer.start(mockApplication, mockAppStateListener);
    verify(mockApplication).registerComponentCallbacks(componentCallbacksCaptor.capture());
    final ComponentCallbacks2 componentCallbacks = componentCallbacksCaptor.getValue();

    componentCallbacks.onTrimMemory(TRIM_MEMORY_UI_HIDDEN);
    mockApplication.sendBroadcast(new Intent(ACTION_SCREEN_OFF));

    verify(mockAppStateListener, times(1)).onAppDidEnterBackground();
  }
}

@@ -122,16 +122,58 @@
 lbacks;%0A
+import android.content.BroadcastReceiver;%0A
 import a
@@ -239,16 +239,54 @@
 Intent;%0A
+import android.content.IntentFilter;%0A%0A
 import c
@@ -374,24 +374,25 @@
 teListener;%0A
+%0A
 import org.j
@@ -1298,16 +1298,17 @@
 register
+s
 Callback
@@ -1573,32 +1573,133 @@
 backs2.class));%0A
+    verify(mockApplication).registerReceiver(any(BroadcastReceiver.class), any(IntentFilter.class));%0A
   %7D%0A%0A  @Test%0A  p
@@ -1968,32 +1968,110 @@
 backs2.class));%0A
+    verify(mockApplication).unregisterReceiver(any(BroadcastReceiver.class));%0A
   %7D%0A%0A  @Test%0A  p

Add tests for registering / unregistering screen off BroadcastReceiver