001package edu.pdx.cs.joy.apptbookweb;
002
003import org.junit.jupiter.api.Test;
004import org.mockito.ArgumentCaptor;
005
006import jakarta.servlet.ServletException;
007import jakarta.servlet.http.HttpServletRequest;
008import jakarta.servlet.http.HttpServletResponse;
009import java.io.IOException;
010import java.io.PrintWriter;
011import java.io.StringWriter;
012
013import static org.hamcrest.MatcherAssert.assertThat;
014import static org.hamcrest.Matchers.containsString;
015import static org.hamcrest.Matchers.equalTo;
016import static org.mockito.Mockito.*;
017
018/**
019 * A unit test for the {@link AppointmentBookServlet}.  It uses mockito to
020 * provide mock http requests and responses.
021 */
022public class AppointmentBookServletTest {
023
024  @Test
025  void initiallyServletContainsNoDictionaryEntries() throws ServletException, IOException {
026    AppointmentBookServlet servlet = new AppointmentBookServlet();
027
028    HttpServletRequest request = mock(HttpServletRequest.class);
029    HttpServletResponse response = mock(HttpServletResponse.class);
030    PrintWriter pw = mock(PrintWriter.class);
031
032    when(response.getWriter()).thenReturn(pw);
033
034    servlet.doGet(request, response);
035
036    // Nothing is written to the response's PrintWriter
037    verify(pw, never()).println(anyString());
038    verify(response).setStatus(HttpServletResponse.SC_OK);
039  }
040
041  @Test
042  void addOneWordToDictionary() throws ServletException, IOException {
043    AppointmentBookServlet servlet = new AppointmentBookServlet();
044
045    String word = "TEST WORD";
046    String definition = "TEST DEFINITION";
047
048    HttpServletRequest request = mock(HttpServletRequest.class);
049    when(request.getParameter(AppointmentBookServlet.WORD_PARAMETER)).thenReturn(word);
050    when(request.getParameter(AppointmentBookServlet.DEFINITION_PARAMETER)).thenReturn(definition);
051
052    HttpServletResponse response = mock(HttpServletResponse.class);
053
054    // Use a StringWriter to gather the text from multiple calls to println()
055    StringWriter stringWriter = new StringWriter();
056    PrintWriter pw = new PrintWriter(stringWriter, true);
057
058    when(response.getWriter()).thenReturn(pw);
059
060    servlet.doPost(request, response);
061
062    assertThat(stringWriter.toString(), containsString(Messages.definedWordAs(word, definition)));
063
064    // Use an ArgumentCaptor when you want to make multiple assertions against the value passed to the mock
065    ArgumentCaptor<Integer> statusCode = ArgumentCaptor.forClass(Integer.class);
066    verify(response).setStatus(statusCode.capture());
067
068    assertThat(statusCode.getValue(), equalTo(HttpServletResponse.SC_OK));
069
070    assertThat(servlet.getDefinition(word), equalTo(definition));
071  }
072
073}