package com.google.sticknotesbackend.servlets;

import static com.google.common.truth.Truth.assertThat;
import static com.googlecode.objectify.ObjectifyService.ofy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.sticknotesbackend.models.Note;
import com.google.sticknotesbackend.models.Whiteboard;
import com.googlecode.objectify.Ref;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import javax.servlet.ServletException;
import org.junit.Before;
import org.junit.Test;

/**
 * Unit tests for NoteServlet
 */
public class NoteServletTest extends NotesboardTestBase {
  private NoteServlet noteServlet;

  @Before
  public void setUp() throws Exception {
    // parent logic of setting up objectify
    super.setUp();
    // Set up a fake HTTP request
    when(mockRequest.getContentType()).thenReturn("application/json");
    // Set up a fake HTTP response
    responseWriter = new StringWriter();
    when(mockResponse.getWriter()).thenReturn(new PrintWriter(responseWriter));
    noteServlet = new NoteServlet();
  }

  @Test
  public void testNoteCreateSuccessWithValidPayload() throws IOException, ServletException {
    // create a mock board
    Whiteboard board = getMockBoard();
    // save the board and get autogenerated board id
    board.id = ofy().save().entity(board).now().getId();
    // generate a payload
    JsonObject jsonObject = new JsonObject();
    jsonObject.addProperty("boardId", board.id);
    jsonObject.addProperty("color", "#000000");
    jsonObject.addProperty("content", "dummy content");
    jsonObject.addProperty("x", 1);
    jsonObject.addProperty("y", 2);
    // prepare mocked request
    when(mockRequest.getReader()).thenReturn(new BufferedReader(new StringReader(jsonObject.toString())));
    // do request
    noteServlet.doPost(mockRequest, mockResponse);
    // check that note with the id from response is saved in the datastore
    // read Json from response to a Note object
    // check that response has id
    assertThat(responseWriter.toString()).contains("id");
    // if id is there, check if the note with this id is really saved
    Note note = new Gson().fromJson(responseWriter.toString(), Note.class);
    // load note with the given id from datastore
    Note savedNote = ofy().load().type(Note.class).id(note.id).now();
    assertThat(savedNote).isNotNull();
  }

  @Test
  public void testNoteDeleteSuccessWithValidBoardId() throws IOException, ServletException {
    // create mocked note and save it
    Note note = getMockNote();
    // save note
    note.id = ofy().save().entity(note).now().getId();
    // create mocked board and save it
    Whiteboard board = getMockBoard();
    board.notes.add(Ref.create(note));
    board.id = ofy().save().entity(board).now().getId();
    // save id of the board in the note
    note.boardId = board.id;
    ofy().save().entity(note).now().getId();

    // add note id to the request
    when(mockRequest.getParameter("id")).thenReturn(Long.toString(note.id));
    // do delete
    noteServlet.doDelete(mockRequest, mockResponse);
    // verify that no note with this id is in the datastore
    Note deletedNote = ofy().load().type(Note.class).id(note.id).now();
    assertThat(deletedNote).isNull();
    verify(mockResponse).setStatus(NO_CONTENT);
  }
}

@@ -241,16 +241,84 @@
 .when;%0A%0A
+import com.google.appengine.repackaged.com.google.gson.JsonElement;%0A
 import c
@@ -373,16 +373,51 @@
 Object;%0A
+import com.google.gson.JsonParser;%0A
 import c
@@ -2272,66 +2272,8 @@
  id%0A
-    assertThat(responseWriter.toString()).contains(%22id%22);%0A
     
@@ -2346,39 +2346,48 @@
     
-Note note
+JsonObject body
  = new 
-Gson().fromJson
+JsonParser().parse
 (res
@@ -2412,20 +2412,67 @@
 ng()
-, Note.class
+).getAsJsonObject();%0A    assertThat(body.has(%22id%22)).isTrue(
 );%0A 
@@ -2566,39 +2566,76 @@
 (Note.class).id(
-note.id
+Long.parseLong(body.get(%22id%22).getAsString())
 ).now();%0A    ass

Fix test