All Downloads are FREE. Search and download functionalities are using the official Maven repository.

test.java.com.cloudant.tests.ViewPaginationTests Maven / Gradle / Ivy

There is a newer version: 2.20.1
Show newest version
/*
 * Copyright (c) 2015 IBM Corp. All rights reserved.
 *
 * 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 com.cloudant.tests;

import static org.junit.Assert.assertEquals;

import com.cloudant.client.api.Database;
import com.cloudant.client.api.views.Key;
import com.cloudant.client.api.views.ViewRequest;
import com.cloudant.client.api.views.ViewResponse;
import com.cloudant.tests.util.CheckPagination;
import com.cloudant.tests.util.CloudantClientResource;
import com.cloudant.tests.util.DatabaseResource;
import com.cloudant.tests.util.Utils;

import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import java.util.ArrayList;
import java.util.List;

@RunWith(Parameterized.class)
public class ViewPaginationTests {

    /**
     * Parameters for these tests so we run each test multiple times.
     * We run with a single key or a complex key and both ascending and descending.
     */
    @Parameterized.Parameters(name = "Key:{0},Descending:{1},Stateless:{2}")
    public static Iterable data() {

        boolean[] tf = new boolean[]{true, false};
        List parameters = new ArrayList();
        for (CheckPagination.Type type : CheckPagination.Type.values()) {
            for (boolean descending : tf) {
                for (boolean stateless : tf) {
                    parameters.add(new Object[]{type, descending, stateless});
                }
            }
        }
        return parameters;
    }

    @Parameterized.Parameter
    public CheckPagination.Type type;

    @Parameterized.Parameter(value = 1)
    public boolean descending;

    @Parameterized.Parameter(value = 2)
    public boolean stateless;

    @ClassRule
    public static CloudantClientResource clientResource = new CloudantClientResource();
    @Rule
    public DatabaseResource dbResource = new DatabaseResource(clientResource);

    private Database db;

    @Before
    public void setUp() throws Exception {
        db = dbResource.get();
        Utils.putDesignDocs(db);
    }

    /**
     * Check that we can page through a view where the number of results
     * is an exact multiple of the number of pages. Check each page contains the documents
     * we expect.
     *
     * Page forward to the last page, back to the first page, forward to the last page and back to
     * the first page.
     */
    @Test
    public void allTheWayInEachDirectionTwice() throws Exception {
        CheckPagination.newTest(type)
                .descending(descending)
                .docCount(6)
                .docsPerPage(2)
                .pageToPages(3, 1, 3, 1)
                .stateless(stateless)
                .runTest(db);
    }

    /**
     * Check that we can page through a view where the number of results
     * is not an exact multiple of the number of pages. Check each page contains the documents
     * we expect.
     *
     * Page forward to the last page, back to the first page, forward to the last page and back to
     * the first page.
     */
    @Test
    public void partialLastPageAllTheWayInEachDirectionTwice() throws Exception {
        CheckPagination.newTest(type)
                .descending(descending)
                .docCount(5)
                .docsPerPage(2)
                .pageToPages(3, 1, 3, 1)
                .stateless(stateless)
                .runTest(db);
    }

    /**
     * Check that we can page through a view where the number of results
     * is an exact multiple of the number of pages. Check each page contains the documents
     * we expect.
     *
     * Page part way forward, and part way back a few times before paging to the last page.
     */
    @Test
    public void partWayInEachDirection() throws Exception {
        CheckPagination.newTest(type)
                .descending(descending)
                .docCount(30)
                .docsPerPage(5)
                .pageToPages(4, 2, 5, 3, 4, 2, 6)
                .stateless(stateless)
                .runTest(db);
    }

    /**
     * Check that we can page through a view where the number of results
     * is not an exact multiple of the number of pages. Check each page contains the documents
     * we expect.
     *
     * Page part way forward, and part way back a few times before paging to the last page.
     */
    @Test
    public void partialLastPagePartWayInEachDirection() throws Exception {
        CheckPagination.newTest(type)
                .descending(descending)
                .docCount(28)
                .docsPerPage(5)
                .pageToPages(4, 2, 5, 3, 4, 2, 6)
                .stateless(stateless)
                .runTest(db);
    }

    /**
     * Check that we can page through a view where we use start and end keys.
     * Assert that we don't exceed the limits of those keys.
     */
    @Test
    public void startAndEndKeyLimits() throws Exception {
        startAndEndKeyLimits(true);
    }

    /**
     * Check that we can page through a view where we use start and end keys.
     * Assert that we don't exceed the limits of those keys.
     */
    @Test
    public void startAndEndKeyLimitsExclusiveEnd() throws Exception {
        startAndEndKeyLimits(false);
    }

    private void startAndEndKeyLimits(boolean inclusiveEnd) throws Exception {
        //use the CheckPagination to set-up for this test, but we need to do running differently
        //since this page is not just simple paging
        CheckPagination cp = CheckPagination.newTest(type)
                .descending(descending)
                .docCount(20)
                .docsPerPage(4)
                .stateless(stateless);
        cp.initTest(db);

        // set up the start and end keys based on the test type
        // if we are descending then the start and end keys need to be reversed
        // if we are exclusive end then we need to change the expected end key
        // then run the test with the correct request and limits
        if (CheckPagination.Type.SINGLE.equals(type)) {
            String startKey = (descending) ? "011" : "003";
            String endKey = (descending) ? "003" : "011";
            String expectedEndKey = (inclusiveEnd) ? endKey : ((descending) ? "004" : "010");
            ViewRequest request = db.getViewRequestBuilder("example", "foo")
                    .newPaginatedRequest(Key.Type.STRING, String.class).reduce(false).descending
                            (descending).inclusiveEnd(inclusiveEnd).rowsPerPage(4).startKey
                            (startKey).endKey(endKey).build();
            runStartAndEndKeyLimits(request, startKey, expectedEndKey);
        } else {
            //for multi we will use the creator_created view
            Key.ComplexKey startKey = (descending) ? Key.complex("uuid").add(1011) : Key.complex
                    ("uuid").add(1003);
            Key.ComplexKey endKey = (descending) ? Key.complex("uuid").add(1003) : Key.complex
                    ("uuid").add(1011);
            Key.ComplexKey expectedEndKey = (inclusiveEnd) ? endKey : ((descending) ? Key.complex
                    ("uuid").add(1004) : Key.complex("uuid").add(1010));
            ViewRequest request = db.getViewRequestBuilder("example",
                    "creator_created")
                    .newPaginatedRequest(Key.Type.COMPLEX, String.class).reduce(false).descending
                            (descending).inclusiveEnd(inclusiveEnd).rowsPerPage(4).startKey
                            (startKey).endKey(endKey).build();
            runStartAndEndKeyLimits(request, startKey, expectedEndKey);
        }
    }

    private  void runStartAndEndKeyLimits(ViewRequest request, T expectedStartKey,
                                             T expectedEndKey)
            throws Exception {

        ViewResponse page = request.getResponse();

        //check the start key is as expected
        assertEquals("The start key should be " + expectedStartKey, expectedStartKey, page
                .getKeys().get(0));

        //get the last page
        while (page.hasNextPage()) {
            if (stateless) {
                page = request.getResponse(page.getNextPageToken());
            } else {
                page = page.nextPage();
            }
        }
        //check the end key is as expected
        assertEquals("The end key should be " + expectedEndKey, expectedEndKey, page.getKeys()
                .get(page.getKeys()
                        .size()
                        - 1));

        //now page backwards and ensure the last key we get is the start key
        while (page.hasPreviousPage()) {
            if (stateless) {
                page = request.getResponse(page.getPreviousPageToken());
            } else {
                page = page.previousPage();
            }
        }
        //check the start key is as expected
        assertEquals("The start key should be " + expectedStartKey, expectedStartKey, page
                .getKeys().get(0));
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy