package org.camunda.bpm.cockpit.plugin.base.tenantcheck;

import static org.fest.assertions.Assertions.assertThat;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.camunda.bpm.cockpit.impl.plugin.base.dto.ProcessDefinitionDto;
import org.camunda.bpm.cockpit.impl.plugin.base.dto.query.ProcessDefinitionQueryDto;
import org.camunda.bpm.cockpit.impl.plugin.base.sub.resources.ProcessDefinitionResource;
import org.camunda.bpm.cockpit.plugin.test.AbstractCockpitPluginTest;
import org.camunda.bpm.engine.IdentityService;
import org.camunda.bpm.engine.ProcessEngine;
import org.camunda.bpm.engine.ProcessEngineConfiguration;
import org.camunda.bpm.engine.RuntimeService;
import org.camunda.bpm.engine.authorization.Groups;
import org.camunda.bpm.engine.runtime.ProcessInstance;
import org.junit.Before;
import org.junit.Test;

public class ProcessDefinitionResourceTenantCheckTest extends AbstractCockpitPluginTest {

  protected static final String TENANT_ONE = "tenant1";
  protected static final String TENANT_TWO = "tenant2";

  private ProcessEngine processEngine;
  private ProcessEngineConfiguration processEngineConfiguration;
  private RuntimeService runtimeService;
  private IdentityService identityService;

  private ProcessDefinitionResource resource;
  private ProcessDefinitionQueryDto queryParameter;

  @Before
  public void init() throws Exception {

    processEngine = getProcessEngine();
    processEngineConfiguration = processEngine.getProcessEngineConfiguration();

    runtimeService = processEngine.getRuntimeService();
    identityService = processEngine.getIdentityService();

    deploy("processes/multi-tenancy-call-activity.bpmn");
    deployForTenant(TENANT_ONE, "processes/user-task-process.bpmn");
    deployForTenant(TENANT_TWO, "processes/user-task-process.bpmn");

    ProcessInstance processInstance = runtimeService.createProcessInstanceByKey("multiTenancyCallActivity").execute();

    resource = new ProcessDefinitionResource(getProcessEngine().getName(), processInstance.getProcessDefinitionId());

    queryParameter = new ProcessDefinitionQueryDto();
  }

  @Test
  public void calledProcessDefinitionByParentProcessDefinitionIdNoAuthenticatedTenant() {

    identityService.setAuthentication("user", null, null);

    List<ProcessDefinitionDto> result = resource.queryCalledProcessDefinitions(queryParameter);
    assertThat(result).isEmpty();
  }

  @Test
  public void calledProcessDefinitionByParentProcessDefinitionIdWithAuthenticatedTenant() {

    identityService.setAuthentication("user", null, Arrays.asList(TENANT_ONE));

    List<ProcessDefinitionDto> result = resource.queryCalledProcessDefinitions(queryParameter);
    assertThat(result).isNotEmpty();
    assertThat(result).hasSize(1);

    ProcessDefinitionDto dto = result.get(0);
    String calledFrom = dto.getCalledFromActivityIds().get(0);
    assertThat(calledFrom).isEqualTo("CallActivity_Tenant1");
  }

  @Test
  public void calledProcessDefinitionByParentProcessDefinitionIdDisabledTenantCheck() {

    processEngineConfiguration.setTenantCheckEnabled(false);
    identityService.setAuthentication("user", null, null);

    List<ProcessDefinitionDto> result = resource.queryCalledProcessDefinitions(queryParameter);
    assertThat(result).isNotEmpty();
    assertThat(result).hasSize(2);

    ProcessDefinitionDto dto = result.get(0);
    String calledFrom = dto.getCalledFromActivityIds().get(0);
    assertThat(calledFrom).isEqualTo("CallActivity_Tenant1");

    dto = result.get(1);
    calledFrom = dto.getCalledFromActivityIds().get(0);
    assertThat(calledFrom).isEqualTo("CallActivity_Tenant2");
  }

  @Test
  public void calledProcessDefinitionByParentProcessDefinitionIdWithCamundaAdmin() {

    identityService.setAuthentication("user", Collections.singletonList(Groups.CAMUNDA_ADMIN), null);

    List<ProcessDefinitionDto> result = resource.queryCalledProcessDefinitions(queryParameter);
    assertThat(result).isNotEmpty();
    assertThat(result).hasSize(2);

    ProcessDefinitionDto dto = result.get(0);
    String calledFrom = dto.getCalledFromActivityIds().get(0);
    assertThat(calledFrom).isEqualTo("CallActivity_Tenant1");

    dto = result.get(1);
    calledFrom = dto.getCalledFromActivityIds().get(0);
    assertThat(calledFrom).isEqualTo("CallActivity_Tenant2");
  }

}

@@ -105,24 +105,52 @@
 ssertThat;%0A%0A
+import java.util.ArrayList;%0A
 import java.
@@ -2813,149 +2813,65 @@
     
-ProcessDefinitionDto dto = result.get(0);%0A    String calledFrom = dto.getCalledFromActivityIds().get(0);%0A    assertThat(calledFrom).isEqualTo
+assertThat(getCalledFromActivityIds(result)).containsOnly
 (%22Ca
@@ -3292,294 +3292,86 @@
     
-ProcessDefinitionDto dto = result.get(0);%0A    String calledFrom = dto.getCalledFromActivityIds().get(0);%0A    assertThat(calledFrom).isEqualTo(%22CallActivity_Tenant1%22);%0A%0A    dto = result.get(1);%0A    calledFrom = dto.getCalledFromActivityIds().get(0);%0A    assertThat(calledFrom).isEqualTo(
+assertThat(getCalledFromActivityIds(result)).contains(%22CallActivity_Tenant1%22, 
 %22Cal
@@ -3770,221 +3770,386 @@
     
-ProcessDefinitionDto dto = result.get(0);%0A    String calledFrom = dto.getCalledFromActivityIds().get(0);%0A    assertThat(calledFrom).isEqualTo(%22CallActivity_Tenant1%22);%0A%0A    dto = result.get(1);%0A    calledFrom = dto
+assertThat(getCalledFromActivityIds(result)).contains(%22CallActivity_Tenant1%22, %22CallActivity_Tenant2%22);%0A  %7D%0A%0A  protected List%3CString%3E getCalledFromActivityIds(List%3CProcessDefinitionDto%3E processDefinitions) %7B%0A    List%3CString%3E activityIds = new ArrayList%3CString%3E();%0A%0A    for (ProcessDefinitionDto processDefinition : processDefinitions) %7B%0A      activityIds.addAll(processDefinition
 .get
@@ -4175,82 +4175,46 @@
 ds()
-.get(0
 );%0A    
-assertThat(calledFrom).isEqualTo(%22CallActivity_Tenant2%22)
+%7D%0A%0A    return activityIds
 ;%0A  %7D%0A%0A
+%0A
 %7D%0A

fix result ordering in process definition tenant check test