@Test
  public void threeGroups() {

    Result result1 = mock(Result.class);
    Map<String, Collection<Object>> props1 = Maps.newHashMap();
    props1.put("id", Sets.newHashSet((Object) "prop1"));
    when(result1.getProperties()).thenReturn(props1);

    Result result2 = mock(Result.class);
    Map<String, Collection<Object>> props2 = Maps.newHashMap();
    props2.put("id", Sets.newHashSet((Object) "prop2"));
    when(result2.getProperties()).thenReturn(props2);

    Result result3 = mock(Result.class);
    Map<String, Collection<Object>> props3 = Maps.newHashMap();
    props3.put("id", Sets.newHashSet((Object) "prop3"));
    when(result3.getProperties()).thenReturn(props3);

    List<Result> results = Lists.newArrayList(result1, result2, result3);

    when(rs.getSize()).thenReturn((long) 3);
    when(rs.getResultSetIterator()).thenReturn(results.iterator());

    Map<String, String> propertiesMap = Maps.newHashMap();

    provider.loadUserProperties(request, propertiesMap);

    System.out.println("GOT: " + propertiesMap.get("_groupQuery"));

    assertEquals(
        " AND id:(\"prop1\"^4 OR \"prop2\"^3 OR \"prop3\"^2) AND -readers:\"user1\"",
        propertiesMap.get("_groupQuery"));
  }
  @Test
  public void noGroups() {
    reset(auth1);
    Collection<Group> noGroups = Collections.emptyList();
    when(auth1.memberOf(authMgr)).thenReturn(noGroups.iterator());

    List<Result> results = Lists.newArrayList();
    when(rs.getResultSetIterator()).thenReturn(results.iterator());

    Map<String, String> propertiesMap = Maps.newHashMap();

    provider.loadUserProperties(request, propertiesMap);

    assertEquals("", propertiesMap.get("_groupQuery"));
  }
  @Test
  public void oneGroup() {
    Result result1 = mock(Result.class);
    Map<String, Collection<Object>> props1 = Maps.newHashMap();
    props1.put("id", Sets.newHashSet((Object) "prop1-id"));

    List<Result> results = Lists.newArrayList(result1);
    when(result1.getProperties()).thenReturn(props1);
    when(rs.getResultSetIterator()).thenReturn(results.iterator());

    Map<String, String> propertiesMap = Maps.newHashMap();

    provider.loadUserProperties(request, propertiesMap);

    assertEquals(
        " AND id:(\"prop1\\-id\"^1) AND -readers:\"user1\"", propertiesMap.get("_groupQuery"));
  }
  @Override
  protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response)
      throws ServletException, IOException {
    try {
      Resource resource = request.getResource();
      if (!resource.getPath().startsWith(SEARCH_PATH_PREFIX)) {
        response.sendError(
            HttpServletResponse.SC_FORBIDDEN,
            "Search templates can only be executed if they are located under "
                + SEARCH_PATH_PREFIX);
        return;
      }

      Node node = resource.adaptTo(Node.class);
      if (node != null && node.hasProperty(SAKAI_QUERY_TEMPLATE)) {
        // TODO: we might want to use this ?
        @SuppressWarnings("unused")
        boolean limitResults = true;
        if (node.hasProperty(SAKAI_LIMIT_RESULTS)) {
          limitResults = node.getProperty(SAKAI_LIMIT_RESULTS).getBoolean();
        }

        // KERN-1147 Respond better when all parameters haven't been provided for a query
        Query query = null;
        try {
          query = processQuery(request, node);
        } catch (MissingParameterException e) {
          response.sendError(HttpServletResponse.SC_BAD_REQUEST, e.getMessage());
          return;
        }

        long nitems =
            SolrSearchUtil.longRequestParameter(
                request, PARAMS_ITEMS_PER_PAGE, DEFAULT_PAGED_ITEMS);
        long page = SolrSearchUtil.longRequestParameter(request, PARAMS_PAGE, 0);

        // allow number of items to be specified in sakai:query-template-options
        if (query.getOptions().containsKey(PARAMS_ITEMS_PER_PAGE)) {
          nitems = Long.valueOf(query.getOptions().get(PARAMS_ITEMS_PER_PAGE));
        } else {
          // add this to the options so that all queries are constrained to a limited
          // number of returns per page.
          query.getOptions().put(PARAMS_ITEMS_PER_PAGE, Long.toString(nitems));
        }

        if (query.getOptions().containsKey(PARAMS_PAGE)) {
          page = Long.valueOf(query.getOptions().get(PARAMS_PAGE));
        } else {
          // add this to the options so that all queries are constrained to a limited
          // number of returns per page.
          query.getOptions().put(PARAMS_PAGE, Long.toString(page));
        }

        boolean useBatch = false;
        // Get the
        SolrSearchBatchResultProcessor searchBatchProcessor = defaultSearchBatchProcessor;
        if (node.hasProperty(SAKAI_BATCHRESULTPROCESSOR)) {
          searchBatchProcessor =
              batchProcessors.get(node.getProperty(SAKAI_BATCHRESULTPROCESSOR).getString());
          useBatch = true;
          if (searchBatchProcessor == null) {
            searchBatchProcessor = defaultSearchBatchProcessor;
          }
        }

        SolrSearchResultProcessor searchProcessor = defaultSearchProcessor;
        if (node.hasProperty(SAKAI_RESULTPROCESSOR)) {
          searchProcessor = processors.get(node.getProperty(SAKAI_RESULTPROCESSOR).getString());
          if (searchProcessor == null) {
            searchProcessor = defaultSearchProcessor;
          }
        }

        SolrSearchResultSet rs = null;
        try {
          // Prepare the result set.
          // This allows a processor to do other queries and manipulate the results.
          if (useBatch) {
            rs = searchBatchProcessor.getSearchResultSet(request, query);
          } else {
            rs = searchProcessor.getSearchResultSet(request, query);
          }
        } catch (SolrSearchException e) {
          response.sendError(e.getCode(), e.getMessage());
          return;
        }

        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");

        ExtendedJSONWriter write = new ExtendedJSONWriter(response.getWriter());
        write.setTidy(isTidy(request));

        write.object();
        write.key(PARAMS_ITEMS_PER_PAGE);
        write.value(nitems);
        write.key(JSON_RESULTS);

        write.array();

        Iterator<Result> iterator = rs.getResultSetIterator();
        if (useBatch) {
          LOGGER.info("Using batch processor for results");
          searchBatchProcessor.writeResults(request, write, iterator);
        } else {
          LOGGER.info("Using regular processor for results");
          // We don't skip any rows ourselves here.
          // We expect a rowIterator coming from a resultset to be at the right place.
          for (long i = 0; i < nitems && iterator.hasNext(); i++) {
            // Get the next row.
            Result result = iterator.next();

            // Write the result for this row.
            searchProcessor.writeResult(request, write, result);
          }
        }
        write.endArray();

        // write the total out after processing the list to give the underlying iterator
        // a chance to walk the results then report how many there were.
        write.key(TOTAL);
        write.value(rs.getSize());

        write.endObject();
      }
    } catch (RepositoryException e) {
      LOGGER.error(e.getMessage(), e);
      response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
    } catch (JSONException e) {
      LOGGER.error(e.getMessage(), e);
      response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
    }
  }