/*
 * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
 * agreements. See the NOTICE file distributed with this work for additional information regarding
 * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance with the License. You may obtain a
 * copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package org.apache.geode.tools.pulse.controllers;

import static java.util.Collections.singletonList;
import static java.util.Collections.singletonMap;
import static org.apache.geode.cache.Region.SEPARATOR;
import static org.apache.geode.tools.pulse.internal.data.Cluster.CLUSTER_STAT_GARBAGE_COLLECTION;
import static org.apache.geode.tools.pulse.internal.data.Cluster.CLUSTER_STAT_MEMORY_USAGE;
import static org.apache.geode.tools.pulse.internal.data.Cluster.CLUSTER_STAT_THROUGHPUT_READS;
import static org.apache.geode.tools.pulse.internal.data.Cluster.CLUSTER_STAT_THROUGHPUT_WRITES;
import static org.assertj.core.util.Arrays.array;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.quality.Strictness.LENIENT;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
import static org.springframework.http.MediaType.parseMediaType;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import java.io.File;
import java.security.Principal;
import java.util.HashMap;
import java.util.List;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import org.apache.geode.test.junit.categories.PulseTest;
import org.apache.geode.tools.pulse.internal.data.Cluster;
import org.apache.geode.tools.pulse.internal.data.PulseConfig;
import org.apache.geode.tools.pulse.internal.data.Repository;

@Category({PulseTest.class})
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration("classpath*:WEB-INF/pulse-servlet.xml")
@ActiveProfiles({"pulse.controller.test"})
public class PulseControllerJUnitTest {
  private static final String AEQ_LISTENER = "async-event-listener";
  private static final String CLIENT_NAME = "client-1";
  private static final String CLUSTER_NAME = "mock-cluster";
  private static final String GEMFIRE_VERSION = "1.0.0";
  private static final MediaType JSON_MEDIA_TYPE = parseMediaType(APPLICATION_JSON_VALUE);
  private static final String MEMBER_ID = "member1";
  private static final String MEMBER_NAME = "localhost-server";
  private static final String PHYSICAL_HOST_NAME = "physical-host-1";
  private static final String PRINCIPAL_USER = "test-user";
  private static final String REGION_NAME = "mock-region";
  private static final String REGION_PATH = SEPARATOR + REGION_NAME;
  private static final String REGION_TYPE = "PARTITION";
  private static final Principal PRINCIPAL = () -> PRINCIPAL_USER;

  @Rule
  public TemporaryFolder tempFolder = new TemporaryFolder();

  @Rule
  public MockitoRule mockitoRule = MockitoJUnit.rule().strictness(LENIENT);

  @Autowired
  private WebApplicationContext wac;

  @Autowired
  private Repository repository;

  @Mock
  Cluster cluster;

  private final ObjectMapper mapper = new ObjectMapper();
  private MockMvc mockMvc;

  @Before
  public void setup() throws Exception {
    prepareCluster();
    when(repository.getCluster()).thenReturn(cluster);

    PulseConfig config = new PulseConfig();
    File tempQueryLog = tempFolder.newFile("query_history.log");
    config.setQueryHistoryFileName(tempQueryLog.toString());
    when(repository.getPulseConfig()).thenReturn(config);

    mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
  }

  @Test
  public void pulseUpdateForClusterDetails() throws Exception {
    mockMvc.perform(
        post("/pulseUpdate")
            .with(csrf())
            .param("pulseData", "{\"ClusterDetails\":\"{}\"}")
            .principal(PRINCIPAL)
            .accept(JSON_MEDIA_TYPE))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.ClusterDetails.userName").value(PRINCIPAL_USER))
        .andExpect(jsonPath("$.ClusterDetails.totalHeap").value(0D))
        .andExpect(jsonPath("$.ClusterDetails.clusterName").value(CLUSTER_NAME));
  }

  @Test
  public void pulseUpdateForClusterDiskThroughput() throws Exception {
    mockMvc.perform(
        post("/pulseUpdate")
            .with(csrf())
            .param("pulseData", "{\"ClusterDiskThroughput\":\"{}\"}")
            .principal(PRINCIPAL)
            .accept(JSON_MEDIA_TYPE))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.ClusterDiskThroughput.currentThroughputWrites").value(0D))
        .andExpect(jsonPath("$.ClusterDiskThroughput.throughputReads", contains(1, 2, 3)))
        .andExpect(jsonPath("$.ClusterDiskThroughput.currentThroughputReads").value(0D))
        .andExpect(jsonPath("$.ClusterDiskThroughput.throughputWrites", contains(4, 5, 6)));
  }

  @Test
  public void pulseUpdateForClusterGCPauses() throws Exception {
    mockMvc.perform(
        post("/pulseUpdate")
            .with(csrf())
            .param("pulseData", "{\"ClusterJVMPauses\":\"{}\"}")
            .principal(PRINCIPAL)
            .accept(JSON_MEDIA_TYPE))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.ClusterJVMPauses.currentGCPauses").value(0))
        .andExpect(jsonPath("$.ClusterJVMPauses.gCPausesTrend").isEmpty());
  }

  @Test
  public void pulseUpdateForClusterKeyStatistics() throws Exception {
    mockMvc.perform(
        post("/pulseUpdate")
            .with(csrf())
            .param("pulseData", "{\"ClusterKeyStatistics\":\"{}\"}")
            .principal(PRINCIPAL)
            .accept(JSON_MEDIA_TYPE))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.ClusterKeyStatistics.readPerSecTrend").hasJsonPath())
        .andExpect(jsonPath("$.ClusterKeyStatistics.queriesPerSecTrend").hasJsonPath())
        .andExpect(jsonPath("$.ClusterKeyStatistics.writePerSecTrend").hasJsonPath());
  }

  @Test
  public void pulseUpdateForClusterMember() throws Exception {
    mockMvc.perform(
        post("/pulseUpdate")
            .with(csrf())
            .param("pulseData", "{\"ClusterMembers\":\"{}\"}")
            .principal(PRINCIPAL)
            .accept(JSON_MEDIA_TYPE))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.ClusterMembers.members[0].serverGroups[0]").value("Default"))
        .andExpect(jsonPath("$.ClusterMembers.members[0].cpuUsage").value(55.77D))
        .andExpect(jsonPath("$.ClusterMembers.members[0].clients").value(1))
        .andExpect(jsonPath("$.ClusterMembers.members[0].heapUsage").value(0))
        .andExpect(jsonPath("$.ClusterMembers.members[0].name").value(MEMBER_NAME))
        .andExpect(jsonPath("$.ClusterMembers.members[0].currentHeapUsage").value(0))
        .andExpect(jsonPath("$.ClusterMembers.members[0].isManager").value(false))
        .andExpect(jsonPath("$.ClusterMembers.members[0].threads").value(0))
        .andExpect(jsonPath("$.ClusterMembers.members[0].memberId").value(MEMBER_ID))
        .andExpect(jsonPath("$.ClusterMembers.members[0].redundancyZones[0]").value("Default"));
  }

  @Test
  public void pulseUpdateForClusterMembersRGraph() throws Exception {
    mockMvc.perform(
        post("/pulseUpdate")
            .with(csrf())
            .param("pulseData", "{\"ClusterMembersRGraph\":\"{}\"}")
            .principal(PRINCIPAL)
            .accept(JSON_MEDIA_TYPE))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.ClusterMembersRGraph.memberCount").value(0))
        .andExpect(jsonPath("$.ClusterMembersRGraph.clustor.data").isEmpty())
        .andExpect(jsonPath("$.ClusterMembersRGraph.clustor.name").value(0))
        .andExpect(jsonPath("$.ClusterMembersRGraph.clustor.id").value(0))
        .andExpect(
            jsonPath("$.ClusterMembersRGraph.clustor.children[0].id").value(PHYSICAL_HOST_NAME))
        .andExpect(
            jsonPath("$.ClusterMembersRGraph.clustor.children[0].name").value(PHYSICAL_HOST_NAME))
        .andExpect(jsonPath("$.ClusterMembersRGraph.clustor.children[0].data.loadAvg").value(0D))
        .andExpect(jsonPath("$.ClusterMembersRGraph.clustor.children[0].data.sockets").value(0))
        .andExpect(jsonPath("$.ClusterMembersRGraph.clustor.children[0].data.threads").value(0))
        .andExpect(jsonPath("$.ClusterMembersRGraph.clustor.children[0].data.cpuUsage").value(0D))
        .andExpect(jsonPath("$.ClusterMembersRGraph.clustor.children[0].data.memoryUsage").value(0))
        .andExpect(
            jsonPath("$.ClusterMembersRGraph.clustor.children[0].data.hostStatus").value("Normal"))
        .andExpect(jsonPath("$.ClusterMembersRGraph.clustor.children[0].data.$type")
            .value("hostNormalNode"))
        .andExpect(
            jsonPath("$.ClusterMembersRGraph.clustor.children[0].children[0].id").value(MEMBER_ID))
        .andExpect(jsonPath("$.ClusterMembersRGraph.clustor.children[0].children[0].name")
            .value(MEMBER_NAME))
        .andExpect(
            jsonPath("$.ClusterMembersRGraph.clustor.children[0].children[0].data.gemfireVersion")
                .value(GEMFIRE_VERSION))
        .andExpect(
            jsonPath("$.ClusterMembersRGraph.clustor.children[0].children[0].data.memoryUsage")
                .value(0))
        .andExpect(jsonPath("$.ClusterMembersRGraph.clustor.children[0].children[0].data.cpuUsage")
            .value(55.77D))
        .andExpect(jsonPath("$.ClusterMembersRGraph.clustor.children[0].children[0].data.regions")
            .value(1))
        .andExpect(jsonPath("$.ClusterMembersRGraph.clustor.children[0].children[0].data.host")
            .value(PHYSICAL_HOST_NAME))
        .andExpect(
            jsonPath("$.ClusterMembersRGraph.clustor.children[0].children[0].data.port").value("-"))
        .andExpect(jsonPath("$.ClusterMembersRGraph.clustor.children[0].children[0].data.clients")
            .value(1))
        .andExpect(jsonPath("$.ClusterMembersRGraph.clustor.children[0].children[0].data.gcPauses")
            .value(0))
        .andExpect(
            jsonPath("$.ClusterMembersRGraph.clustor.children[0].children[0].data.numThreads")
                .value(0))
        .andExpect(jsonPath("$.ClusterMembersRGraph.clustor.children[0].children[0].data.nodeType")
            .value("memberNormalNode"))
        .andExpect(jsonPath("$.ClusterMembersRGraph.clustor.children[0].children[0].data.$type")
            .value("memberNormalNode"))
        .andExpect(
            jsonPath("$.ClusterMembersRGraph.clustor.children[0].children[0].data.gatewaySender")
                .value(0))
        .andExpect(
            jsonPath("$.ClusterMembersRGraph.clustor.children[0].children[0].data.gatewayReceiver")
                .value(0))
        .andExpect(
            jsonPath("$.ClusterMembersRGraph.clustor.children[0].children[0].children").isEmpty());
  }

  @Test
  public void pulseUpdateForClusterMemoryUsage() throws Exception {
    mockMvc.perform(
        post("/pulseUpdate")
            .with(csrf())
            .param("pulseData", "{\"ClusterMemoryUsage\":\"{}\"}")
            .principal(PRINCIPAL)
            .accept(JSON_MEDIA_TYPE))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.ClusterMemoryUsage.currentMemoryUsage").value(0))
        .andExpect(jsonPath("$.ClusterMemoryUsage.memoryUsageTrend", containsInAnyOrder(1, 2, 3)));
  }

  @Test
  public void pulseUpdateForClusterRegion() throws Exception {
    mockMvc.perform(
        post("/pulseUpdate")
            .with(csrf())
            .param("pulseData", "{\"ClusterRegion\":\"{}\"}")
            .principal(PRINCIPAL)
            .accept(JSON_MEDIA_TYPE))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.ClusterRegion.clusterName").value(CLUSTER_NAME))
        .andExpect(jsonPath("$.ClusterRegion.userName").value(PRINCIPAL_USER))
        .andExpect(jsonPath("$.ClusterRegion.region[0].regionPath").value(REGION_PATH))
        .andExpect(jsonPath("$.ClusterRegion.region[0].diskReadsTrend").isEmpty())
        .andExpect(jsonPath("$.ClusterRegion.region[0].memoryUsage").value("0.0000"))
        .andExpect(jsonPath("$.ClusterRegion.region[0].getsRate").value(27.99D))
        .andExpect(jsonPath("$.ClusterRegion.region[0].wanEnabled").value(false))
        .andExpect(jsonPath("$.ClusterRegion.region[0].memberCount").value(1))
        .andExpect(jsonPath("$.ClusterRegion.region[0].memberNames[0].name").value(MEMBER_NAME))
        .andExpect(jsonPath("$.ClusterRegion.region[0].memberNames[0].id").value(MEMBER_ID))
        .andExpect(jsonPath("$.ClusterRegion.region[0].emptyNodes").value(0))
        .andExpect(jsonPath("$.ClusterRegion.region[0].type").value(REGION_TYPE))
        .andExpect(jsonPath("$.ClusterRegion.region[0].isEnableOffHeapMemory").value("OFF"))
        .andExpect(jsonPath("$.ClusterRegion.region[0].putsRate").value(12.31D))
        .andExpect(jsonPath("$.ClusterRegion.region[0].totalMemory").value(0))
        .andExpect(jsonPath("$.ClusterRegion.region[0].entryCount").value(0))
        .andExpect(jsonPath("$.ClusterRegion.region[0].compressionCodec").value("NA"))
        .andExpect(jsonPath("$.ClusterRegion.region[0].name").value(REGION_NAME))
        .andExpect(jsonPath("$.ClusterRegion.region[0].systemRegionEntryCount").value(0))
        .andExpect(jsonPath("$.ClusterRegion.region[0].persistence").value("OFF"))
        .andExpect(jsonPath("$.ClusterRegion.region[0].memoryReadsTrend").isEmpty())
        .andExpect(jsonPath("$.ClusterRegion.region[0].diskWritesTrend").isEmpty())
        .andExpect(jsonPath("$.ClusterRegion.region[0].memoryWritesTrend").isEmpty())
        .andExpect(jsonPath("$.ClusterRegion.region[0].dataUsage").value(0))
        .andExpect(jsonPath("$.ClusterRegion.region[0].entrySize").value("0.0000"));
  }

  @Test
  public void pulseUpdateForClusterRegions() throws Exception {
    mockMvc.perform(
        post("/pulseUpdate")
            .with(csrf())
            .param("pulseData", "{\"ClusterRegions\":\"{}\"}")
            .principal(PRINCIPAL)
            .accept(JSON_MEDIA_TYPE))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.ClusterRegions.regions[0].regionPath").value(REGION_PATH))
        .andExpect(jsonPath("$.ClusterRegions.regions[0].diskReadsTrend").isEmpty())
        .andExpect(jsonPath("$.ClusterRegions.regions[0].memoryUsage").value("0.0000"))
        .andExpect(jsonPath("$.ClusterRegions.regions[0].getsRate").value(27.99D))
        .andExpect(jsonPath("$.ClusterRegions.regions[0].wanEnabled").value(false))
        .andExpect(jsonPath("$.ClusterRegions.regions[0].memberCount").value(1))
        .andExpect(jsonPath("$.ClusterRegions.regions[0].memberNames[0].name").value(MEMBER_NAME))
        .andExpect(jsonPath("$.ClusterRegions.regions[0].memberNames[0].id").value(MEMBER_ID))
        .andExpect(jsonPath("$.ClusterRegions.regions[0].emptyNodes").value(0))
        .andExpect(jsonPath("$.ClusterRegions.regions[0].type").value(REGION_TYPE))
        .andExpect(jsonPath("$.ClusterRegions.regions[0].isEnableOffHeapMemory").value("OFF"))
        .andExpect(jsonPath("$.ClusterRegions.regions[0].putsRate").value(12.31D))
        .andExpect(jsonPath("$.ClusterRegions.regions[0].totalMemory").value(0))
        .andExpect(jsonPath("$.ClusterRegions.regions[0].entryCount").value(0))
        .andExpect(jsonPath("$.ClusterRegions.regions[0].compressionCodec").value("NA"))
        .andExpect(jsonPath("$.ClusterRegions.regions[0].name").value(REGION_NAME))
        .andExpect(jsonPath("$.ClusterRegions.regions[0].systemRegionEntryCount").value(0))
        .andExpect(jsonPath("$.ClusterRegions.regions[0].persistence").value("OFF"))
        .andExpect(jsonPath("$.ClusterRegions.regions[0].memoryReadsTrend").isEmpty())
        .andExpect(jsonPath("$.ClusterRegions.regions[0].diskWritesTrend").isEmpty())
        .andExpect(jsonPath("$.ClusterRegions.regions[0].memoryWritesTrend").isEmpty())
        .andExpect(jsonPath("$.ClusterRegions.regions[0].dataUsage").value(0))
        .andExpect(jsonPath("$.ClusterRegions.regions[0].entrySize").value("0.0000"));
  }

  @Test
  public void pulseUpdateForClusterSelectedRegion() throws Exception {
    mockMvc.perform(
        post("/pulseUpdate")
            .with(csrf())
            .param("pulseData",
                "{\"ClusterSelectedRegion\":{\"regionFullPath\":\"" + REGION_PATH + "\"}}")
            .principal(PRINCIPAL)
            .accept(JSON_MEDIA_TYPE))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.ClusterSelectedRegion.selectedRegion.lruEvictionRate").value(0D))
        .andExpect(jsonPath("$.ClusterSelectedRegion.selectedRegion.getsRate").value(27.99D))
        .andExpect(jsonPath("$.ClusterSelectedRegion.selectedRegion.emptyNodes").value(0))
        .andExpect(jsonPath("$.ClusterSelectedRegion.selectedRegion.type").value(REGION_TYPE))
        .andExpect(
            jsonPath("$.ClusterSelectedRegion.selectedRegion.isEnableOffHeapMemory").value("OFF"))
        .andExpect(jsonPath("$.ClusterSelectedRegion.selectedRegion.path").value(REGION_PATH))
        .andExpect(
            jsonPath("$.ClusterSelectedRegion.selectedRegion.members[0].cpuUsage").value(55.77D))
        .andExpect(jsonPath("$.ClusterSelectedRegion.selectedRegion.members[0].clients").value(1))
        .andExpect(jsonPath("$.ClusterSelectedRegion.selectedRegion.members[0].heapUsage").value(0))
        .andExpect(
            jsonPath("$.ClusterSelectedRegion.selectedRegion.members[0].name").value(MEMBER_NAME))
        .andExpect(
            jsonPath("$.ClusterSelectedRegion.selectedRegion.members[0].currentHeapUsage").value(0))
        .andExpect(
            jsonPath("$.ClusterSelectedRegion.selectedRegion.members[0].isManager").value(false))
        .andExpect(jsonPath("$.ClusterSelectedRegion.selectedRegion.members[0].threads").value(0))
        .andExpect(
            jsonPath("$.ClusterSelectedRegion.selectedRegion.members[0].memberId").value(MEMBER_ID))
        .andExpect(jsonPath("$.ClusterSelectedRegion.selectedRegion.members[0].uptime")
            .value("0 Hours 0 Mins 1 Secs"))
        .andExpect(jsonPath("$.ClusterSelectedRegion.selectedRegion.memoryReadsTrend").isEmpty())
        .andExpect(jsonPath("$.ClusterSelectedRegion.selectedRegion.diskWritesTrend").isEmpty())
        .andExpect(jsonPath("$.ClusterSelectedRegion.selectedRegion.dataUsage").value(0))
        .andExpect(
            jsonPath("$.ClusterSelectedRegion.selectedRegion.regionPath").value(REGION_PATH))
        .andExpect(jsonPath("$.ClusterSelectedRegion.selectedRegion.diskReadsTrend").isEmpty())
        .andExpect(jsonPath("$.ClusterSelectedRegion.selectedRegion.memoryUsage").value("0.0000"))
        .andExpect(jsonPath("$.ClusterSelectedRegion.selectedRegion.wanEnabled").value(false))
        .andExpect(jsonPath("$.ClusterSelectedRegion.selectedRegion.memberCount").value(1))
        .andExpect(jsonPath("$.ClusterSelectedRegion.selectedRegion.putsRate").value(12.31D))
        .andExpect(jsonPath("$.ClusterSelectedRegion.selectedRegion.totalMemory").value(0))
        .andExpect(jsonPath("$.ClusterSelectedRegion.selectedRegion.entryCount").value(0))
        .andExpect(jsonPath("$.ClusterSelectedRegion.selectedRegion.compressionCodec").value("NA"))
        .andExpect(jsonPath("$.ClusterSelectedRegion.selectedRegion.name").value(REGION_NAME))
        .andExpect(
            jsonPath("$.ClusterSelectedRegion.selectedRegion.systemRegionEntryCount").value(0))
        .andExpect(jsonPath("$.ClusterSelectedRegion.selectedRegion.persistence").value("OFF"))
        .andExpect(jsonPath("$.ClusterSelectedRegion.selectedRegion.memoryWritesTrend").isEmpty())
        .andExpect(jsonPath("$.ClusterSelectedRegion.selectedRegion.entrySize").value("0.0000"));
  }

  @Test
  public void pulseUpdateForClusterSelectedRegionsMember() throws Exception {
    mockMvc.perform(
        post("/pulseUpdate")
            .with(csrf())
            .param("pulseData",
                "{\"ClusterSelectedRegionsMember\":{\"regionFullPath\":\"" + REGION_PATH + "\"}}")
            .principal(PRINCIPAL)
            .accept(JSON_MEDIA_TYPE))
        .andExpect(status().isOk())
        .andExpect(
            jsonPath("$.ClusterSelectedRegionsMember.selectedRegionsMembers.%s.diskReadsTrend",
                MEMBER_NAME).isEmpty())
        .andExpect(
            jsonPath("$.ClusterSelectedRegionsMember.selectedRegionsMembers.%s.regionFullPath",
                MEMBER_NAME).value(REGION_PATH))
        .andExpect(jsonPath("$.ClusterSelectedRegionsMember.selectedRegionsMembers.%s.entryCount",
            MEMBER_NAME).value(0))
        .andExpect(jsonPath("$.ClusterSelectedRegionsMember.selectedRegionsMembers.%s.accessor",
            MEMBER_NAME).value("True"))
        .andExpect(jsonPath("$.ClusterSelectedRegionsMember.selectedRegionsMembers.%s.memberName",
            MEMBER_NAME).value(MEMBER_NAME))
        .andExpect(
            jsonPath("$.ClusterSelectedRegionsMember.selectedRegionsMembers.%s.memoryReadsTrend",
                MEMBER_NAME).isEmpty())
        .andExpect(
            jsonPath("$.ClusterSelectedRegionsMember.selectedRegionsMembers.%s.diskWritesTrend",
                MEMBER_NAME).isEmpty())
        .andExpect(
            jsonPath("$.ClusterSelectedRegionsMember.selectedRegionsMembers.%s.memoryWritesTrend",
                MEMBER_NAME).isEmpty())
        .andExpect(jsonPath("$.ClusterSelectedRegionsMember.selectedRegionsMembers.%s.entrySize",
            MEMBER_NAME).value(0))
        .andExpect(jsonPath("$.ClusterSelectedRegionsMember.clusterName").value(CLUSTER_NAME))
        .andExpect(jsonPath("$.ClusterSelectedRegionsMember.userName").value(PRINCIPAL_USER));
  }

  @Test
  public void pulseUpdateForClusterWANInfo() throws Exception {
    mockMvc.perform(
        post("/pulseUpdate")
            .with(csrf())
            .param("pulseData", "{\"ClusterWANInfo\":\"{}\"}")
            .principal(PRINCIPAL)
            .accept(JSON_MEDIA_TYPE))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.ClusterWANInfo.connectedClusters").isEmpty());
  }

  @Test
  public void pulseUpdateForMemberAsynchEventQueues() throws Exception {
    mockMvc.perform(
        post("/pulseUpdate")
            .with(csrf())
            .param("pulseData",
                "{\"MemberAsynchEventQueues\":{\"memberName\":\"" + MEMBER_NAME + "\"}}")
            .principal(PRINCIPAL)
            .accept(JSON_MEDIA_TYPE))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.MemberAsynchEventQueues.isAsyncEventQueuesPresent").value(true))
        .andExpect(
            jsonPath("$.MemberAsynchEventQueues.asyncEventQueues[0].batchTimeInterval").value(0))
        .andExpect(jsonPath("$.MemberAsynchEventQueues.asyncEventQueues[0].batchConflationEnabled")
            .value(false))
        .andExpect(jsonPath("$.MemberAsynchEventQueues.asyncEventQueues[0].queueSize").value(0))
        .andExpect(
            jsonPath("$.MemberAsynchEventQueues.asyncEventQueues[0].senderType").value(false))
        .andExpect(jsonPath("$.MemberAsynchEventQueues.asyncEventQueues[0].asyncEventListener")
            .value(AEQ_LISTENER))
        .andExpect(jsonPath("$.MemberAsynchEventQueues.asyncEventQueues[0].batchSize").value(0))
        .andExpect(jsonPath("$.MemberAsynchEventQueues.asyncEventQueues[0].primary").value(false));
  }

  @Test
  public void pulseUpdateForMemberClients() throws Exception {
    mockMvc.perform(
        post("/pulseUpdate")
            .with(csrf())
            .param("pulseData", "{\"MemberClients\":{\"memberName\":\"" + MEMBER_NAME + "\"}}")
            .principal(PRINCIPAL)
            .accept(JSON_MEDIA_TYPE))
        .andExpect(status().isOk()).andExpect(jsonPath("$.MemberClients.name").value(MEMBER_NAME))
        .andExpect(jsonPath("$.MemberClients.memberClients[0].puts").value(0))
        .andExpect(jsonPath("$.MemberClients.memberClients[0].cpuUsage").value("0.0000"))
        .andExpect(jsonPath("$.MemberClients.memberClients[0].clientId").value("100"))
        .andExpect(jsonPath("$.MemberClients.memberClients[0].queueSize").value(0))
        .andExpect(jsonPath("$.MemberClients.memberClients[0].clientCQCount").value(0))
        .andExpect(jsonPath("$.MemberClients.memberClients[0].name").value(CLIENT_NAME))
        .andExpect(jsonPath("$.MemberClients.memberClients[0].isConnected").value("No"))
        .andExpect(jsonPath("$.MemberClients.memberClients[0].threads").value(0))
        .andExpect(jsonPath("$.MemberClients.memberClients[0].isSubscriptionEnabled").value("No"))
        .andExpect(jsonPath("$.MemberClients.memberClients[0].gets").value(0))
        .andExpect(
            jsonPath("$.MemberClients.memberClients[0].uptime").value("0 Hours 0 Mins 1 Secs"));
  }

  @Test
  public void pulseUpdateForMemberDetails() throws Exception {
    mockMvc.perform(
        post("/pulseUpdate")
            .with(csrf())
            .param("pulseData", "{\"MemberDetails\":{\"memberName\":\"" + MEMBER_NAME + "\"}}")
            .principal(PRINCIPAL)
            .accept(JSON_MEDIA_TYPE))
        .andExpect(status().isOk()).andExpect(jsonPath("$.MemberDetails.name").value(MEMBER_NAME))
        .andExpect(jsonPath("$.MemberDetails.offHeapUsedSize").value(0))
        .andExpect(jsonPath("$.MemberDetails.diskStorageUsed").value(0D))
        .andExpect(jsonPath("$.MemberDetails.regionsCount").value(1))
        .andExpect(jsonPath("$.MemberDetails.clusterName").value(CLUSTER_NAME))
        .andExpect(jsonPath("$.MemberDetails.name").value(MEMBER_NAME))
        .andExpect(jsonPath("$.MemberDetails.threads").value(0))
        .andExpect(jsonPath("$.MemberDetails.clusterId").isNotEmpty())
        .andExpect(jsonPath("$.MemberDetails.numClients").value(1))
        .andExpect(jsonPath("$.MemberDetails.userName").value(PRINCIPAL_USER))
        .andExpect(jsonPath("$.MemberDetails.offHeapFreeSize").value(0))
        .andExpect(jsonPath("$.MemberDetails.memberId").value(MEMBER_ID))
        .andExpect(jsonPath("$.MemberDetails.status").value("Normal"));
  }

  @Test
  public void pulseUpdateForMemberDiskThroughput() throws Exception {
    mockMvc.perform(
        post("/pulseUpdate")
            .with(csrf())
            .param("pulseData",
                "{\"MemberDiskThroughput\":{\"memberName\":\"" + MEMBER_NAME + "\"}}")
            .principal(PRINCIPAL)
            .accept(JSON_MEDIA_TYPE))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.MemberDiskThroughput.throughputWritesTrend").isEmpty())
        .andExpect(jsonPath("$.MemberDiskThroughput.throughputReadsTrend").isEmpty())
        .andExpect(jsonPath("$.MemberDiskThroughput.throughputWrites").value(0D))
        .andExpect(jsonPath("$.MemberDiskThroughput.throughputReads").value(0D));
  }

  @Test
  public void pulseUpdateForMemberGatewayHub() throws Exception {
    mockMvc.perform(
        post("/pulseUpdate")
            .with(csrf())
            .param("pulseData",
                "{\"MemberGatewayHub\":{\"memberName\":\"" + MEMBER_NAME + "\"}}")
            .principal(PRINCIPAL)
            .accept(JSON_MEDIA_TYPE))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.MemberGatewayHub.isGatewayReceiver").value(false))
        .andExpect(jsonPath("$.MemberGatewayHub.asyncEventQueues[0].batchTimeInterval").value(0))
        .andExpect(
            jsonPath("$.MemberGatewayHub.asyncEventQueues[0].batchConflationEnabled").value(false))
        .andExpect(jsonPath("$.MemberGatewayHub.asyncEventQueues[0].queueSize").value(0))
        .andExpect(jsonPath("$.MemberGatewayHub.asyncEventQueues[0].senderType").value(false))
        .andExpect(jsonPath("$.MemberGatewayHub.asyncEventQueues[0].asyncEventListener")
            .value(AEQ_LISTENER))
        .andExpect(jsonPath("$.MemberGatewayHub.asyncEventQueues[0].batchSize").value(0))
        .andExpect(jsonPath("$.MemberGatewayHub.asyncEventQueues[0].primary").value(false))
        .andExpect(jsonPath("$.MemberGatewayHub.isGatewaySender").value(false))
        .andExpect(jsonPath("$.MemberGatewayHub.regionsInvolved").isEmpty())
        .andExpect(jsonPath("$.MemberGatewayHub.gatewaySenders").isEmpty());
  }

  @Test
  public void pulseUpdateForMemberGCPauses() throws Exception {
    mockMvc.perform(
        post("/pulseUpdate")
            .with(csrf())
            .param("pulseData",
                "{\"MemberGCPauses\":{\"memberName\":\"" + MEMBER_NAME + "\"}}")
            .principal(PRINCIPAL)
            .accept(JSON_MEDIA_TYPE))
        .andExpect(status().isOk()).andExpect(jsonPath("$.MemberGCPauses.gcPausesCount").value(0))
        .andExpect(jsonPath("$.MemberGCPauses.gcPausesTrend").isEmpty());
  }

  @Test
  public void pulseUpdateForMemberHeapUsage() throws Exception {
    mockMvc.perform(
        post("/pulseUpdate")
            .with(csrf())
            .param("pulseData",
                "{\"MemberHeapUsage\":{\"memberName\":\"" + MEMBER_NAME + "\"}}")
            .principal(PRINCIPAL)
            .accept(JSON_MEDIA_TYPE))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.MemberHeapUsage.heapUsageTrend").isEmpty())
        .andExpect(jsonPath("$.MemberHeapUsage.currentHeapUsage").value(0));
  }

  @Test
  public void pulseUpdateForMemberKeyStatistics() throws Exception {
    mockMvc.perform(
        post("/pulseUpdate")
            .with(csrf())
            .param("pulseData",
                "{\"MemberKeyStatistics\":{\"memberName\":\"" + MEMBER_NAME + "\"}}")
            .principal(PRINCIPAL)
            .accept(JSON_MEDIA_TYPE))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.MemberKeyStatistics.readPerSecTrend").isEmpty())
        .andExpect(jsonPath("$.MemberKeyStatistics.cpuUsageTrend").isEmpty())
        .andExpect(jsonPath("$.MemberKeyStatistics.memoryUsageTrend").isEmpty())
        .andExpect(jsonPath("$.MemberKeyStatistics.writePerSecTrend").isEmpty());
  }

  @Test
  public void pulseUpdateForMemberRegions() throws Exception {
    mockMvc.perform(
        post("/pulseUpdate")
            .with(csrf())
            .param("pulseData", "{\"MemberRegions\":{\"memberName\":\"" + MEMBER_NAME + "\"}}")
            .principal(PRINCIPAL)
            .accept(JSON_MEDIA_TYPE))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.MemberRegions.name").value(MEMBER_NAME))
        .andExpect(jsonPath("$.MemberRegions.memberRegions[0].fullPath").value(REGION_PATH))
        .andExpect(jsonPath("$.MemberRegions.memberRegions[0].entryCount").value(0))
