@Test
  public void testFillOptions() throws Exception {
    final Operand operand = new SingleValueOperand("one");
    final TerminalClause testClause = new TerminalClauseImpl("test", Operator.EQUALS, operand);
    final QueryLiteral literal1 = new QueryLiteral(operand, 1L);
    final QueryLiteral literal2 = new QueryLiteral(operand, 2L);
    final QueryLiteral literal3 = new QueryLiteral(operand, 3L);
    final MockOption option1 = new MockOption(null, null, null, null, null, 25L);
    final MockOption option2 = new MockOption(null, null, null, null, null, 26L);
    final MockOption option3 = new MockOption(null, null, null, null, null, 242L);
    final MockOption option4 = new MockOption(null, null, null, null, null, 27L);

    final List<QueryLiteral> testLiterals = Arrays.asList(literal1, literal2, literal3);

    when(jqlOperandResolver.getValues(theUser, operand, testClause)).thenReturn(testLiterals);

    jqlCascadingSelectLiteralUtil =
        new JqlCascadingSelectLiteralUtil(jqlSelectOptionsUtil) {
          @Override
          public void processPositiveNegativeOptionLiterals(
              final List<QueryLiteral> inputLiterals,
              final List<QueryLiteral> positiveLiterals,
              final List<QueryLiteral> negativeLiterals) {
            assertEquals(testLiterals, inputLiterals);
            positiveLiterals.add(literal1);
            positiveLiterals.add(literal2);
            negativeLiterals.add(literal3);
          }
        };

    when(jqlSelectOptionsUtil.getOptions(customField, literal1, true))
        .thenReturn(Collections.<Option>singletonList(option1));
    when(jqlSelectOptionsUtil.getOptions(customField, literal2, true))
        .thenReturn(Arrays.<Option>asList(option2, option3));
    when(jqlSelectOptionsUtil.getOptions(customField, literal3, true))
        .thenReturn(Arrays.<Option>asList(option4));

    final CascadingSelectCustomFieldClauseContextFactory factory =
        new CascadingSelectCustomFieldClauseContextFactory(
            customField,
            contextSetUtil,
            jqlSelectOptionsUtil,
            fieldConfigSchemeClauseContextUtil,
            jqlOperandResolver,
            jqlCascadingSelectLiteralUtil,
            operatorUsageValidator);

    Set<Option> posOpts = new HashSet<Option>();
    Set<Option> negOpts = new HashSet<Option>();

    factory.fillOptions(theUser, testClause, posOpts, negOpts);

    assertEquals(CollectionBuilder.<Option>newBuilder(option1, option2, option3).asSet(), posOpts);
    assertEquals(CollectionBuilder.<Option>newBuilder(option4).asSet(), negOpts);
  }
  @Test
  public void testNegativeQueryWithNegativeOptions() throws Exception {
    final TerminalClause testClause = new TerminalClauseImpl("one", Operator.NOT_IN, "fine");
    final MockOption option2 = new MockOption(null, null, null, null, null, 26L);
    final MockOption option2child2 = new MockOption(option2, null, null, null, null, 28L);
    final MockOption option2child1 = new MockOption(option2, null, null, null, null, 27L);
    option2.setChildOptions(Arrays.asList(option2child1, option2child2));

    final ClauseContext context2 = createContextForProjects(3);

    final FieldConfigScheme scheme = mock(FieldConfigScheme.class);
    when(scheme.isGlobal()).thenReturn(false);

    when(customField.getConfigurationSchemes()).thenReturn(Arrays.asList(scheme, scheme));

    // Will not be included because here are no options.
    when(jqlSelectOptionsUtil.getOptionsForScheme(scheme))
        .thenReturn(Collections.<Option>emptyList());

    // This second scheme should not be included because it only has options that we are to exclude.
    when(jqlSelectOptionsUtil.getOptionsForScheme(scheme))
        .thenReturn(Arrays.<Option>asList(option2, option2child1, option2child2));
    when(fieldConfigSchemeClauseContextUtil.getContextForConfigScheme(theUser, scheme))
        .thenReturn(context2);

    final CascadingSelectCustomFieldClauseContextFactory factory =
        new CascadingSelectCustomFieldClauseContextFactory(
            customField,
            contextSetUtil,
            jqlSelectOptionsUtil,
            fieldConfigSchemeClauseContextUtil,
            jqlOperandResolver,
            jqlCascadingSelectLiteralUtil,
            operatorUsageValidator) {
          @Override
          void fillOptions(
              final User user,
              final TerminalClause clause,
              final Set<Option> positiveOption,
              final Set<Option> negativeOption) {
            assertEquals(theUser, user);
            assertEquals(testClause, clause);

            negativeOption.add(option2child1);
          }
        };

    assertEquals(context2, factory.getClauseContext(theUser, testClause));
  }
  @Test
  public void testPositiveQueryWithPositiveAndNegativeOptions() throws Exception {
    final TerminalClause testClause = new TerminalClauseImpl("one", Operator.EQUALS, "fine");
    final MockOption option1 = new MockOption(null, null, null, null, null, 25L);
    final MockOption option2 = new MockOption(null, null, null, null, null, 26L);
    final MockOption option2child2 = new MockOption(option2, null, null, null, null, 28L);
    final MockOption option2child1 = new MockOption(option2, null, null, null, null, 27L);
    option2.setChildOptions(Arrays.asList(option2child1, option2child2));

    final ClauseContext context1 = createContextForProjects(1, 56);

    final FieldConfigScheme scheme = mock(FieldConfigScheme.class);
    when(customField.getConfigurationSchemes()).thenReturn(Arrays.asList(scheme, scheme));

    // The second scheme has no options in the scheme not in the exclude list.
    when(jqlSelectOptionsUtil.getOptionsForScheme(scheme))
        .thenReturn(Arrays.<Option>asList(option1, option2))
        .thenReturn(Arrays.<Option>asList(option2, option2child1, option2child2));
    when(fieldConfigSchemeClauseContextUtil.getContextForConfigScheme(theUser, scheme))
        .thenReturn(context1);

    final CascadingSelectCustomFieldClauseContextFactory factory =
        new CascadingSelectCustomFieldClauseContextFactory(
            customField,
            contextSetUtil,
            jqlSelectOptionsUtil,
            fieldConfigSchemeClauseContextUtil,
            jqlOperandResolver,
            jqlCascadingSelectLiteralUtil,
            operatorUsageValidator) {
          @Override
          void fillOptions(
              final User user,
              final TerminalClause clause,
              final Set<Option> positiveOption,
              final Set<Option> negativeOption) {
            assertEquals(theUser, user);
            assertEquals(testClause, clause);

            positiveOption.add(option1);
            negativeOption.add(option2);
          }
        };

    assertEquals(context1, factory.getClauseContext(theUser, testClause));
  }
  @Test
  public void testNoGeneratedContext() throws Exception {
    final TerminalClause testClause = new TerminalClauseImpl("one", Operator.EQUALS, "fine");
    final MockOption option1 = new MockOption(null, null, null, null, null, 25L);
    final MockOption option2 = new MockOption(null, null, null, null, null, 26L);
    final ClauseContext context1 = createContextForProjects(1, 2);
    final ClauseContext context2 = createContextForProjects(5);

    final FieldConfigScheme scheme = mock(FieldConfigScheme.class);
    when(customField.getConfigurationSchemes()).thenReturn(Arrays.asList(scheme, scheme));
    when(jqlSelectOptionsUtil.getOptionsForScheme(scheme))
        .thenReturn(Arrays.<Option>asList(option1, option2));
    when(fieldConfigSchemeClauseContextUtil.getContextForConfigScheme(theUser, scheme))
        .thenReturn(context1, context2);
    when(contextSetUtil.union(CollectionBuilder.newBuilder(context1, context2).asSet()))
        .thenReturn(new ClauseContextImpl());

    final CascadingSelectCustomFieldClauseContextFactory factory =
        new CascadingSelectCustomFieldClauseContextFactory(
            customField,
            contextSetUtil,
            jqlSelectOptionsUtil,
            fieldConfigSchemeClauseContextUtil,
            jqlOperandResolver,
            jqlCascadingSelectLiteralUtil,
            operatorUsageValidator) {
          @Override
          void fillOptions(
              final User user,
              final TerminalClause clause,
              final Set<Option> positiveOption,
              final Set<Option> negativeOption) {

            assertEquals(theUser, user);
            assertEquals(testClause, clause);

            positiveOption.add(option1);
          }
        };

    assertEquals(
        ClauseContextImpl.createGlobalClauseContext(),
        factory.getClauseContext(theUser, testClause));
  }