diff --git a/appengine/firebase-tictactoe/src/main/java/com/example/appengine/firetactoe/DeleteServlet.java b/appengine/firebase-tictactoe/src/main/java/com/example/appengine/firetactoe/DeleteServlet.java
index 7444191e419..5975aa191c4 100644
--- a/appengine/firebase-tictactoe/src/main/java/com/example/appengine/firetactoe/DeleteServlet.java
+++ b/appengine/firebase-tictactoe/src/main/java/com/example/appengine/firetactoe/DeleteServlet.java
@@ -41,6 +41,7 @@ public void doPost(HttpServletRequest request, HttpServletResponse response)
UserService userService = UserServiceFactory.getUserService();
String currentUserId = userService.getCurrentUser().getUserId();
+ // TODO(you): In practice, first validate that the user has permission to delete the Game
game.deleteChannel(currentUserId);
}
}
diff --git a/appengine/firebase-tictactoe/src/main/java/com/example/appengine/firetactoe/MoveServlet.java b/appengine/firebase-tictactoe/src/main/java/com/example/appengine/firetactoe/MoveServlet.java
index fffe9d8a15a..605749969c4 100644
--- a/appengine/firebase-tictactoe/src/main/java/com/example/appengine/firetactoe/MoveServlet.java
+++ b/appengine/firebase-tictactoe/src/main/java/com/example/appengine/firetactoe/MoveServlet.java
@@ -44,7 +44,7 @@ public void doPost(HttpServletRequest request, HttpServletResponse response)
int cell = new Integer(request.getParameter("cell"));
if (!game.makeMove(cell, currentUserId)) {
- response.setStatus(HttpServletResponse.SC_FORBIDDEN);
+ response.sendError(HttpServletResponse.SC_FORBIDDEN);
} else {
ofy.save().entity(game).now();
}
diff --git a/appengine/firebase-tictactoe/src/main/java/com/example/appengine/firetactoe/OpenedServlet.java b/appengine/firebase-tictactoe/src/main/java/com/example/appengine/firetactoe/OpenedServlet.java
index 1553b52da33..8a27c28ee10 100644
--- a/appengine/firebase-tictactoe/src/main/java/com/example/appengine/firetactoe/OpenedServlet.java
+++ b/appengine/firebase-tictactoe/src/main/java/com/example/appengine/firetactoe/OpenedServlet.java
@@ -16,7 +16,6 @@
package com.example.appengine.firetactoe;
-import com.googlecode.objectify.NotFoundException;
import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyService;
@@ -32,19 +31,10 @@ public class OpenedServlet extends HttpServlet {
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException {
+ // TODO(you): In practice, you should validate the user has permission to post to the given Game
String gameId = request.getParameter("gameKey");
Objectify ofy = ObjectifyService.ofy();
- try {
- Game game = ofy.load().type(Game.class).id(gameId).safe();
- if (gameId != null && request.getUserPrincipal() != null) {
- game.sendUpdateToClients();
- response.setContentType("text/plain");
- response.getWriter().println("ok");
- } else {
- response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
- }
- } catch (NotFoundException e) {
- response.setStatus(HttpServletResponse.SC_NOT_FOUND);
- }
+ Game game = ofy.load().type(Game.class).id(gameId).safe();
+ game.sendUpdateToClients();
}
}
diff --git a/appengine/firebase-tictactoe/src/main/java/com/example/appengine/firetactoe/TicTacToeServlet.java b/appengine/firebase-tictactoe/src/main/java/com/example/appengine/firetactoe/TicTacToeServlet.java
index 8eeffda4451..07e040b5244 100644
--- a/appengine/firebase-tictactoe/src/main/java/com/example/appengine/firetactoe/TicTacToeServlet.java
+++ b/appengine/firebase-tictactoe/src/main/java/com/example/appengine/firetactoe/TicTacToeServlet.java
@@ -16,7 +16,6 @@
package com.example.appengine.firetactoe;
-import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.gson.Gson;
import com.googlecode.objectify.Objectify;
@@ -60,18 +59,12 @@ private String getGameUriWithGameParam(HttpServletRequest request, String gameKe
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
- final UserService userService = UserServiceFactory.getUserService();
String gameKey = request.getParameter("gameKey");
- if (userService.getCurrentUser() == null) {
- response.getWriter().println("
Please sign in.
");
- return;
- }
// 1. Create or fetch a Game object from the datastore
Objectify ofy = ObjectifyService.ofy();
Game game = null;
- String userId = userService.getCurrentUser().getUserId();
+ String userId = UserServiceFactory.getUserService().getCurrentUser().getUserId();
if (gameKey != null) {
game = ofy.load().type(Game.class).id(gameKey).now();
if (null == game) {
diff --git a/appengine/firebase-tictactoe/src/main/webapp/WEB-INF/web.xml b/appengine/firebase-tictactoe/src/main/webapp/WEB-INF/web.xml
index fcc0ee9f00a..334b6e84ca8 100644
--- a/appengine/firebase-tictactoe/src/main/webapp/WEB-INF/web.xml
+++ b/appengine/firebase-tictactoe/src/main/webapp/WEB-INF/web.xml
@@ -21,6 +21,15 @@ http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
index
+
+
+ entire-app
+ /*
+
+
+ *
+
+
TicTacToeServlet
com.example.appengine.firetactoe.TicTacToeServlet
diff --git a/appengine/firebase-tictactoe/src/test/java/com/example/appengine/firetactoe/DeleteServletTest.java b/appengine/firebase-tictactoe/src/test/java/com/example/appengine/firetactoe/DeleteServletTest.java
new file mode 100644
index 00000000000..e89cff31704
--- /dev/null
+++ b/appengine/firebase-tictactoe/src/test/java/com/example/appengine/firetactoe/DeleteServletTest.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2016 Google Inc. 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.example.appengine.firetactoe;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import com.google.api.client.http.LowLevelHttpRequest;
+import com.google.api.client.http.LowLevelHttpResponse;
+import com.google.api.client.testing.http.MockHttpTransport;
+import com.google.api.client.testing.http.MockLowLevelHttpRequest;
+import com.google.api.client.testing.http.MockLowLevelHttpResponse;
+import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig;
+import com.google.appengine.tools.development.testing.LocalServiceTestHelper;
+import com.google.appengine.tools.development.testing.LocalURLFetchServiceTestConfig;
+import com.google.appengine.tools.development.testing.LocalUserServiceTestConfig;
+import com.google.common.collect.ImmutableMap;
+import com.googlecode.objectify.Objectify;
+import com.googlecode.objectify.ObjectifyFactory;
+import com.googlecode.objectify.ObjectifyService;
+import com.googlecode.objectify.util.Closeable;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Unit tests for {@link DeleteServlet}.
+ */
+@RunWith(JUnit4.class)
+public class DeleteServletTest {
+ private static final String USER_EMAIL = "whisky@tangofoxtr.ot";
+ private static final String USER_ID = "whiskytangofoxtrot";
+ private static final String FIREBASE_DB_URL = "http://firebase.com/dburl";
+
+ private final LocalServiceTestHelper helper =
+ new LocalServiceTestHelper(
+ // Set no eventual consistency, that way queries return all results.
+ // http://g.co/cloud/appengine/docs/java/tools/localunittesting#Java_Writing_High_Replication_Datastore_tests
+ new LocalDatastoreServiceTestConfig().setDefaultHighRepJobPolicyUnappliedJobPercentage(0),
+ new LocalUserServiceTestConfig(),
+ new LocalURLFetchServiceTestConfig()
+ )
+ .setEnvEmail(USER_EMAIL)
+ .setEnvAuthDomain("gmail.com")
+ .setEnvAttributes(new HashMap(
+ ImmutableMap.of("com.google.appengine.api.users.UserService.user_id_key", USER_ID)));
+
+ @Mock private HttpServletRequest mockRequest;
+ @Mock private HttpServletResponse mockResponse;
+ protected Closeable dbSession;
+
+ private DeleteServlet servletUnderTest;
+
+ @BeforeClass
+ public static void setUpBeforeClass() {
+ // Reset the Factory so that all translators work properly.
+ ObjectifyService.setFactory(new ObjectifyFactory());
+ ObjectifyService.register(Game.class);
+ // Mock out the firebase config
+ FirebaseChannel.firebaseConfigStream = new ByteArrayInputStream(
+ String.format("databaseURL: \"%s\"", FIREBASE_DB_URL).getBytes());
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ helper.setUp();
+ dbSession = ObjectifyService.begin();
+
+ servletUnderTest = new DeleteServlet();
+
+ helper.setEnvIsLoggedIn(true);
+ // Make sure there are no firebase requests if we don't expect it
+ FirebaseChannel.getInstance().httpTransport = null;
+ }
+
+ @After
+ public void tearDown() {
+ dbSession.close();
+ helper.tearDown();
+ }
+
+ @Test
+ public void doPost_noGameKey() throws Exception {
+ try {
+ servletUnderTest.doPost(mockRequest, mockResponse);
+ fail("Should not succeed with no gameKey specified.");
+ } catch (IllegalArgumentException e) {
+ assertThat(e.getMessage()).startsWith("id 'null'");
+ }
+ }
+
+ @Test
+ public void doPost_deleteGame() throws Exception {
+ // Insert a game
+ Objectify ofy = ObjectifyService.ofy();
+ Game game = new Game(USER_ID, "my-opponent", " ", true);
+ ofy.save().entity(game).now();
+ String gameKey = game.getId();
+ when(mockRequest.getParameter("gameKey")).thenReturn(gameKey);
+
+ // Mock out the firebase response. See
+ // http://g.co/dv/api-client-library/java/google-http-java-client/unit-testing
+ MockHttpTransport mockHttpTransport = spy(new MockHttpTransport() {
+ @Override
+ public LowLevelHttpRequest buildRequest(String method, String url) throws IOException {
+ return new MockLowLevelHttpRequest() {
+ @Override
+ public LowLevelHttpResponse execute() throws IOException {
+ MockLowLevelHttpResponse response = new MockLowLevelHttpResponse();
+ response.setStatusCode(200);
+ return response;
+ }
+ };
+ }
+ });
+ FirebaseChannel.getInstance().httpTransport = mockHttpTransport;
+
+ servletUnderTest.doPost(mockRequest, mockResponse);
+
+ verify(mockHttpTransport, times(1)).buildRequest(
+ eq("DELETE"), Matchers.matches(FIREBASE_DB_URL + "/channels/[\\w-]+.json$"));
+ }
+}
diff --git a/appengine/firebase-tictactoe/src/test/java/com/example/appengine/firetactoe/MoveServletTest.java b/appengine/firebase-tictactoe/src/test/java/com/example/appengine/firetactoe/MoveServletTest.java
new file mode 100644
index 00000000000..5083c4c96c9
--- /dev/null
+++ b/appengine/firebase-tictactoe/src/test/java/com/example/appengine/firetactoe/MoveServletTest.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2016 Google Inc. 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.example.appengine.firetactoe;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import com.google.api.client.http.LowLevelHttpRequest;
+import com.google.api.client.http.LowLevelHttpResponse;
+import com.google.api.client.testing.http.MockHttpTransport;
+import com.google.api.client.testing.http.MockLowLevelHttpRequest;
+import com.google.api.client.testing.http.MockLowLevelHttpResponse;
+import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig;
+import com.google.appengine.tools.development.testing.LocalServiceTestHelper;
+import com.google.appengine.tools.development.testing.LocalURLFetchServiceTestConfig;
+import com.google.appengine.tools.development.testing.LocalUserServiceTestConfig;
+import com.google.common.collect.ImmutableMap;
+import com.googlecode.objectify.Objectify;
+import com.googlecode.objectify.ObjectifyFactory;
+import com.googlecode.objectify.ObjectifyService;
+import com.googlecode.objectify.util.Closeable;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Unit tests for {@link MoveServlet}.
+ */
+@RunWith(JUnit4.class)
+public class MoveServletTest {
+ private static final String USER_EMAIL = "whisky@tangofoxtr.ot";
+ private static final String USER_ID = "whiskytangofoxtrot";
+ private static final String FIREBASE_DB_URL = "http://firebase.com/dburl";
+
+ private final LocalServiceTestHelper helper =
+ new LocalServiceTestHelper(
+ // Set no eventual consistency, that way queries return all results.
+ // http://g.co/cloud/appengine/docs/java/tools/localunittesting#Java_Writing_High_Replication_Datastore_tests
+ new LocalDatastoreServiceTestConfig().setDefaultHighRepJobPolicyUnappliedJobPercentage(0),
+ new LocalUserServiceTestConfig(),
+ new LocalURLFetchServiceTestConfig()
+ )
+ .setEnvEmail(USER_EMAIL)
+ .setEnvAuthDomain("gmail.com")
+ .setEnvAttributes(new HashMap(
+ ImmutableMap.of("com.google.appengine.api.users.UserService.user_id_key", USER_ID)));
+
+ @Mock private HttpServletRequest mockRequest;
+ @Mock private HttpServletResponse mockResponse;
+ protected Closeable dbSession;
+
+ private MoveServlet servletUnderTest;
+
+ @BeforeClass
+ public static void setUpBeforeClass() {
+ // Reset the Factory so that all translators work properly.
+ ObjectifyService.setFactory(new ObjectifyFactory());
+ ObjectifyService.register(Game.class);
+ // Mock out the firebase config
+ FirebaseChannel.firebaseConfigStream = new ByteArrayInputStream(
+ String.format("databaseURL: \"%s\"", FIREBASE_DB_URL).getBytes());
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ helper.setUp();
+ dbSession = ObjectifyService.begin();
+
+ servletUnderTest = new MoveServlet();
+
+ helper.setEnvIsLoggedIn(true);
+ // Make sure there are no firebase requests if we don't expect it
+ FirebaseChannel.getInstance().httpTransport = null;
+ }
+
+ @After
+ public void tearDown() {
+ dbSession.close();
+ helper.tearDown();
+ }
+
+ @Test
+ public void doPost_myTurn_move() throws Exception {
+ // Insert a game
+ Objectify ofy = ObjectifyService.ofy();
+ Game game = new Game(USER_ID, "my-opponent", " ", true);
+ ofy.save().entity(game).now();
+ String gameKey = game.getId();
+
+ when(mockRequest.getParameter("gameKey")).thenReturn(gameKey);
+ when(mockRequest.getParameter("cell")).thenReturn("1");
+
+ // Mock out the firebase response. See
+ // http://g.co/dv/api-client-library/java/google-http-java-client/unit-testing
+ MockHttpTransport mockHttpTransport = spy(new MockHttpTransport() {
+ @Override
+ public LowLevelHttpRequest buildRequest(String method, String url) throws IOException {
+ return new MockLowLevelHttpRequest() {
+ @Override
+ public LowLevelHttpResponse execute() throws IOException {
+ MockLowLevelHttpResponse response = new MockLowLevelHttpResponse();
+ response.setStatusCode(200);
+ return response;
+ }
+ };
+ }
+ });
+ FirebaseChannel.getInstance().httpTransport = mockHttpTransport;
+
+ servletUnderTest.doPost(mockRequest, mockResponse);
+
+ game = ofy.load().type(Game.class).id(gameKey).safe();
+ assertThat(game.board).isEqualTo(" X ");
+
+ verify(mockHttpTransport, times(2)).buildRequest(
+ eq("PATCH"), Matchers.matches(FIREBASE_DB_URL + "/channels/[\\w-]+.json$"));
+ }
+
+ public void doPost_notMyTurn_move() throws Exception {
+ // Insert a game
+ Objectify ofy = ObjectifyService.ofy();
+ Game game = new Game(USER_ID, "my-opponent", " ", false);
+ ofy.save().entity(game).now();
+ String gameKey = game.getId();
+
+ when(mockRequest.getParameter("gameKey")).thenReturn(gameKey);
+ when(mockRequest.getParameter("cell")).thenReturn("1");
+
+ servletUnderTest.doPost(mockRequest, mockResponse);
+
+ verify(mockResponse).sendError(401);
+ }
+}
diff --git a/appengine/firebase-tictactoe/src/test/java/com/example/appengine/firetactoe/OpenedServletTest.java b/appengine/firebase-tictactoe/src/test/java/com/example/appengine/firetactoe/OpenedServletTest.java
new file mode 100644
index 00000000000..593f4287988
--- /dev/null
+++ b/appengine/firebase-tictactoe/src/test/java/com/example/appengine/firetactoe/OpenedServletTest.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2016 Google Inc. 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.example.appengine.firetactoe;
+
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import com.google.api.client.http.LowLevelHttpRequest;
+import com.google.api.client.http.LowLevelHttpResponse;
+import com.google.api.client.testing.http.MockHttpTransport;
+import com.google.api.client.testing.http.MockLowLevelHttpRequest;
+import com.google.api.client.testing.http.MockLowLevelHttpResponse;
+import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig;
+import com.google.appengine.tools.development.testing.LocalServiceTestHelper;
+import com.google.appengine.tools.development.testing.LocalURLFetchServiceTestConfig;
+import com.google.appengine.tools.development.testing.LocalUserServiceTestConfig;
+import com.google.common.collect.ImmutableMap;
+import com.googlecode.objectify.Objectify;
+import com.googlecode.objectify.ObjectifyFactory;
+import com.googlecode.objectify.ObjectifyService;
+import com.googlecode.objectify.util.Closeable;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+import org.mockito.Matchers;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.HashMap;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Unit tests for {@link OpenedServlet}.
+ */
+@RunWith(JUnit4.class)
+public class OpenedServletTest {
+ private static final String USER_EMAIL = "whisky@tangofoxtr.ot";
+ private static final String USER_ID = "whiskytangofoxtrot";
+ private static final String FIREBASE_DB_URL = "http://firebase.com/dburl";
+
+ private final LocalServiceTestHelper helper =
+ new LocalServiceTestHelper(
+ // Set no eventual consistency, that way queries return all results.
+ // http://g.co/cloud/appengine/docs/java/tools/localunittesting#Java_Writing_High_Replication_Datastore_tests
+ new LocalDatastoreServiceTestConfig().setDefaultHighRepJobPolicyUnappliedJobPercentage(0),
+ new LocalUserServiceTestConfig(),
+ new LocalURLFetchServiceTestConfig()
+ )
+ .setEnvEmail(USER_EMAIL)
+ .setEnvAuthDomain("gmail.com")
+ .setEnvAttributes(new HashMap(
+ ImmutableMap.of("com.google.appengine.api.users.UserService.user_id_key", USER_ID)));
+
+ @Mock private HttpServletRequest mockRequest;
+ @Mock private HttpServletResponse mockResponse;
+ protected Closeable dbSession;
+
+ private OpenedServlet servletUnderTest;
+
+ @BeforeClass
+ public static void setUpBeforeClass() {
+ // Reset the Factory so that all translators work properly.
+ ObjectifyService.setFactory(new ObjectifyFactory());
+ ObjectifyService.register(Game.class);
+ // Mock out the firebase config
+ FirebaseChannel.firebaseConfigStream = new ByteArrayInputStream(
+ String.format("databaseURL: \"%s\"", FIREBASE_DB_URL).getBytes());
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ helper.setUp();
+ dbSession = ObjectifyService.begin();
+
+ servletUnderTest = new OpenedServlet();
+
+ helper.setEnvIsLoggedIn(true);
+ // Make sure there are no firebase requests if we don't expect it
+ FirebaseChannel.getInstance().httpTransport = null;
+ }
+
+ @After
+ public void tearDown() {
+ dbSession.close();
+ helper.tearDown();
+ }
+
+ @Test
+ public void doPost_open() throws Exception {
+ // Insert a game
+ Objectify ofy = ObjectifyService.ofy();
+ Game game = new Game(USER_ID, "my-opponent", " ", true);
+ ofy.save().entity(game).now();
+ String gameKey = game.getId();
+
+ when(mockRequest.getParameter("gameKey")).thenReturn(gameKey);
+
+ // Mock out the firebase response. See
+ // http://g.co/dv/api-client-library/java/google-http-java-client/unit-testing
+ MockHttpTransport mockHttpTransport = spy(new MockHttpTransport() {
+ @Override
+ public LowLevelHttpRequest buildRequest(String method, String url) throws IOException {
+ return new MockLowLevelHttpRequest() {
+ @Override
+ public LowLevelHttpResponse execute() throws IOException {
+ MockLowLevelHttpResponse response = new MockLowLevelHttpResponse();
+ response.setStatusCode(200);
+ return response;
+ }
+ };
+ }
+ });
+ FirebaseChannel.getInstance().httpTransport = mockHttpTransport;
+
+ servletUnderTest.doPost(mockRequest, mockResponse);
+
+ verify(mockHttpTransport, times(2)).buildRequest(
+ eq("PATCH"), Matchers.matches(FIREBASE_DB_URL + "/channels/[\\w-]+.json$"));
+ }
+}
diff --git a/appengine/firebase-tictactoe/src/test/java/com/example/appengine/firetactoe/TicTacToeServletTest.java b/appengine/firebase-tictactoe/src/test/java/com/example/appengine/firetactoe/TicTacToeServletTest.java
index 7666e06792d..aa45cba0875 100644
--- a/appengine/firebase-tictactoe/src/test/java/com/example/appengine/firetactoe/TicTacToeServletTest.java
+++ b/appengine/firebase-tictactoe/src/test/java/com/example/appengine/firetactoe/TicTacToeServletTest.java
@@ -50,8 +50,6 @@
import java.io.ByteArrayInputStream;
import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
import java.lang.StringBuffer;
import java.util.HashMap;
import javax.servlet.RequestDispatcher;
@@ -82,7 +80,6 @@ public class TicTacToeServletTest {
@Mock private HttpServletRequest mockRequest;
@Mock private HttpServletResponse mockResponse;
- private StringWriter responseWriter;
protected Closeable dbSession;
@Mock RequestDispatcher requestDispatcher;
@@ -105,12 +102,12 @@ public void setUp() throws Exception {
dbSession = ObjectifyService.begin();
// Set up a fake HTTP response.
- responseWriter = new StringWriter();
- when(mockResponse.getWriter()).thenReturn(new PrintWriter(responseWriter));
when(mockRequest.getRequestURL()).thenReturn(new StringBuffer("https://timbre/"));
when(mockRequest.getRequestDispatcher("/WEB-INF/view/index.jsp")).thenReturn(requestDispatcher);
servletUnderTest = new TicTacToeServlet();
+
+ helper.setEnvIsLoggedIn(true);
}
@After
@@ -120,17 +117,7 @@ public void tearDown() {
}
@Test
- public void doGet_loggedOut() throws Exception {
- helper.setEnvIsLoggedIn(false);
- servletUnderTest.doGet(mockRequest, mockResponse);
-
- String response = responseWriter.toString();
- assertThat(response).contains("sign in");
- }
-
- @Test
- public void doGet_loggedIn_noGameKey() throws Exception {
- helper.setEnvIsLoggedIn(true);
+ public void doGet_noGameKey() throws Exception {
// Mock out the firebase response. See
// http://g.co/dv/api-client-library/java/google-http-java-client/unit-testing
MockHttpTransport mockHttpTransport = spy(new MockHttpTransport() {
@@ -167,8 +154,7 @@ public LowLevelHttpResponse execute() throws IOException {
}
@Test
- public void doGet_loggedIn_existingGame() throws Exception {
- helper.setEnvIsLoggedIn(true);
+ public void doGet_existingGame() throws Exception {
// Mock out the firebase response. See
// http://g.co/dv/api-client-library/java/google-http-java-client/unit-testing
MockHttpTransport mockHttpTransport = spy(new MockHttpTransport() {
@@ -213,9 +199,7 @@ public LowLevelHttpResponse execute() throws IOException {
}
@Test
- public void doGet_loggedIn_nonExistentGame() throws Exception {
- helper.setEnvIsLoggedIn(true);
-
+ public void doGet_nonExistentGame() throws Exception {
when(mockRequest.getParameter("gameKey")).thenReturn("does-not-exist");
servletUnderTest.doGet(mockRequest, mockResponse);