All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.taketoday.test.web.servlet.MockServletWebServer Maven / Gradle / Ivy

/*
 * Original Author -> Harry Yang ([email protected]) https://taketoday.cn
 * Copyright © TODAY & 2017 - 2022 All Rights Reserved.
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see [http://www.gnu.org/licenses/]
 */

package cn.taketoday.test.web.servlet;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cn.taketoday.mock.web.MockSessionCookieConfig;
import cn.taketoday.util.ExceptionUtils;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterRegistration;
import jakarta.servlet.Servlet;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRegistration;
import jakarta.servlet.SessionCookieConfig;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;

/**
 * Base class for Mock {@code ServletWebServer} implementations.
 * {@code autoconfigure} and {@code actuator}.
 *
 * @author Phillip Webb
 * @author Andy Wilkinson
 * @since 4.0
 */
public abstract class MockServletWebServer {

  private ServletContext servletContext;

  private final Initializer[] initializers;

  private final List registeredServlets = new ArrayList<>();

  private final List registeredFilters = new ArrayList<>();

  private final int port;

  public MockServletWebServer(Initializer[] initializers, int port) {
    this.initializers = initializers;
    this.port = port;
    initialize();
  }

  private void initialize() {
    try {
      this.servletContext = mock(ServletContext.class);
      lenient().doAnswer((invocation) -> {
        RegisteredServlet registeredServlet = new RegisteredServlet(invocation.getArgument(1));
        MockServletWebServer.this.registeredServlets.add(registeredServlet);
        return registeredServlet.getRegistration();
      }).when(this.servletContext).addServlet(anyString(), any(Servlet.class));
      lenient().doAnswer((invocation) -> {
        RegisteredFilter registeredFilter = new RegisteredFilter(invocation.getArgument(1));
        MockServletWebServer.this.registeredFilters.add(registeredFilter);
        return registeredFilter.getRegistration();
      }).when(this.servletContext).addFilter(anyString(), any(Filter.class));
      final SessionCookieConfig sessionCookieConfig = new MockSessionCookieConfig();
      given(this.servletContext.getSessionCookieConfig()).willReturn(sessionCookieConfig);
      final Map initParameters = new HashMap<>();
      lenient().doAnswer((invocation) -> {
        initParameters.put(invocation.getArgument(0), invocation.getArgument(1));
        return null;
      }).when(this.servletContext).setInitParameter(anyString(), anyString());
      lenient().when(this.servletContext.getInitParameterNames())
              .thenReturn(Collections.enumeration(initParameters.keySet()));
      lenient().doAnswer((invocation) -> initParameters.get(invocation.getArgument(0))).when(this.servletContext)
              .getInitParameter(anyString());
      lenient().when(this.servletContext.getAttributeNames()).thenReturn(Collections.emptyEnumeration());
      for (Initializer initializer : this.initializers) {
        initializer.onStartup(this.servletContext);
      }
    }
    catch (ServletException ex) {
      throw ExceptionUtils.sneakyThrow(ex);
    }
  }

  public void stop() {
    this.servletContext = null;
    this.registeredServlets.clear();
  }

  public ServletContext getServletContext() {
    return this.servletContext;
  }

  public Servlet[] getServlets() {
    Servlet[] servlets = new Servlet[this.registeredServlets.size()];
    Arrays.setAll(servlets, (i) -> this.registeredServlets.get(i).getServlet());
    return servlets;
  }

  public RegisteredServlet getRegisteredServlet(int index) {
    return getRegisteredServlets().get(index);
  }

  public List getRegisteredServlets() {
    return this.registeredServlets;
  }

  public RegisteredFilter getRegisteredFilters(int index) {
    return getRegisteredFilters().get(index);
  }

  public List getRegisteredFilters() {
    return this.registeredFilters;
  }

  public int getPort() {
    return this.port;
  }

  /**
   * A registered servlet.
   */
  public static class RegisteredServlet {

    private final Servlet servlet;

    private final ServletRegistration.Dynamic registration;

    public RegisteredServlet(Servlet servlet) {
      this.servlet = servlet;
      this.registration = mock(ServletRegistration.Dynamic.class);
    }

    public ServletRegistration.Dynamic getRegistration() {
      return this.registration;
    }

    public Servlet getServlet() {
      return this.servlet;
    }

  }

  /**
   * A registered filter.
   */
  public static class RegisteredFilter {

    private final Filter filter;

    private final FilterRegistration.Dynamic registration;

    public RegisteredFilter(Filter filter) {
      this.filter = filter;
      this.registration = mock(FilterRegistration.Dynamic.class);
    }

    public FilterRegistration.Dynamic getRegistration() {
      return this.registration;
    }

    public Filter getFilter() {
      return this.filter;
    }

  }

  /**
   * Initializer (usually implement by adapting {@code Initializer}).
   */
  @FunctionalInterface
  protected interface Initializer {

    void onStartup(ServletContext context) throws ServletException;

  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy