package com.getbase.android.db.provider;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.net.Uri;

import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.eq;

@RunWith(RobolectricTestRunner.class)
@Config(manifest = Config.NONE)
public class ProviderActionsTest {

  private static final Uri TEST_URI = Uri.parse("content://authority/people");

  @Mock
  private ContentResolver contentResolverMock;

  @Before
  public void setUp() throws Exception {
    MockitoAnnotations.initMocks(this);
  }

  @Test
  public void shouldPassNullsEverywhere() throws Exception {
    ProviderAction.query(TEST_URI)
        .perform(contentResolverMock);
    verify(contentResolverMock).query(eq(TEST_URI), eq((String[]) null), eq((String) null), eq((String[]) null), eq((String) null));
  }

  @Test
  public void shouldUseProjectionWhenQuery() throws Exception {
    ProviderAction.query(TEST_URI)
        .projection("COL1")
        .perform(contentResolverMock);
    verify(contentResolverMock).query(eq(TEST_URI), eq(new String[] { "COL1" }), eq((String) null), eq((String[]) null), eq((String) null));
  }

  @Test
  public void shouldAppendProjection() throws Exception {
    ProviderAction.query(TEST_URI)
        .projection("COL1")
        .projection("COL2")
        .perform(contentResolverMock);
    verify(contentResolverMock).query(eq(TEST_URI), eq(new String[] { "COL1", "COL2" }), eq((String) null), eq((String[]) null), eq((String) null));
  }

  @Test
  public void shouldConcatenateSelectionProperlyWhenQuerying() throws Exception {
    ProviderAction.query(TEST_URI)
        .where("COL1 = ?", "arg")
        .where("COL2 = ?", "arg2")
        .perform(contentResolverMock);
    verify(contentResolverMock).query(eq(TEST_URI), eq((String[]) null), eq("COL1 = ? AND COL2 = ?"), eq(new String[] { "arg", "arg2" }), eq((String) null));
  }

  @Test
  public void shouldUseOrderBy() throws Exception {
    ProviderAction.query(TEST_URI)
        .orderBy("COL1 DESC")
        .perform(contentResolverMock);
    verify(contentResolverMock).query(eq(TEST_URI), eq((String[]) null), eq((String) null), eq((String[]) null), eq("COL1 DESC"));
  }

  @Test
  public void shouldPerformProperInsert() throws Exception {
    ContentValues values = new ContentValues();
    values.put("asdf", "value");
    ProviderAction.insert(TEST_URI)
        .values(values)
        .perform(contentResolverMock);
    verify(contentResolverMock).insert(eq(TEST_URI), eq(values));
  }

  @Test
  public void shouldPerformUpdateWithValues() throws Exception {
    ContentValues values = new ContentValues();
    values.put("col1", "val1");
    ProviderAction.update(TEST_URI)
        .values(values)
        .perform(contentResolverMock);
    verify(contentResolverMock).update(eq(TEST_URI), eq(values), eq((String) null), eq((String[]) null));
  }

  @Test
  public void shouldPerformUpdateWithSelectionAndSelectionArgs() throws Exception {
    ContentValues values = new ContentValues();
    values.put("col1", "val1");
    ProviderAction.update(TEST_URI)
        .values(values)
        .where("col2 = ?", "blah")
        .perform(contentResolverMock);
    verify(contentResolverMock).update(eq(TEST_URI), eq(values), eq("col2 = ?"), eq(new String[] { "blah" }));
  }

  @Test
  public void shouldPerformDeleteOnUri() throws Exception {
    ProviderAction.delete(TEST_URI).perform(contentResolverMock);
    verify(contentResolverMock).delete(eq(TEST_URI), eq((String) null), eq((String[]) null));
  }

  @Test
  public void shouldCareAboutSelectionAndSelectionArgsWhenDeleting() throws Exception {
    ProviderAction.delete(TEST_URI)
        .where("col1 = ?", "val1")
        .perform(contentResolverMock);
    verify(contentResolverMock).delete(eq(TEST_URI), eq("col1 = ?"), eq(new String[] { "val1" }));
  }

  @Test
  public void shouldBeAbleToUseNonStringObjectsInSelectionArgs() throws Exception {
    ProviderAction.query(TEST_URI)
        .where("col1 > ?", 18)
        .perform(contentResolverMock);
    verify(contentResolverMock).query(eq(TEST_URI), eq((String[]) null), eq("col1 > ?"), eq(new String[] { "18" }), eq((String) null));
  }
}

@@ -453,16 +453,177 @@
 to.eq;%0A%0A
+import com.google.common.base.Joiner;%0Aimport com.google.common.collect.Lists;%0A%0Aimport java.util.ArrayList;%0Aimport java.util.Collections;%0Aimport java.util.List;%0A%0A
 @RunWith
@@ -4583,11 +4583,592 @@
 l));%0A  %7D
+%0A%0A  @Test%0A  public void shouldBeAbleToCreateASelectionWithWhereIn() throws Exception %7B%0A    final List%3CString%3E inSet = Lists.newArrayList(%22one%22, %22two%22, %22three%22);%0A    ProviderAction.query(TEST_URI)%0A        .whereIn(%22col1%22, inSet)%0A        .perform(contentResolverMock);%0A    final String expectedSelection = %22col1 IN (%22 + Joiner.on(%22,%22).join(Collections.nCopies(inSet.size(), %22?%22)) + %22)%22;%0A    verify(contentResolverMock).query(eq(TEST_URI),%0A        eq((String%5B%5D) null),%0A        eq(expectedSelection),%0A        eq(inSet.toArray(new String%5BinSet.size()%5D)),%0A        eq((String) null));%0A  %7D
 %0A%7D%0A

Add missing spec for Query.whereIn()