package uk.ac.ebi.quickgo.rest.search.filter;

import java.util.Collections;
import java.util.Optional;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.collection.IsIterableContainingInOrder.contains;
import static uk.ac.ebi.quickgo.rest.search.filter.FieldExecutionConfig.ExecutionType.*;
import static uk.ac.ebi.quickgo.rest.search.filter.FilterUtil.createExecutionConfig;

/**
 * Tests the behaviour of the {@link ExternalFilterExecutionConfig} class.
 */
public class ExternalFilterExecutionConfigTest {
    @Rule
    public ExpectedException thrown = ExpectedException.none();

    private ExternalFilterExecutionConfig config;


    @Before
    public void setUp() throws Exception {
        config = new ExternalFilterExecutionConfig();
    }

    @Test
    public void newExternalFilterConfigHasNoFields() {
        assertThat(config.getFields(), hasSize(0));
    }

    @Test
    public void newExternalFilterConfigReturnsEmptyOptionalWhenCallingGetField() {
        Optional<FieldExecutionConfig> fieldConfigOpt = config.getField("field");

        assertThat(fieldConfigOpt.isPresent(), is(false));
    }

    @Test
    public void settingFieldsToNullReturnsAnEmptyListWhenCallingGetFields() {
        config.setFields(null);

        assertThat(config.getFields(), hasSize(0));
    }

    @Test
    public void settingFieldsToNullReturnsEmptyOptionalWhenCallingGetField(){
        config.setFields(null);

        Optional<FieldExecutionConfig> fieldConfigOpt = config.getField("field");

        assertThat(fieldConfigOpt.isPresent(), is(false));
    }

    @Test
    public void settingFieldsWithOneFieldExecutionConfigReturnsAListWithThatField() {
        String name = "name";
        FieldExecutionConfig.ExecutionType type = SIMPLE;

        FieldExecutionConfig field = createExecutionConfig(name, type);

        config.setFields(Collections.singletonList(field));

        assertThat(config.getFields(), contains(field));
    }

    @Test
    public void gettingFieldWithRecognizedFieldNameReturnsAnPopulatedOptional() {
        String name = "aspect";
        FieldExecutionConfig.ExecutionType type = JOIN;

        FieldExecutionConfig field = createExecutionConfig(name, type);

        config.setFields(Collections.singletonList(field));

        assertThat(config.getField(name), is(Optional.of(field)));
    }

    @Test
    public void gettingFieldWithUnrecognizedFieldNameReturnsAnEmptyOptional() {
        String name = "aspect";
        FieldExecutionConfig.ExecutionType type = JOIN;

        FieldExecutionConfig field = createExecutionConfig(name, type);

        config.setFields(Collections.singletonList(field));

        assertThat(config.getField("fake"), is(Optional.empty()));
    }
}
@@ -40,16 +40,41 @@
 ilter;%0A%0A
+import java.util.Arrays;%0A
 import j
@@ -2973,10 +2973,710 @@
 );%0A    %7D
+%0A%0A    @Test%0A    public void getsFirstOfTwoFieldsWithTheSameName() %7B%0A        String name = %22field%22;%0A        FieldExecutionConfig.ExecutionType type1 = JOIN;%0A        FieldExecutionConfig.ExecutionType type2 = SIMPLE;%0A%0A        FieldExecutionConfig field1 = createExecutionConfig(name, type1);%0A        FieldExecutionConfig field2 = createExecutionConfig(name, type2);%0A%0A        config.setFields(Arrays.asList(field1, field2));%0A%0A        Optional%3CFieldExecutionConfig%3E retrievedFieldOpt = config.getField(name);%0A%0A        FieldExecutionConfig retrievedField = retrievedFieldOpt.get();%0A%0A        assertThat(retrievedField.getName(), is(name));%0A        assertThat(retrievedField.getExecution(), is(JOIN));%0A    %7D
 %0A%7D

Add test to show that the ExternalFilterExecutionConfig only retrieves the first field if there is more than one field with the same name.