From 6f89051b1f3d2ff2e6e4e4a574276cc06ecedbb7 Mon Sep 17 00:00:00 2001 From: Marco de Wild Date: Tue, 19 Jan 2021 15:10:18 +0100 Subject: Added explanation about failing test --- README.md | 6 +++--- domain/src/main/java/mancala/domain/Foo.java | 2 +- domain/src/test/java/mancala/domain/FooTest.java | 6 ------ 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 18f211d..ad46ee4 100644 --- a/README.md +++ b/README.md @@ -35,18 +35,18 @@ To tell the build tool which files to compile, the above structure is used. In s ## Using Gradle -You can either install Gradle on your machine and use the installation or use the Gradle wrapper files found next to this README. +You can either install Gradle on your machine and use the installation or use the Gradle wrapper files found next to this README. Replace the `./gradlew` command with `gradle` if using the globally installed Gradle or `.\gradlew.bat` if you're running the Windows batch script. ```bash # Building ./gradlew build -# Testing +# Testing (will fail with the initial code) ./gradlew test # Running (only relevant for the MVC case) ./gradlew run ``` -Replace the `./gradlew` command with `gradle` if using the globally installed Gradle or `.\gradlew.bat` if you're running the Windows batch script. +When you run the test, you will see a build failure. In `domain/src/test/java/mancala/domain.FooTest.java`, there is a failing test. If you fix the failing test, the build will succeed. ## Assignment diff --git a/domain/src/main/java/mancala/domain/Foo.java b/domain/src/main/java/mancala/domain/Foo.java index 51045fe..bcce6fa 100644 --- a/domain/src/main/java/mancala/domain/Foo.java +++ b/domain/src/main/java/mancala/domain/Foo.java @@ -6,6 +6,6 @@ package mancala.domain; public class Foo { public int theAnswerToLifeTheUniverseAndEverything() { - return 42; + return 41; } } \ No newline at end of file diff --git a/domain/src/test/java/mancala/domain/FooTest.java b/domain/src/test/java/mancala/domain/FooTest.java index 2861c43..fa784d3 100644 --- a/domain/src/test/java/mancala/domain/FooTest.java +++ b/domain/src/test/java/mancala/domain/FooTest.java @@ -20,10 +20,4 @@ public class FooTest { Foo foo = new Foo(); assertEquals(42, foo.theAnswerToLifeTheUniverseAndEverything()); } - - @Test - public void thisTestFailsUnfortunately() { - Foo foo = new Foo(); - assertEquals(3, foo.theAnswerToLifeTheUniverseAndEverything()); - } } \ No newline at end of file -- cgit v1.2.3 From a15537ec310d8fe6ba458971caa3ec31fe80412e Mon Sep 17 00:00:00 2001 From: Marco de Wild Date: Thu, 14 Jan 2021 14:32:49 +0100 Subject: Added files for interfacing with the domain --- domain/src/main/java/mancala/domain/Mancala.java | 55 ++++++++++++++++++++++ .../main/java/mancala/domain/MancalaException.java | 7 +++ .../src/main/java/mancala/domain/MancalaImpl.java | 34 +++++++++++++ 3 files changed, 96 insertions(+) create mode 100644 domain/src/main/java/mancala/domain/Mancala.java create mode 100644 domain/src/main/java/mancala/domain/MancalaException.java create mode 100644 domain/src/main/java/mancala/domain/MancalaImpl.java diff --git a/domain/src/main/java/mancala/domain/Mancala.java b/domain/src/main/java/mancala/domain/Mancala.java new file mode 100644 index 0000000..b8b8b7b --- /dev/null +++ b/domain/src/main/java/mancala/domain/Mancala.java @@ -0,0 +1,55 @@ +package mancala.domain; + +public interface Mancala { + public static final int NO_PLAYERS = 0; + public static final int PLAYER_ONE = 1; + public static final int PLAYER_TWO = 1; + public static final int BOTH_PLAYERS = 3; + + /** + * Method indicating if the first player has the next turn or not. + * If player 1 is not in turn, then player 2 is in turn. + * @param The player which you want to know the turn for. + * @return True if the first player has the next turn, false if it's the turn of the other player. + */ + boolean isPlayersTurn(int player); + + /** + * Method for playing the specified recess. Index is as specified below: + * + * 12 11 10 9 8 7 + * 13 6 + * 0 1 2 3 4 5 + * + * @param index Index of the recess to be played. + * @return 15 item long Array with the current state of the game. The 15th item indicates which player has the next turn (possible values are 1 or 2). + */ + void playPit(int index) throws MancalaException; + + /** + * Method for returning the amount of stones in de specified pit. Index is as specified below: + * + * 12 11 10 9 8 7 + * 13 6 + * 0 1 2 3 4 5 + * + * @param index Index of the pit. + * @return Amount of stone. + */ + int getStonesForPit(int index); + + /** + * Method for retrieving whether the game has ended or not. + * + * @return True is the game has ended otherwise False. + */ + boolean isEndOfGame(); + + /** + * Method for retrieving the player that has won the game. + * + * @return Integer value representing which player(s) (if any) won the game. + */ + int getWinner(); + +} \ No newline at end of file diff --git a/domain/src/main/java/mancala/domain/MancalaException.java b/domain/src/main/java/mancala/domain/MancalaException.java new file mode 100644 index 0000000..783b229 --- /dev/null +++ b/domain/src/main/java/mancala/domain/MancalaException.java @@ -0,0 +1,7 @@ +package mancala.domain; + +public class MancalaException extends Exception { + public MancalaException(String message) { + super(message); + } +} \ No newline at end of file diff --git a/domain/src/main/java/mancala/domain/MancalaImpl.java b/domain/src/main/java/mancala/domain/MancalaImpl.java new file mode 100644 index 0000000..de04c8f --- /dev/null +++ b/domain/src/main/java/mancala/domain/MancalaImpl.java @@ -0,0 +1,34 @@ +package mancala.domain; + +public class MancalaImpl implements Mancala { + public MancalaImpl() { + // Initialize the game here. + } + + @Override + public boolean isPlayersTurn(int player) { + return true; + } + + @Override + public void playPit(int index) throws MancalaException { + // Implement playing a pit. + } + + @Override + public int getStonesForPit(int index) { + // Make a sane implementation. + if((index + 1 % 7) == 0) return 0; + return 4; + } + + @Override + public boolean isEndOfGame() { + return false; + } + + @Override + public int getWinner() { + return Mancala.NO_PLAYERS; + } +} \ No newline at end of file -- cgit v1.2.3 From c980d8dfc3aa0778f51eb67e8212919fa34dcc91 Mon Sep 17 00:00:00 2001 From: Marco de Wild Date: Thu, 14 Jan 2021 14:42:57 +0100 Subject: Added a stub for the API --- api/build.gradle | 50 +++++++++++ api/src/main/java/mancala/App.java | 48 +++++++++++ api/src/main/java/mancala/api/StartMancala.java | 32 ++++++++ .../main/java/mancala/api/models/GameStatus.java | 24 ++++++ api/src/main/java/mancala/api/models/Mancala.java | 21 +++++ api/src/main/java/mancala/api/models/Pit.java | 18 ++++ api/src/main/java/mancala/api/models/Player.java | 28 +++++++ .../main/java/mancala/api/models/PlayerInput.java | 23 ++++++ .../test/java/mancala/api/StartMancalaTest.java | 96 ++++++++++++++++++++++ 9 files changed, 340 insertions(+) create mode 100644 api/build.gradle create mode 100644 api/src/main/java/mancala/App.java create mode 100644 api/src/main/java/mancala/api/StartMancala.java create mode 100644 api/src/main/java/mancala/api/models/GameStatus.java create mode 100644 api/src/main/java/mancala/api/models/Mancala.java create mode 100644 api/src/main/java/mancala/api/models/Pit.java create mode 100644 api/src/main/java/mancala/api/models/Player.java create mode 100644 api/src/main/java/mancala/api/models/PlayerInput.java create mode 100644 api/src/test/java/mancala/api/StartMancalaTest.java diff --git a/api/build.gradle b/api/build.gradle new file mode 100644 index 0000000..6dc681a --- /dev/null +++ b/api/build.gradle @@ -0,0 +1,50 @@ + +plugins { + id 'java' + // This time we're building a command-line executable application. + id 'application' +} + +repositories { + jcenter() +} + +dependencies { + + // Use the Jersey framework to make writing and testing servlets easier. + implementation 'org.glassfish.jersey.containers:jersey-container-servlet-core:+' + implementation 'org.glassfish.jersey.containers:jersey-container-jetty-http:+' + implementation 'org.glassfish.jersey.core:jersey-server:+' + implementation 'org.glassfish.jersey.inject:jersey-hk2:+' + implementation 'org.glassfish.jersey.media:jersey-media-json-jackson:+' + // Use Jakarta (Java EE) for the servlet primitives. + implementation 'jakarta.servlet:jakarta.servlet-api:+' + // Use the Jetty server. + implementation 'org.eclipse.jetty:jetty-server:+' + implementation 'org.eclipse.jetty:jetty-servlet:+' + implementation 'org.eclipse.jetty:jetty-webapp:+' + // We want to have some logging output if things go wrong, so use the simple console logger from SLF4J. + // In our simple use case, the logger gets automatically configured by simply existing. + implementation 'org.slf4j:slf4j-simple:+' + + // Reference the domain subproject. + implementation project(':domain') + + // Use JUnit Jupiter API for testing. + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.2' + // Also use the Mockito mocking framework to mock simple server functionality. + testImplementation "org.mockito:mockito-core:2.+" + + // Use JUnit Jupiter Engine for testing. + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.2' +} + +application { + // Define the main class for the application. + mainClassName = 'mancala.App' +} + +test { + // Use junit platform for unit tests + useJUnitPlatform() +} diff --git a/api/src/main/java/mancala/App.java b/api/src/main/java/mancala/App.java new file mode 100644 index 0000000..062e8e1 --- /dev/null +++ b/api/src/main/java/mancala/App.java @@ -0,0 +1,48 @@ +package mancala; + +import org.eclipse.jetty.server.Handler; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.*; +import org.eclipse.jetty.webapp.*; +import org.eclipse.jetty.servlet.ServletHandler; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.glassfish.jersey.servlet.ServletContainer; + +import mancala.api.*; + +public class App { + public static void main(String[] args) throws Exception { + Server server = startServer(8080); + ServletContextHandler context = createStatefulContext(server); + registerServlets(context); + + server.start(); + System.out.println("Started server."); + System.out.println("Listening on http://localhost:8080/"); + System.out.println("Press CTRL+C to exit."); + server.join(); + } + + private static Server startServer(int port) { + return new Server(8080); + } + + private static ServletContextHandler createStatefulContext(Server server) { + ServletContextHandler context = + new ServletContextHandler(ServletContextHandler.SESSIONS); + context.setContextPath("/"); + server.setHandler(context); + } + + private static void registerServlets(ServletContextHandler context) { + // Use the Jersey framework to translate the classes in the + // mancala.api package to server endpoints (servlets). + // For example, the StartMancala class will become an endpoint at + // http://localost:8080/start + ServletHolder serverHolder = context.addServlet(ServletContainer.class, "/mancala/api/*"); + serverHolder.setInitOrder(1); + serverHolder.setInitParameter("jersey.config.server.provider.packages", + "mancala.api"); + } +} diff --git a/api/src/main/java/mancala/api/StartMancala.java b/api/src/main/java/mancala/api/StartMancala.java new file mode 100644 index 0000000..7bd2330 --- /dev/null +++ b/api/src/main/java/mancala/api/StartMancala.java @@ -0,0 +1,32 @@ +package mancala.api; + +import java.io.IOException; +import jakarta.servlet.http.*; +import jakarta.servlet.ServletException; +import jakarta.ws.rs.*; +import jakarta.ws.rs.core.*; + +import mancala.api.models.*; +import mancala.domain.MancalaImpl; + +@Path("/start") +public class StartMancala { + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response initialize( + @Context HttpServletRequest request, + PlayerInput players) { + var mancala = new MancalaImpl(); + String namePlayer1 = players.getNameplayer1(); + String namePlayer2 = players.getNameplayer2(); + + HttpSession session = request.getSession(true); + session.setAttribute("mancala", mancala); + session.setAttribute("player1", namePlayer1); + session.setAttribute("player2", namePlayer2); + + var output = new Mancala(mancala, namePlayer1, namePlayer2); + return Response.status(200).entity(output).build(); + } +} diff --git a/api/src/main/java/mancala/api/models/GameStatus.java b/api/src/main/java/mancala/api/models/GameStatus.java new file mode 100644 index 0000000..a90269c --- /dev/null +++ b/api/src/main/java/mancala/api/models/GameStatus.java @@ -0,0 +1,24 @@ +package mancala.api.models; + +public class GameStatus { + boolean endOfGame; + public boolean getEndOfGame() { return endOfGame; } + + String winner; + public String getWinner() { return winner; } + + public GameStatus(mancala.domain.Mancala mancala, + String namePlayer1, String namePlayer2) { + this.endOfGame = mancala.isEndOfGame(); + int winner = mancala.getWinner(); + if(winner == mancala.NO_PLAYERS) { + this.winner = null; + } else if(winner == mancala.PLAYER_ONE) { + this.winner = namePlayer1; + } else if(winner == mancala.PLAYER_TWO) { + this.winner = namePlayer2; + } else { + this.winner = namePlayer1 + "and" + namePlayer2; + } + } +} \ No newline at end of file diff --git a/api/src/main/java/mancala/api/models/Mancala.java b/api/src/main/java/mancala/api/models/Mancala.java new file mode 100644 index 0000000..bb747c5 --- /dev/null +++ b/api/src/main/java/mancala/api/models/Mancala.java @@ -0,0 +1,21 @@ +package mancala.api.models; + +// This package is a collection of DTO's (data transfer objects). +// A DTO is a simple datastructure which models the +// data your web API sends back to the client. The Java +// objects will be converted to JSON objects. +public class Mancala { + public Mancala(mancala.domain.Mancala mancala, + String namePlayer1, String namePlayer2) { + players = new Player[2]; + players[0] = new Player(mancala, namePlayer1, true); + players[1] = new Player(mancala, namePlayer2, false); + gameStatus = new GameStatus(mancala, namePlayer1, namePlayer2); + } + + Player[] players; + public Player[] getPlayers() { return players; } + + GameStatus gameStatus; + public GameStatus getGameStatus() { return gameStatus; } +} \ No newline at end of file diff --git a/api/src/main/java/mancala/api/models/Pit.java b/api/src/main/java/mancala/api/models/Pit.java new file mode 100644 index 0000000..457d19b --- /dev/null +++ b/api/src/main/java/mancala/api/models/Pit.java @@ -0,0 +1,18 @@ +package mancala.api.models; + +public class Pit { + int index; + + public int getIndex() { + return index; + } + + int nrOfStones; + + public int getNrOfStones() { return nrOfStones; } + + public Pit(int index, int nrOfStones) { + this.index = index; + this.nrOfStones = nrOfStones; + } +} \ No newline at end of file diff --git a/api/src/main/java/mancala/api/models/Player.java b/api/src/main/java/mancala/api/models/Player.java new file mode 100644 index 0000000..f987e82 --- /dev/null +++ b/api/src/main/java/mancala/api/models/Player.java @@ -0,0 +1,28 @@ +package mancala.api.models; + +public class Player { + public Player(mancala.domain.Mancala mancala, + String name, boolean isFirstPlayer) { + this.name = name; + type = isFirstPlayer ? "player1" : "player2"; + hasTurn = mancala.isPlayersTurn(isFirstPlayer ? + mancala.PLAYER_ONE : mancala.PLAYER_TWO); + this.pits = new Pit[7]; + var firstHole = isFirstPlayer ? 0 : 7; + for(int i = 0; i < 7; ++i) { + this.pits[i] = new Pit(i + firstHole, mancala.getStonesForPit(i + firstHole)); + } + } + + String name; + public String getName() { return name; } + + String type; + public String getType() { return type; } + + boolean hasTurn; + public boolean getHasTurn() { return hasTurn; } + + Pit[] pits; + public Pit[] getPits() { return pits; } +} \ No newline at end of file diff --git a/api/src/main/java/mancala/api/models/PlayerInput.java b/api/src/main/java/mancala/api/models/PlayerInput.java new file mode 100644 index 0000000..8fdbd2a --- /dev/null +++ b/api/src/main/java/mancala/api/models/PlayerInput.java @@ -0,0 +1,23 @@ +package mancala.api.models; + +public class PlayerInput { + + String nameplayer1; + String nameplayer2; + + public String getNameplayer1() { + return nameplayer1; + } + + public void setNameplayer1(String nameplayer1) { + this.nameplayer1 = nameplayer1; + } + + public String getNameplayer2() { + return nameplayer2; + } + + public void setNameplayer2(String nameplayer2) { + this.nameplayer2 = nameplayer2; + } +} \ No newline at end of file diff --git a/api/src/test/java/mancala/api/StartMancalaTest.java b/api/src/test/java/mancala/api/StartMancalaTest.java new file mode 100644 index 0000000..0c4b23f --- /dev/null +++ b/api/src/test/java/mancala/api/StartMancalaTest.java @@ -0,0 +1,96 @@ +package mancala.api; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +import jakarta.servlet.http.*; +import jakarta.ws.rs.core.*; + +import mancala.api.models.*; +import mancala.domain.MancalaImpl; + +public class StartMancalaTest { + @Test + public void startingMancalaShouldBeAllowed() { + var response = startMancala("Mario", "Luigi"); + assertEquals(200, response.getStatus()); + } + + @Test + public void startingMancalaReturnsAGameWithoutAWinner() { + var response = startMancala("Mario", "Luigi"); + var entity = (Mancala)response.getEntity(); + var gameState = entity.getGameStatus(); + assertFalse(gameState.getEndOfGame()); + assertNull(gameState.getWinner()); + } + + @Test + public void startingMancalaReturnsThePlayerData() { + var response = startMancala("Mario", "Luigi"); + var entity = (Mancala)response.getEntity(); + var players = entity.getPlayers(); + assertEquals(2, players.length); + assertEquals("Mario", players[0].getName()); + assertEquals("Luigi", players[1].getName()); + } + + @Test + public void startingMancalaReturnsThePits() { + var response = startMancala("Mario", "Luigi"); + var entity = (Mancala)response.getEntity(); + var players = entity.getPlayers(); + assertEquals(7, players[0].getPits().length); + assertEquals(0, players[0].getPits()[0].getIndex()); + assertEquals(4, players[0].getPits()[0].getNrOfStones()); + assertEquals(0, players[0].getPits()[6].getNrOfStones()); + assertEquals(7, players[1].getPits().length); + assertEquals(7, players[1].getPits()[0].getIndex()); + assertEquals(4, players[1].getPits()[0].getNrOfStones()); + assertEquals(0, players[1].getPits()[6].getNrOfStones()); + } + + @Test + public void startingMancalaStartsANewSession() { + startMancala("Mario", "Luigi"); + verify(request).getSession(true); + } + + @Test + public void startingMancalaSavesTheNewGameInASession() { + startMancala("Mario", "Luigi"); + verify(session).setAttribute(eq("mancala"), any(MancalaImpl.class)); + } + + @Test + public void startingMancalaSavesTheNamesInASession() { + startMancala("Mario", "Luigi"); + verify(session).setAttribute("player1", "Mario"); + verify(session).setAttribute("player2", "Luigi"); + } + + private Response startMancala(String namePlayer1, String namePlayer2) { + var servlet = new StartMancala(); + var request = createRequestContext(); + var input = playerInput(namePlayer1, namePlayer2); + return servlet.initialize(request, input); + } + + private HttpServletRequest createRequestContext() { + request = mock(HttpServletRequest.class); + session = mock(HttpSession.class); + when(request.getSession(true)).thenReturn(session); + return request; + } + + private HttpServletRequest request; + private HttpSession session; + + private PlayerInput playerInput(String namePlayer1, String namePlayer2) { + var input = new PlayerInput(); + input.setNameplayer1(namePlayer1); + input.setNameplayer2(namePlayer2); + return input; + } +} \ No newline at end of file -- cgit v1.2.3 From 1a6eeaa4b4f060ad05a6bd297702d246aba69313 Mon Sep 17 00:00:00 2001 From: Marco de Wild Date: Fri, 15 Jan 2021 15:59:16 +0100 Subject: Modified Readme for the MVc case --- README.md | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index ad46ee4..2126ff3 100644 --- a/README.md +++ b/README.md @@ -5,11 +5,13 @@ This repository contains the files for three modules: - Model view controller: build a website for your own mancala game (or use the sloppy default implementation). - CI/CD: run your tests automatically when pushing code to Gitlab. -The skeleton project for the MVC is found on the mvc branch. On that branch, the README is updated with additional information. ## Repository structure - Main folder (this folder): contains the files relevant for the whole project. For example the Gradle-wrapper files, the .gitignore, and this readme. +- api/: contains the files for the API or service layer of your application. +- api/src/main/java/mancala/api: contains the web endpoints. +- api/src/main/java/mancala/api/models: contains the web endpoints. - domain/: contains the files that model the business domain (game rules). This is the folder you develop your OO mancala case in. ## Java project structure @@ -50,17 +52,14 @@ When you run the test, you will see a build failure. In `domain/src/test/java/ma ## Assignment -For the lectures, see [the drive](https://drive.google.com/drive/u/0/folders/1NK95KK9Ev1yZAz1vLoQSO8rEkZq-A9AC). +For the lecture, see [the drive](https://drive.google.com/drive/u/0/folders/1PvC-HS8ty3mdtSaNdR5rt5-GwL-5_LaY). -Design an object-oriented model for mancala that can handle the following scenarios: +The global goal is to make a web front-end to your mancala back-end. A stub has been made. In api/src/test you can find examples of how you can test the api endpoints. -- All small bowls start with 4 beads -- Players take turns making a move -- A player moves by selecting a small bowl on their own side, take all the beads and distribute them anti-clockwise one at a time -- When distributing, players include their own kalaha but not the opponent's -- If a move ends in the own kalaha, the player can make another move. -- If the last bead ends in an empty bowl on the own side, the player can take that bowl's bead and the direct opposite bowl's bead and put them in their kalaha. -- The game ends if all bowls of the turn player are empty -- The winner is the player with the most beads on their territory (all bowls). - -Implement the game rules test-driven. Don't be afraid to delete or modify the Foo(Test) files, as they are just an example. \ No newline at end of file +- Familiarise yourself with the repository. Get the servers running and make sure you can connect to both servers. Enter two names in the boxes. You should see a "TODO" screen. +- Show the mancala game when it is started. +- If you want to use your own implementation, reference your implemenation in the `MancalaImpl` class. +- Build the API endpoint to make a move. +- Show the winner as soon as the game is over. +- Optionally, allow for a "revenge" option in which two players can play again. +- Optionally, allow an ongoing game to continue after a page refresh. \ No newline at end of file -- cgit v1.2.3 From 7b1b8a35db9699240b6c5243cd89ef0be7fd798a Mon Sep 17 00:00:00 2001 From: Marco de Wild Date: Tue, 19 Jan 2021 15:15:14 +0100 Subject: Clarified the 'stuck' build --- README.md | 2 +- api/src/main/java/mancala/App.java | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2126ff3..2e9dd60 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ You can either install Gradle on your machine and use the installation or use th ./gradlew run ``` -When you run the test, you will see a build failure. In `domain/src/test/java/mancala/domain.FooTest.java`, there is a failing test. If you fix the failing test, the build will succeed. +If you run the program, you will notice the build "progress" is stuck on 87% or so. That means your application is running and Gradle is waiting for it to succeed. You can ignore the progress bar when running the application; it should print some lines when it's ready. ## Assignment diff --git a/api/src/main/java/mancala/App.java b/api/src/main/java/mancala/App.java index 062e8e1..3d89bb0 100644 --- a/api/src/main/java/mancala/App.java +++ b/api/src/main/java/mancala/App.java @@ -33,6 +33,7 @@ public class App { new ServletContextHandler(ServletContextHandler.SESSIONS); context.setContextPath("/"); server.setHandler(context); + return context; } private static void registerServlets(ServletContextHandler context) { -- cgit v1.2.3