package com.contentful.java.cda;

import com.contentful.java.cda.lib.Enqueue;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import org.junit.Test;
import rx.functions.Action1;

import static com.google.common.truth.Truth.assertThat;

public class EntryTest extends BaseTest {
  @Test
  @Enqueue("demo/array_empty.json")
  public void fetchNonExistingReturnsNull() throws Exception {
    assertThat(client.fetch(CDAEntry.class).one("foo")).isNull();
  }

  @Test
  @Enqueue("demo/array_empty.json")
  public void fetchNonExistingEntryEmitsNull() throws Exception {
    final Object result[] = new Object[] { new Object() };
    final CountDownLatch latch = new CountDownLatch(1);
    assertThat(client.observe(CDAEntry.class)
        .one("foo")
        .subscribe(new Action1<CDAEntry>() {
          @Override public void call(CDAEntry entry) {
            result[0] = entry;
            latch.countDown();
          }
        }));
    latch.await();
    assertThat(result[0]).isNull();
  }

  @Test
  @Enqueue("demo/array_empty.json")
  public void fetchNonExistingEntryInvokesSuccessWithNull() throws Exception {
    final Object result[] = new Object[] { new Object() };
    final CountDownLatch latch = new CountDownLatch(1);
    client.fetch(CDAEntry.class).one("foo", new CDACallback<CDAEntry>() {
      @Override protected void onSuccess(CDAEntry entry) {
        result[0] = entry;
        latch.countDown();
      }
    });
    latch.await();
    assertThat(result[0]).isNull();
  }

  @Test
  @Enqueue("demo/entries_nyancat.json")
  public void entryContentType() throws Exception {
    CDAEntry entry = client.fetch(CDAEntry.class).one("nyancat");
    assertThat(entry.contentType()).isNotNull();
  }

  @Test
  @Enqueue("demo/entries_nyancat.json")
  public void fetchEntry() throws Exception {
    assertNyanCat(client.fetch(CDAEntry.class).one("nyancat"));
  }

  @Test
  @Enqueue("demo/entries_nyancat.json")
  public void fetchEntryAsync() throws Exception {
    final CountDownLatch latch = new CountDownLatch(1);
    final CDAEntry[] result = { null };

    client.fetch(CDAEntry.class).one("nyancat", new CDACallback<CDAEntry>() {
      @Override protected void onSuccess(CDAEntry entry) {
        result[0] = entry;
        latch.countDown();
      }

      @Override protected void onFailure(Throwable error) {
        latch.countDown();
      }
    });

    latch.await();
    assertThat(result[0]).isNotNull();
    assertNyanCat(result[0]);
  }

  @Test
  @Enqueue("demo/entries.json")
  public void fetchAllEntries() throws Exception {
    CDAArray array = client.fetch(CDAEntry.class).all();
    assertThat(array.items()).hasSize(15);
    assertThat(array.assets()).hasSize(4);
    assertThat(array.entries()).hasSize(11);

    assertThat(array.total()).isEqualTo(11);
    assertThat(array.skip()).isEqualTo(0);
    assertThat(array.limit()).isEqualTo(100);

    for (CDAEntry entry : array.entries().values()) {
      assertThat(entry.contentType()).isNotNull();
    }

    CDAEntry nyanCat = array.entries().get("nyancat");
    assertThat(nyanCat).isNotNull();
    assertNyanCat(nyanCat);
  }

  private void assertNyanCat(CDAEntry entry) {
    assertThat(entry.id()).isEqualTo("nyancat");
    assertThat(entry.getField("name")).isEqualTo("Nyan Cat");
    assertThat(entry.getField("color")).isEqualTo("rainbow");
    assertThat(entry.getField("birthday")).isEqualTo("2011-04-04T22:00:00+00:00");
    assertThat(entry.getField("lives")).isEqualTo(1337.0);

    List<String> likes = entry.getField("likes");
    assertThat(likes).containsExactly("rainbows", "fish");

    Object bestFriend = entry.getField("bestFriend");
    assertThat(bestFriend).isInstanceOf(CDAEntry.class);
    assertThat(entry).isSameAs(((CDAEntry) bestFriend).getField("bestFriend"));

    // Localization
    assertThat(entry.locale()).isEqualTo("en-US");
    entry.setLocale("tlh");
    assertThat(entry.getField("color")).isEqualTo("rainbow");
    assertThat(entry.getField("non-existing-does-not-throw")).isNull();
  }
}

@@ -71,16 +71,65 @@
 nqueue;%0A
+import com.contentful.java.cda.lib.TestCallback;%0A
 import j
@@ -1186,122 +1186,41 @@
     
-final Object result%5B%5D = new Object%5B%5D %7B new Object() %7D;%0A    final CountDownLatch latch = new CountDownLatch(1);%0A   
+TestCallback%3CCDAEntry%3E callback =
  cli
@@ -1236,32 +1236,41 @@
 (CDAEntry.class)
+%0A        
 .one(%22foo%22, new 
@@ -1265,27 +1265,28 @@
 (%22foo%22, new 
-CDA
+Test
 Callback%3CCDA
@@ -1297,155 +1297,68 @@
 y%3E()
- %7B
+)
 %0A      
-@Override protected void onSuccess(CDAEntry entry) %7B%0A        result%5B0%5D = entry;%0A        latch.countDown();%0A      %7D%0A    %7D);%0A    latch.await
+  .await();%0A%0A    assertThat(callback.error()).isNull
 ();%0A
@@ -1368,33 +1368,41 @@
  assertThat(
+callback.
 result
-%5B0%5D
+()
 ).isNull();%0A

Use `TestCallback` in test