package uk.ac.ebi.quickgo.annotation.controller;

import org.springframework.test.web.servlet.ResultMatcher;

import static java.lang.String.format;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;

/**
 * Helper class containing several methods that verifies the response from the stats endpoint.
 *
 * @author Ricardo Antunes
 */
final class StatsResponseVerifier {
    private static final String GROUP_NAME_TAG = "groupName";
    private static final String TYPE_NAME_TAG = "type";
    private static final String KEY_NAME_TAG = "key";
    private static final String TOTAL_GROUP_HITS_TAG = "totalHits";

    private StatsResponseVerifier() {}

    static ResultMatcher totalHitsInGroup(String groupName, int hits) {
        String hitsInGroupText = "%s[?(@.%s=='%s')].%s";

        return jsonPath(
                format(hitsInGroupText, ResponseVerifier.RESULTS, GROUP_NAME_TAG, groupName, TOTAL_GROUP_HITS_TAG)
        ).value(hits);
    }

    /**
     * Checks that the value specified in the {@param value} is present in the {@param
     * type} within the given {@param group}.
     *
     * @param group the stats group to check in
     * @param type the stats type defined within in the {@param group}
     * @param value the value to check for
     * @return a {@link ResultMatcher} that checks for the given inputs
     */
    static ResultMatcher numericValueForGroup(String group, String type, String field, int value) {
        String valuesInTypeForGroup = "%s[?(@.%s=='%s')]..[?(@.%s=='%s')]..%s";
        return jsonPath(
                format(valuesInTypeForGroup,
                        ResponseVerifier.RESULTS,
                        GROUP_NAME_TAG, group,
                        TYPE_NAME_TAG, type,
                        field),
                containsInAnyOrder(value)
        );
    }

    /**
     * Checks that all of the keys defined in the {@param keys} array are present in the {@param
     * type} within the given {@param group}.
     *
     * @param group the stats group to check in
     * @param type the stats type defined within in the {@param group}
     * @param keys the keys to check for
     * @return a {@link ResultMatcher} that checks for the given inputs
     */
    static ResultMatcher keysInTypeWithinGroup(String group, String type, String[] keys) {
        String valuesInTypeForGroup = "%s[?(@.%s=='%s')]..[?(@.%s=='%s')]..%s";
        return jsonPath(
                format(valuesInTypeForGroup,
                        ResponseVerifier.RESULTS,
                        GROUP_NAME_TAG, group,
                        TYPE_NAME_TAG, type,
                        KEY_NAME_TAG),
                containsInAnyOrder(keys)
        );
    }
}

@@ -630,16 +630,72 @@
  %22key%22;%0A
+    private static final String NAME_NAME_TAG = %22name%22;%0A
     priv
@@ -2454,24 +2454,801 @@
 g%5B%5D keys) %7B%0A
+        return targetInTypeWithinGroup(group, type, keys, KEY_NAME_TAG);%0A    %7D%0A%0A    /**%0A     * Checks that all of the names defined in the %7B@param names%7D array are present in the %7B@param%0A     * type%7D within the given %7B@param group%7D.%0A     *%0A     * @param group the stats group to check in%0A     * @param type the stats type defined within in the %7B@param group%7D%0A     * @param names the names to check for%0A     * @return a %7B@link ResultMatcher%7D that checks for the given inputs%0A     */%0A    static ResultMatcher namesInTypeWithinGroup(String group, String type, String%5B%5D names) %7B%0A        return targetInTypeWithinGroup(group, type, names, NAME_NAME_TAG);%0A    %7D%0A%0A    private static ResultMatcher targetInTypeWithinGroup(String group, String type, String%5B%5D expected, String target) %7B%0A
         Stri
@@ -3307,32 +3307,32 @@
 s=='%25s')%5D..%25s%22;%0A
-
         return j
@@ -3551,28 +3551,22 @@
         
-KEY_NAME_TAG
+target
 ),%0A     
@@ -3599,22 +3599,17 @@
 der(
-keys)%0A        
+expected)
 );%0A 

Add checking of names within a group, share code with key checking.