/*
* Copyright 2016 Google 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 com.example.appengine;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.SortDirection;
import com.google.appengine.api.datastore.QueryResultList;
import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig;
import com.google.appengine.tools.development.testing.LocalServiceTestHelper;
import com.google.common.collect.ImmutableList;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.io.PrintWriter;
import java.io.StringWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Unit tests for {@link ListPeopleServlet}.
*/
@RunWith(JUnit4.class)
public class ListPeopleServletTest {
private static final ImmutableList<String> TEST_NAMES =
// Keep in alphabetical order, so this is the same as the query order.
ImmutableList.<String>builder()
.add("Alpha")
.add("Bravo")
.add("Charlie")
.add("Delta")
.add("Echo")
.add("Foxtrot")
.add("Golf")
.add("Hotel")
.add("India")
.add("Juliett")
.add("Kilo")
.add("Lima")
.add("Mike")
.add("November")
.add("Oscar")
.add("Papa")
.add("Quebec")
.add("Romeo")
.add("Sierra")
.add("Tango")
.build();
private final LocalServiceTestHelper helper =
new LocalServiceTestHelper(
// Set no eventual consistency, that way queries return all results.
// https://cloud.google.com/appengine/docs/java/tools/localunittesting#Java_Writing_High_Replication_Datastore_tests
new LocalDatastoreServiceTestConfig()
.setDefaultHighRepJobPolicyUnappliedJobPercentage(0));
@Mock private HttpServletRequest mockRequest;
@Mock private HttpServletResponse mockResponse;
private StringWriter responseWriter;
private DatastoreService datastore;
private ListPeopleServlet servletUnderTest;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
helper.setUp();
datastore = DatastoreServiceFactory.getDatastoreService();
// Add test data.
ImmutableList.Builder<Entity> people = ImmutableList.builder();
for (String name : TEST_NAMES) {
people.add(createPerson(name));
}
datastore.put(people.build());
// Set up a fake HTTP response.
responseWriter = new StringWriter();
when(mockResponse.getWriter()).thenReturn(new PrintWriter(responseWriter));
servletUnderTest = new ListPeopleServlet();
}
@After
public void tearDown() {
helper.tearDown();
}
private Entity createPerson(String name) {
Entity person = new Entity("Person");
person.setProperty("name", name);
return person;
}
@Test
public void doGet_noCursor_writesNames() throws Exception {
servletUnderTest.doGet(mockRequest, mockResponse);
String response = responseWriter.toString();
for (int i = 0; i < ListPeopleServlet.PAGE_SIZE; i++) {
assertThat(response).named("ListPeopleServlet response").contains(TEST_NAMES.get(i));
}
}
private String getFirstCursor() {
Query q = new Query("Person").addSort("name", SortDirection.ASCENDING);
PreparedQuery pq = datastore.prepare(q);
FetchOptions fetchOptions = FetchOptions.Builder.withLimit(ListPeopleServlet.PAGE_SIZE);
QueryResultList<Entity> results = pq.asQueryResultList(fetchOptions);
return results.getCursor().toWebSafeString();
}
@Test
public void doGet_withValidCursor_writesNames() throws Exception {
when(mockRequest.getParameter("cursor")).thenReturn(getFirstCursor());
servletUnderTest.doGet(mockRequest, mockResponse);
String response = responseWriter.toString();
int i = 0;
while (i + ListPeopleServlet.PAGE_SIZE < TEST_NAMES.size() && i < ListPeopleServlet.PAGE_SIZE) {
assertThat(response)
.named("ListPeopleServlet response")
.contains(TEST_NAMES.get(i + ListPeopleServlet.PAGE_SIZE));
i++;
}
}
@Test
public void doGet_withInvalidCursor_writesRedirect() throws Exception {
when(mockRequest.getParameter("cursor")).thenReturn("ThisCursorIsTotallyInvalid");
servletUnderTest.doGet(mockRequest, mockResponse);
verify(mockResponse).sendRedirect("/people");
}
}