/*
 * Copyright (C) 2015 8tory, Inc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package rx.parse;

import com.parse.*;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import bolts.Task;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static mocker.Mocker.mocker;
import rx.Observable;

public class ParseObservableTest {

    @Test
    public void testParseObservableAllNextAfterCompleted() {
        List<ParseUser> users = Arrays.asList(
                mocker(ParseUser.class).when(user -> user.getObjectId()).thenReturn(user -> "1_" + user.hashCode()).mock(),
                mocker(ParseUser.class).when(user -> user.getObjectId()).thenReturn(user -> "2_" + user.hashCode()).mock(),
                mocker(ParseUser.class).when(user -> user.getObjectId()).thenReturn(user -> "3_" + user.hashCode()).mock());

        rx.assertions.RxAssertions.assertThat(rx.parse.ParseObservable.all(mocker(ParseQuery.class)
                    .when(query -> query.countInBackground()).thenReturn(query -> Task.forResult(users.size()))
                    .when(query -> query.findInBackground()).thenReturn(query -> Task.forResult(users))
                    .when(query -> query.setSkip(any(int.class))).thenReturn(query -> null)
                    .when(query -> query.setLimit(any(int.class))).thenReturn(query -> null).mock()))
            .withoutErrors()
            .expectedValues(users)
            .completes();
    }

    @Test
    public void testParseObservableAllForMass() {
        // FIXME: how mockito to make mass mocks?
        List<ParseUser> users = Observable.range(1, 1001)
            .map(i -> mocker(ParseUser.class).when(user -> user.getObjectId()).thenReturn(user -> "" + user.hashCode()).mock())
            .toList()
            .toBlocking()
            .single();

        rx.assertions.RxAssertions.assertThat(rx.parse.ParseObservable.all(mocker(ParseQuery.class)
                    .when(query -> query.countInBackground()).thenReturn(query -> Task.forResult(users.size()))
                    .when(query -> query.findInBackground()).thenReturn(query -> Task.forResult(users))
                    .when(query -> query.setSkip(any(int.class))).thenReturn(query -> null)
                    .when(query -> query.setLimit(any(int.class))).thenReturn(query -> null).mock()))
            .withoutErrors()
            .expectedValues(users)
            .completes();
    }

    @Test
    public void testParseObservableFindNextAfterCompleted() {
        List<ParseUser> users = Arrays.asList(mock(ParseUser.class), mock(ParseUser.class), mock(ParseUser.class));

        rx.assertions.RxAssertions.assertThat(rx.parse.ParseObservable.find(mocker(ParseQuery.class)
                    .when(query -> query.findInBackground()).thenReturn(query -> Task.forResult(users))
                    .mock()))
            .withoutErrors()
            .expectedValues(users)
            .completes();
    }

    @Test
    public void testBlockingFind() {
        List<ParseUser> users = Arrays.asList(mock(ParseUser.class), mock(ParseUser.class), mock(ParseUser.class));
        ParseQuery<ParseUser> query = mocker(ParseQuery.class)
            .when(q -> q.findInBackground()).thenReturn(q -> Task.forResult(users))
            .when(q -> {
                List<ParseUser> list = Collections.emptyList();
                try {
                    list = q.find();
                } catch (Exception e) {
                }
                return list;
            }).thenReturn(q -> users)
            .mock();
        try {
            assertEquals(query.find(), rx.parse.ParseObservable.find(query).toList().toBlocking().single());
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }

    @Test
    public void testParseObservablePin() {
        rx.assertions.RxAssertions.assertThat(rx.parse.ParseObservable.pin(mocker(ParseUser.class)
                    .when(user -> user.pinInBackground())
                    .thenReturn(user -> bolts.Task.<Void>forResult(null))
                    .mock()))
            .withoutErrors()
            .completes();
    }

}

@@ -3944,32 +3944,555 @@
 letes();%0A    %7D%0A%0A
+    @Test%0A    public void testParseObservableFirst() %7B%0A        List%3CParseUser%3E users = Arrays.asList(mock(ParseUser.class), mock(ParseUser.class), mock(ParseUser.class));%0A%0A        rx.assertions.RxAssertions.assertThat(rx.parse.ParseObservable.first(mocker(ParseQuery.class)%0A                    .when(query -%3E query.getFirstInBackground()).thenReturn(query -%3E Task.forResult(users.get(0)))%0A                    .mock()))%0A            .withoutErrors()%0A            .expectedValues(users.get(0))%0A            .completes();%0A    %7D%0A%0A
     @Test%0A    pu
@@ -5665,10 +5665,676 @@
 %0A    %7D%0A%0A
+    @Test%0A    public void testParseObservableSave() %7B%0A        /*%0A        rx.assertions.RxAssertions.assertThat(rx.parse.ParseObservable.save(mocker(ParseUser.class)%0A                    .when(user -%3E %7B%0A                        Task%3CVoid%3E task = Task.forResult(null);%0A                        try %7B%0A                            task = user.saveInBackground();%0A                        %7D catch (Exception e) %7B%0A                        %7D%0A                        return task;%0A                    %7D)%0A                    .thenReturn(user -%3E bolts.Task.%3CVoid%3EforResult(null))%0A                    .mock()))%0A            .withoutErrors()%0A            .completes();%0A        */%0A    %7D%0A%0A
 %7D%0A

Add tests