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

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;

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

    private JoinQuery query;

    private String joinFromAttribute = "id";
    private String joinFromTable = "annotation";
    private String joinToAttribute = "id";
    private String joinToTable = "ontology";

    private QuickGOQuery filterQuery = QuickGOQuery.createAllQuery();

    @Test
    public void throwsExceptionWhenJoinFromTableIsNull() throws Exception {
        joinFromTable = null;

        assertNullOrEmpty("Join From Table cannot be null or empty");

        query = new JoinQuery(joinFromTable, joinFromAttribute, joinToTable, joinToAttribute);
    }

    @Test
    public void throwsExceptionWhenJoinFromTableIsEmpty() throws Exception {
        joinFromTable = "";

        assertNullOrEmpty("Join From Table cannot be null or empty");

        query = new JoinQuery(joinFromTable, joinFromAttribute, joinToTable, joinToAttribute);
    }

    @Test
    public void throwsExceptionWhenJoinFromAttributeIsNull() throws Exception {
        joinFromAttribute = null;

        assertNullOrEmpty("Join From Attribute cannot be null or empty");

        query = new JoinQuery(joinFromTable, joinFromAttribute, joinToTable, joinToAttribute);
    }

    @Test
    public void throwsExceptionWhenJoinFromAttributeIsEmpty() throws Exception {
        joinFromAttribute = "";

        assertNullOrEmpty("Join From Attribute cannot be null or empty");

        query = new JoinQuery(joinFromTable, joinFromAttribute, joinToTable, joinToAttribute);
    }

    @Test
    public void throwsExceptionWhenJoinToTableIsNull() throws Exception {
        joinToTable = null;

        assertNullOrEmpty("Join To Table cannot be null or empty");

        query = new JoinQuery(joinFromTable, joinFromAttribute, joinToTable, joinToAttribute);
    }

    @Test
    public void throwsExceptionWhenJoinToTableIsEmpty() throws Exception {
        joinToTable = "";

        assertNullOrEmpty("Join To Table cannot be null or empty");

        query = new JoinQuery(joinFromTable, joinFromAttribute, joinToTable, joinToAttribute);
    }

    @Test
    public void throwsExceptionWhenJoinToAttributeIsNull() throws Exception {
        joinToAttribute = null;

        assertNullOrEmpty("Join To Attribute cannot be null or empty");

        query = new JoinQuery(joinFromTable, joinFromAttribute, joinToTable, joinToAttribute);
    }

    @Test
    public void throwsExceptionWhenJoinToAttributeIsEmpty() throws Exception {
        joinToAttribute = "";

        assertNullOrEmpty("Join To Attribute cannot be null or empty");

        query = new JoinQuery(joinFromTable, joinFromAttribute, joinToTable, joinToAttribute);
    }

    @Test
    public void createsJoinQueryWithJoinParametersInitializedCorrectly() {
        query = new JoinQuery(joinFromTable, joinFromAttribute, joinToTable, joinToAttribute);

        assertThat(query.getJoinFromTable(), is(joinFromTable));
        assertThat(query.getJoinFromAttribute(), is(joinFromAttribute));
        assertThat(query.getJoinToTable(), is(joinToTable));
        assertThat(query.getJoinToAttribute(), is(joinToAttribute));
    }

    @Test
    public void throwsExceptionWhenQueryIsNull() throws Exception {
        filterQuery = null;

        assertNullOrEmpty("Filter query cannot be null");

        query = new JoinQuery(joinFromTable, joinFromAttribute, joinToTable, joinToAttribute, filterQuery);
    }

    @Test
    public void createsJoinQueryWithJoinParametersAndFilterQueryInitializedCorrectly() {
        query = new JoinQuery(joinFromTable, joinFromAttribute, joinToTable, joinToAttribute, filterQuery);

        assertThat(query.getJoinFromTable(), is(joinFromTable));
        assertThat(query.getJoinFromAttribute(), is(joinFromAttribute));
        assertThat(query.getJoinToTable(), is(joinToTable));
        assertThat(query.getJoinToAttribute(), is(joinToAttribute));
        assertThat(query.getQuery(), is(filterQuery));
    }

    private void assertNullOrEmpty(String errorMsg) {
        thrown.expect(IllegalArgumentException.class);
        thrown.expectMessage(errorMsg);
    }
}
@@ -126,16 +126,121 @@
 ception;
+%0Aimport org.junit.runner.RunWith;%0Aimport org.mockito.Mock;%0Aimport org.mockito.runners.MockitoJUnitRunner;
 %0A%0Aimport
@@ -325,16 +325,58 @@
 hers.is;
+%0Aimport static org.mockito.Mockito.verify;
 %0A%0A/**%0A *
@@ -432,16 +432,51 @@
 ss.%0A */%0A
+@RunWith(MockitoJUnitRunner.class)%0A
 public c
@@ -506,16 +506,16 @@
   @Rule%0A
-
     publ
@@ -567,24 +567,69 @@
 on.none();%0A%0A
+    @Mock%0A    private QueryVisitor visitor;%0A%0A
     private 
@@ -4511,24 +4511,252 @@
 y));%0A    %7D%0A%0A
+    @Test%0A    public void visitorIsCalledCorrectly() throws Exception %7B%0A        FieldQuery%0A                query = new FieldQuery(%22field1%22, %22value1%22);%0A        query.accept(visitor);%0A        verify(visitor).visit(query);%0A    %7D%0A%0A%0A
     private 

Add test to check if visitor is being called properly.