package com.google.sps;

import com.google.appengine.tools.development.testing.LocalServiceTestHelper;
import com.google.appengine.tools.development.testing.LocalUserServiceTestConfig;
import com.google.sps.data.VolunteeringOpportunity;
import com.google.sps.servlets.OpportunitySignupFormHandlerServlet;
import com.google.sps.utilities.SpannerClient;
import com.google.sps.utilities.SpannerTasks;
import com.google.sps.utilities.SpannerTestTasks;
import com.google.sps.utilities.TestUtils;
import java.io.IOException;
import javax.servlet.ServletContextEvent;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
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.Mockito;
import org.springframework.mock.web.MockServletContext;


/** Test that tests the opportunity signup form functionality. */
@RunWith(JUnit4.class)
public final class OpportunitySignupFormHandlerTest {
  private static final String PARAMETER_OPPORTUNITY_ID = "opportunity-id";
  private static final LocalServiceTestHelper authenticationHelper =
      new LocalServiceTestHelper(new LocalUserServiceTestConfig());
  private OpportunitySignupFormHandlerServlet opportunitySignupServlet;
  private HttpServletRequest request;
  private HttpServletResponse response;

  @Before
  public void setUp() throws Exception {
    // Mock a request to trigger the SpannerClient setup to run.
    MockServletContext mockServletContext = new MockServletContext();
    new SpannerClient().contextInitialized(new ServletContextEvent(mockServletContext));
    SpannerTestTasks.setup();

    authenticationHelper.setUp();

    opportunitySignupServlet = new OpportunitySignupFormHandlerServlet();
    request = Mockito.mock(HttpServletRequest.class);
    response = Mockito.mock(HttpServletResponse.class);
  }

  @After
  public void tearDown() {
    SpannerTestTasks.cleanup();
    authenticationHelper.tearDown();
  }

  @Test
  public void testAddOpportunitySignup_LoggedIn() throws IOException {
    VolunteeringOpportunity opportunity = TestUtils.newVolunteeringOpportunity();
    SpannerTasks.insertVolunteeringOpportunity(opportunity);
    authenticationHelper
        .setEnvIsLoggedIn(true)
        .setEnvEmail("test@gmail.com")
        .setEnvAuthDomain("gmail.com");
    Mockito.when(request.getParameter(PARAMETER_OPPORTUNITY_ID))
        .thenReturn(opportunity.getOpportunityId());

    opportunitySignupServlet.doPost(request, response);

    Mockito.verify(response).sendRedirect("/event-details.html");
  }

  @Test
  public void testAddOpportunitySignup_LoggedInOpportunityIdNotSpecified() throws IOException {
    VolunteeringOpportunity opportunity = TestUtils.newVolunteeringOpportunity();
    SpannerTasks.insertVolunteeringOpportunity(opportunity);
    authenticationHelper
        .setEnvIsLoggedIn(true)
        .setEnvEmail("test@gmail.com")
        .setEnvAuthDomain("gmail.com");
    Mockito.when(request.getParameter(PARAMETER_OPPORTUNITY_ID)).thenReturn(null);

    opportunitySignupServlet.doPost(request, response);

    Mockito.verify(response)
        .sendError(HttpServletResponse.SC_BAD_REQUEST, "Opportunity ID not specified.");
  }

  @Test
  public void testAddOpportunitySignup_NotLoggedIn() throws IOException {
    VolunteeringOpportunity opportunity = TestUtils.newVolunteeringOpportunity();
    SpannerTasks.insertVolunteeringOpportunity(opportunity);
    authenticationHelper.setEnvIsLoggedIn(false);
    Mockito.when(request.getParameter(PARAMETER_OPPORTUNITY_ID))
        .thenReturn(opportunity.getOpportunityId());

    opportunitySignupServlet.doPost(request, response);

    Mockito.verify(response).sendRedirect("/index.html");
  }
}

@@ -1089,16 +1089,79 @@
 ty-id%22;%0A
+  private static final String PARAMETER_EVENT_ID = %22event-id%22;%0A
   privat
@@ -2547,32 +2547,168 @@
 pportunityId());
+%0A    String eventId = opportunity.getEventId();%0A    Mockito.when(request.getParameter(PARAMETER_EVENT_ID))%0A        .thenReturn(eventId);
 %0A%0A    opportunit
@@ -2792,16 +2792,30 @@
 edirect(
+String.format(
 %22/event-
@@ -2822,25 +2822,46 @@
 details.html
-%22
+?eventId=%25s%22, eventId)
 );%0A  %7D%0A%0A  @T
@@ -3321,16 +3321,122 @@
 n(null);
+%0A    Mockito.when(request.getParameter(PARAMETER_EVENT_ID))%0A        .thenReturn(opportunity.getEventId());
 %0A%0A    op
@@ -3601,32 +3601,753 @@
 cified.%22);%0A  %7D%0A%0A
+  @Test%0A  public void testAddOpportunitySignup_LoggedInEventIdNotSpecified() throws IOException %7B%0A    VolunteeringOpportunity opportunity = TestUtils.newVolunteeringOpportunity();%0A    SpannerTasks.insertVolunteeringOpportunity(opportunity);%0A    authenticationHelper%0A        .setEnvIsLoggedIn(true)%0A        .setEnvEmail(%22test@gmail.com%22)%0A        .setEnvAuthDomain(%22gmail.com%22);%0A    Mockito.when(request.getParameter(PARAMETER_OPPORTUNITY_ID)).thenReturn(null);%0A    Mockito.when(request.getParameter(PARAMETER_EVENT_ID))%0A        .thenReturn(null);%0A%0A    opportunitySignupServlet.doPost(request, response);%0A%0A    Mockito.verify(response)%0A        .sendError(HttpServletResponse.SC_BAD_REQUEST, %22Event ID not specified.%22);%0A  %7D%0A%0A
   @Test%0A  public
@@ -4718,24 +4718,130 @@
 tunityId());
+%0A    Mockito.when(request.getParameter(PARAMETER_EVENT_ID))%0A        .thenReturn(opportunity.getEventId());
 %0A%0A    opport

Change redirect URL in test.