Просмотр исходного кода

Merge pull request #1220 from kw-udon/integration-tests-Aug-12

Improve Integration Tests for Admin APIs
Shinsuke Sugaya 8 лет назад
Родитель
Сommit
6c2a274037
19 измененных файлов с 256 добавлено и 73 удалено
  1. 3 3
      README.md
  2. 17 10
      src/main/java/org/codelibs/fess/app/web/admin/searchlist/AdminSearchlistAction.java
  3. 2 0
      src/main/java/org/codelibs/fess/app/web/admin/searchlist/CreateForm.java
  4. 6 1
      src/main/java/org/codelibs/fess/app/web/admin/searchlist/EditForm.java
  5. 2 2
      src/main/java/org/codelibs/fess/app/web/api/ApiResult.java
  6. 11 2
      src/main/java/org/codelibs/fess/app/web/api/admin/searchlist/ApiAdminSearchlistAction.java
  7. 14 0
      src/main/java/org/codelibs/fess/app/web/api/admin/searchlist/SearchBody.java
  8. 3 3
      src/main/java/org/codelibs/fess/mylasta/direction/FessConfig.java
  9. 4 4
      src/main/java/org/codelibs/fess/mylasta/direction/FessProp.java
  10. 1 1
      src/main/resources/fess_config.properties
  11. 48 24
      src/test/java/org/codelibs/fess/it/CrudTestBase.java
  12. 18 10
      src/test/java/org/codelibs/fess/it/admin/CrawlerLogTests.java
  13. 107 0
      src/test/java/org/codelibs/fess/it/admin/SearchListTests.java
  14. 12 0
      src/test/java/org/codelibs/fess/it/admin/dict/DictCrudTestBase.java
  15. 0 3
      src/test/java/org/codelibs/fess/it/admin/dict/KuromojiTests.java
  16. 0 1
      src/test/java/org/codelibs/fess/it/admin/dict/MappingTests.java
  17. 4 4
      src/test/java/org/codelibs/fess/it/admin/dict/ProtwordsTests.java
  18. 4 4
      src/test/java/org/codelibs/fess/it/admin/dict/SeunjeonTests.java
  19. 0 1
      src/test/java/org/codelibs/fess/it/admin/dict/SynonymTests.java

+ 3 - 3
README.md

@@ -1,4 +1,4 @@
-Enterprise Search Server: Fess 
+Enterprise Search Server: Fess
 ====
 
 ## Overview
@@ -44,7 +44,7 @@ You can register crawling targets on Web/File System/Data Store of admin pages,
 
 ## Fess on Docker Hub
 
-We provide Docker image on Docker Hub. 
+We provide Docker image on Docker Hub.
 For more details, see [Public Repository](https://hub.docker.com/r/codelibs/fess/).
 
 ## Migration from Other Systems
@@ -101,7 +101,7 @@ Run package goal and then the release file is created in target/releases.
 
 Launch Fess Server and run the following command:
 
-    mvn test -P integrationTests -Dtest.fess.url="http://localhost:8080" -Dtest.es.url="http://localhost:9201"
+    $ mvn test -P integrationTests -Dtest.fess.url="http://localhost:8080" -Dtest.es.url="http://localhost:9201"
 
 ### Translate In Your Language
 

+ 17 - 10
src/main/java/org/codelibs/fess/app/web/admin/searchlist/AdminSearchlistAction.java

@@ -281,7 +281,7 @@ public class AdminSearchlistAction extends FessAdminAction {
         verifyCrudMode(form.crudMode, CrudMode.EDIT);
         validate(form, messages -> {}, () -> asEditHtml());
         validateUpdateFields(form, v -> throwValidationError(v, () -> asEditHtml()));
-        logger.debug("DEBUUG:::role" + form.doc.get("role"));
+        logger.debug("DEBUG:::role" + form.doc.get("role"));
         verifyToken(() -> asEditHtml());
         getDoc(form).ifPresent(
                 entity -> {
@@ -325,46 +325,53 @@ public class AdminSearchlistAction extends FessAdminAction {
 
         if (!fessConfig.validateIndexRequiredFields(form.doc)) {
             final List<String> invalidRequiredFields = fessConfig.invalidIndexRequiredFields(form.doc);
+            final String invalids = String.join(", doc.", invalidRequiredFields);
+
             throwError.accept(messages -> {
-                messages.addErrorsCrudFailedToCreateInstance("doc." + invalidRequiredFields.get(0));
-                // TODO messages.addConstraintsRequiredMessage("doc." + invalidRequiredFields.get(0), invalidRequiredFields.get(0));
-                });
+                messages.addErrorsCrudFailedToCreateCrudTable("doc.", "Required: {doc." + invalids + "}");
+            });
         }
 
         if (!fessConfig.validateIndexArrayFields(form.doc)) {
             final List<String> invalidArrayFields = fessConfig.invalidIndexArrayFields(form.doc);
+            final String invalids = String.join(", doc.", invalidArrayFields);
             throwError.accept(messages -> {
-                messages.addErrorsCrudFailedToCreateInstance("doc." + invalidArrayFields.get(0));
+                messages.addErrorsCrudFailedToCreateCrudTable("doc.", "Must be Array: {doc." + invalids + "}");
             });
         }
         if (!fessConfig.validateIndexDateFields(form.doc)) {
             final List<String> invalidDateFields = fessConfig.invalidIndexDateFields(form.doc);
+            final String invalids = String.join(", doc.", invalidDateFields);
             throwError.accept(messages -> {
-                messages.addErrorsCrudFailedToCreateInstance("doc." + invalidDateFields.get(0));
+                messages.addErrorsCrudFailedToCreateCrudTable("doc.", "Must be Date: {doc." + invalids + "}");
             });
         }
         if (!fessConfig.validateIndexIntegerFields(form.doc)) {
             final List<String> invalidIntegerFields = fessConfig.invalidIndexIntegerFields(form.doc);
+            final String invalids = String.join(", doc.", invalidIntegerFields);
             throwError.accept(messages -> {
-                messages.addErrorsCrudFailedToCreateInstance("doc." + invalidIntegerFields.get(0));
+                messages.addErrorsCrudFailedToCreateCrudTable("doc.", "Must be Integer: {doc." + invalids + "}");
             });
         }
         if (!fessConfig.validateIndexLongFields(form.doc)) {
             final List<String> invalidLongFields = fessConfig.invalidIndexLongFields(form.doc);
+            final String invalids = String.join(", doc.", invalidLongFields);
             throwError.accept(messages -> {
-                messages.addErrorsCrudFailedToCreateInstance("doc." + invalidLongFields.get(0));
+                messages.addErrorsCrudFailedToCreateCrudTable("doc.", "Must be Long: {doc." + invalids + "}");
             });
         }
         if (!fessConfig.validateIndexFloatFields(form.doc)) {
             final List<String> invalidFloatFields = fessConfig.invalidIndexFloatFields(form.doc);
+            final String invalids = String.join(", doc.", invalidFloatFields);
             throwError.accept(messages -> {
-                messages.addErrorsCrudFailedToCreateInstance("doc." + invalidFloatFields.get(0));
+                messages.addErrorsCrudFailedToCreateCrudTable("doc.", "Must be Float: {doc." + invalids + "}");
             });
         }
         if (!fessConfig.validateIndexDoubleFields(form.doc)) {
             final List<String> invalidDoubleFields = fessConfig.invalidIndexDoubleFields(form.doc);
+            final String invalids = String.join(", doc.", invalidDoubleFields);
             throwError.accept(messages -> {
-                messages.addErrorsCrudFailedToCreateInstance("doc." + invalidDoubleFields.get(0));
+                messages.addErrorsCrudFailedToCreateCrudTable("doc.", "Must be Double: {doc." + invalids + "}");
             });
         }
     }

+ 2 - 0
src/main/java/org/codelibs/fess/app/web/admin/searchlist/CreateForm.java

@@ -17,6 +17,7 @@ package org.codelibs.fess.app.web.admin.searchlist;
 
 import java.util.Map;
 
+import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required;
 import org.lastaflute.web.validation.theme.conversion.ValidateTypeFailure;
 
 /**
@@ -27,6 +28,7 @@ public class CreateForm {
     @ValidateTypeFailure
     public Integer crudMode;
 
+    @Required
     public Map<String, Object> doc;
 
     public String q;

+ 6 - 1
src/main/java/org/codelibs/fess/app/web/admin/searchlist/EditForm.java

@@ -15,6 +15,9 @@
  */
 package org.codelibs.fess.app.web.admin.searchlist;
 
+import javax.validation.constraints.Size;
+
+import org.lastaflute.web.validation.Required;
 import org.lastaflute.web.validation.theme.conversion.ValidateTypeFailure;
 
 /**
@@ -24,9 +27,11 @@ public class EditForm extends CreateForm {
 
     public String id;
 
+    @Required
+    @Size(max = 1000)
     public String docId;
 
     @ValidateTypeFailure
     public Long version;
 
-}
+}

+ 2 - 2
src/main/java/org/codelibs/fess/app/web/api/ApiResult.java

@@ -149,7 +149,7 @@ public class ApiResult {
 
     public static class ApiDocsResponse extends ApiResponse {
         protected String queryId;
-        protected List<Map<String, Object>> result;
+        protected List<Map<String, Object>> docs;
         protected String highlightParams;
         protected String execTime;
         protected int pageSize;
@@ -170,7 +170,7 @@ public class ApiResult {
 
         public ApiDocsResponse renderData(final SearchRenderData data) {
             queryId = data.getQueryId();
-            result = data.getDocumentItems();
+            docs = data.getDocumentItems();
             highlightParams = data.getAppendHighlightParams();
             execTime = data.getExecTime();
             pageSize = data.getPageSize();

+ 11 - 2
src/main/java/org/codelibs/fess/app/web/api/admin/searchlist/ApiAdminSearchlistAction.java

@@ -70,8 +70,8 @@ public class ApiAdminSearchlistAction extends FessApiAdminAction {
     //                                                                      Search Execute
     //                                                                      ==============
 
-    // GET /api/admin/searchlist
-    // POST /api/admin/searchlist
+    // GET /api/admin/searchlist/docs
+    // POST /api/admin/searchlist/docs
     @Execute
     public JsonResponse<ApiResult> docs(final SearchBody body) {
         validateApi(body, messages -> {});
@@ -80,6 +80,7 @@ public class ApiAdminSearchlistAction extends FessApiAdminAction {
             // query matches on all documents.
             body.q = Constants.MATCHES_ALL_QUERY;
         }
+
         final SearchRenderData renderData = new SearchRenderData();
         body.initialize();
         try {
@@ -118,6 +119,9 @@ public class ApiAdminSearchlistAction extends FessApiAdminAction {
     @Execute
     public JsonResponse<ApiResult> put$doc(final CreateBody body) {
         validateApi(body, messages -> {});
+        if (body.doc == null) {
+            throwValidationErrorApi(messages -> messages.addErrorsCrudFailedToCreateCrudTable(GLOBAL, "doc is required"));
+        }
         validateCreateFields(body, v -> throwValidationErrorApi(v));
         body.crudMode = CrudMode.CREATE;
         final Map<String, Object> doc = getDoc(body).map(entity -> {
@@ -148,6 +152,11 @@ public class ApiAdminSearchlistAction extends FessApiAdminAction {
     @Execute
     public JsonResponse<ApiResult> post$doc(final EditBody body) {
         validateApi(body, messages -> {});
+
+        if (body.doc == null) {
+            throwValidationErrorApi(messages -> messages.addErrorsCrudFailedToCreateCrudTable(GLOBAL, "doc is required"));
+        }
+
         validateUpdateFields(body, v -> throwValidationErrorApi(v));
         body.crudMode = CrudMode.EDIT;
         final Map<String, Object> doc = getDoc(body).map(entity -> {

+ 14 - 0
src/main/java/org/codelibs/fess/app/web/api/admin/searchlist/SearchBody.java

@@ -16,7 +16,21 @@
 package org.codelibs.fess.app.web.api.admin.searchlist;
 
 import org.codelibs.fess.app.web.admin.searchlist.ListForm;
+import org.lastaflute.web.validation.theme.conversion.ValidateTypeFailure;
 
 public class SearchBody extends ListForm {
 
+    // `size` is an alias of `num`.
+    // `size` is prepared to be compatible with other Admin APIs
+    @ValidateTypeFailure
+    public Integer size;
+
+    @Override
+    public void initialize() {
+        if (size != null) {
+            num = (num == null || num < size) ? size : num;
+        }
+        super.initialize();
+    }
+
 }

+ 3 - 3
src/main/java/org/codelibs/fess/mylasta/direction/FessConfig.java

@@ -450,7 +450,7 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
     /** The key of the configuration. e.g.  */
     String INDEX_ADMIN_DOUBLE_FIELDS = "index.admin.double.fields";
 
-    /** The key of the configuration. e.g. doc_id,url,title,role,boost */
+    /** The key of the configuration. e.g. url,title,role,boost */
     String INDEX_ADMIN_REQUIRED_FIELDS = "index.admin.required.fields";
 
     /** The key of the configuration. e.g. 3m */
@@ -2579,7 +2579,7 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
 
     /**
      * Get the value for the key 'index.admin.required.fields'. <br>
-     * The value is, e.g. doc_id,url,title,role,boost <br>
+     * The value is, e.g. url,title,role,boost <br>
      * @return The value of found property. (NotNull: if not found, exception but basically no way)
      */
     String getIndexAdminRequiredFields();
@@ -7568,7 +7568,7 @@ public interface FessConfig extends FessEnv, org.codelibs.fess.mylasta.direction
             defaultMap.put(FessConfig.INDEX_ADMIN_LONG_FIELDS, "content_length,favorite_count,click_count");
             defaultMap.put(FessConfig.INDEX_ADMIN_FLOAT_FIELDS, "boost");
             defaultMap.put(FessConfig.INDEX_ADMIN_DOUBLE_FIELDS, "");
-            defaultMap.put(FessConfig.INDEX_ADMIN_REQUIRED_FIELDS, "doc_id,url,title,role,boost");
+            defaultMap.put(FessConfig.INDEX_ADMIN_REQUIRED_FIELDS, "url,title,role,boost");
             defaultMap.put(FessConfig.INDEX_SEARCH_TIMEOUT, "3m");
             defaultMap.put(FessConfig.INDEX_SCROLL_SEARCH_TIMEOUT_TIMEOUT, "3m");
             defaultMap.put(FessConfig.INDEX_INDEX_TIMEOUT, "3m");

+ 4 - 4
src/main/java/org/codelibs/fess/mylasta/direction/FessProp.java

@@ -1254,7 +1254,7 @@ public interface FessProp {
         final IntegerTypeValidator integerValidator = new IntegerTypeValidator();
         return split(getIndexAdminIntegerFields(), ",").get(
                 stream -> stream.filter(StringUtil::isNotBlank).map(s -> s.trim()).filter(s -> isNonEmptyValue(source.get(s)))
-                        .filter(s -> !integerValidator.isValid((String) source.get(s), null)).collect(Collectors.toList()));
+                        .filter(s -> !integerValidator.isValid(source.get(s).toString(), null)).collect(Collectors.toList()));
     }
 
     String getIndexAdminLongFields();
@@ -1279,7 +1279,7 @@ public interface FessProp {
         final LongTypeValidator longValidator = new LongTypeValidator();
         return split(getIndexAdminLongFields(), ",").get(
                 stream -> stream.filter(StringUtil::isNotBlank).map(s -> s.trim()).filter(s -> isNonEmptyValue(source.get(s)))
-                        .filter(s -> !longValidator.isValid((String) source.get(s), null)).collect(Collectors.toList()));
+                        .filter(s -> !longValidator.isValid(source.get(s).toString(), null)).collect(Collectors.toList()));
     }
 
     String getIndexAdminFloatFields();
@@ -1304,7 +1304,7 @@ public interface FessProp {
         final FloatTypeValidator floatValidator = new FloatTypeValidator();
         return split(getIndexAdminFloatFields(), ",").get(
                 stream -> stream.filter(StringUtil::isNotBlank).map(s -> s.trim()).filter(s -> isNonEmptyValue(source.get(s)))
-                        .filter(s -> !floatValidator.isValid((String) source.get(s), null)).collect(Collectors.toList()));
+                        .filter(s -> !floatValidator.isValid(source.get(s).toString(), null)).collect(Collectors.toList()));
     }
 
     String getIndexAdminDoubleFields();
@@ -1329,7 +1329,7 @@ public interface FessProp {
         final DoubleTypeValidator doubleValidator = new DoubleTypeValidator();
         return split(getIndexAdminDoubleFields(), ",").get(
                 stream -> stream.filter(StringUtil::isNotBlank).map(s -> s.trim()).filter(s -> isNonEmptyValue(source.get(s)))
-                        .filter(s -> !doubleValidator.isValid((String) source.get(s), null)).collect(Collectors.toList()));
+                        .filter(s -> !doubleValidator.isValid(source.get(s).toString(), null)).collect(Collectors.toList()));
     }
 
     public default Map<String, Object> convertToEditableDoc(final Map<String, Object> source) {

+ 1 - 1
src/main/resources/fess_config.properties

@@ -209,7 +209,7 @@ index.admin.integer.fields=
 index.admin.long.fields=content_length,favorite_count,click_count
 index.admin.float.fields=boost
 index.admin.double.fields=
-index.admin.required.fields=doc_id,url,title,role,boost
+index.admin.required.fields=url,title,role,boost
 
 # timeout
 index.search.timeout=3m

+ 48 - 24
src/test/java/org/codelibs/fess/it/CrudTestBase.java

@@ -30,6 +30,8 @@ import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.BeforeEach;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import io.restassured.RestAssured;
 import io.restassured.path.json.JsonPath;
@@ -40,6 +42,8 @@ public abstract class CrudTestBase extends ITBase {
     protected static final int NUM = 20;
     protected static final int SEARCH_ALL_NUM = 1000;
 
+    private static final Logger logger = LoggerFactory.getLogger(CrudTestBase.class);
+
     // ================
     // Abstract Methods
     // ================
@@ -58,6 +62,11 @@ public abstract class CrudTestBase extends ITBase {
     abstract protected Map<String, Object> getUpdateMap();
 
     // ================
+    // Constant
+    // ================
+    protected String getIdKey() {
+        return "id";
+    }
 
     @BeforeAll
     protected static void initAll() {
@@ -71,12 +80,16 @@ public abstract class CrudTestBase extends ITBase {
 
     @AfterEach
     protected void tearDown() {
-        final Map<String, Object> searchBody = new HashMap<>();
-        searchBody.put("size", SEARCH_ALL_NUM);
-        List<String> idList = getPropList(searchBody, "id");
-        idList.forEach(id -> {
-            checkDeleteMethod(getItemEndpointSuffix() + "/" + id);
-        });
+        final Map<String, Object> searchBody = createSearchBody(SEARCH_ALL_NUM);
+        int count = 0;
+        List<String> idList = getIdList(searchBody);
+        while(idList.size() > 0 && count < NUM) {
+            final String id = idList.get(0);
+            checkDeleteMethod(getItemEndpointSuffix() + "/" + id.toString());
+            refresh();
+            idList = getIdList(searchBody);
+            count += 1;
+        }
     }
 
     @AfterAll
@@ -93,18 +106,19 @@ public abstract class CrudTestBase extends ITBase {
             final Map<String, Object> requestBody = createTestParam(i);
             checkPutMethod(requestBody, getItemEndpointSuffix()).then().body("response.created", equalTo(true))
                     .body("response.status", equalTo(0));
+
+            //logger.info("create " + i + checkPutMethod(requestBody, getItemEndpointSuffix()).asString()); // for debugging
+            refresh();
         }
 
         // Test: number of settings.
-        final Map<String, Object> searchBody = new HashMap<>();
-        searchBody.put("size", SEARCH_ALL_NUM);
+        final Map<String, Object> searchBody = createSearchBody(SEARCH_ALL_NUM);
         checkGetMethod(searchBody, getListEndpointSuffix()).then().body(getJsonPath() + ".size()", equalTo(NUM));
     }
 
     protected void testRead() {
         // Test: get settings api.
-        final Map<String, Object> searchBody = new HashMap<>();
-        searchBody.put("size", SEARCH_ALL_NUM);
+        final Map<String, Object> searchBody = createSearchBody(SEARCH_ALL_NUM);
         List<String> nameList = getPropList(searchBody, getKeyProperty());
 
         assertEquals(NUM, nameList.size());
@@ -113,11 +127,11 @@ public abstract class CrudTestBase extends ITBase {
             assertTrue(nameList.contains(name), name);
         }
 
-        List<String> idList = getPropList(searchBody, "id");
+        List<String> idList = getIdList(searchBody);
         idList.forEach(id -> {
             // Test: get setting api
             checkGetMethod(searchBody, getItemEndpointSuffix() + "/" + id).then()
-                    .body("response." + getItemEndpointSuffix() + ".id", equalTo(id))
+                    .body("response." + getItemEndpointSuffix() + "." + getIdKey(), equalTo(id))
                     .body("response." + getItemEndpointSuffix() + "." + getKeyProperty(), startsWith(getNamePrefix()));
         });
 
@@ -134,15 +148,15 @@ public abstract class CrudTestBase extends ITBase {
         // Test: update settings api
         final Set<String> keySet = createTestParam(0).keySet();
         final Map<String, Object> updateMap = getUpdateMap();
-        Map<String, Object> searchBody = new HashMap<>();
-        searchBody.put("size", SEARCH_ALL_NUM);
+        final Map<String, Object> searchBody = createSearchBody(SEARCH_ALL_NUM);
         List<Map<String, Object>> settings = getItemList(searchBody);
 
         for (Map<String, Object> setting : settings) {
             final Map<String, Object> requestBody = new HashMap<>(updateMap);
             requestBody.put("version_no", 1);
-            if (setting.containsKey("id")) {
-                requestBody.put("id", setting.get("id"));
+            final String idKey = getIdKey();
+            if (setting.containsKey(idKey)) {
+                requestBody.put(idKey, setting.get(idKey));
             }
             for (String key : keySet) {
                 if (!requestBody.containsKey(key)) {
@@ -151,6 +165,7 @@ public abstract class CrudTestBase extends ITBase {
             }
 
             checkPostMethod(requestBody, getItemEndpointSuffix()).then().body("response.status", equalTo(0));
+            refresh();
         }
 
         checkUpdate();
@@ -169,16 +184,15 @@ public abstract class CrudTestBase extends ITBase {
     }
 
     protected void testDelete() {
-        final Map<String, Object> searchBody = new HashMap<>();
-        searchBody.put("size", SEARCH_ALL_NUM);
-        List<String> idList = getPropList(searchBody, "id");
+        final Map<String, Object> searchBody = createSearchBody(SEARCH_ALL_NUM);
 
-        idList.forEach(id -> {
-            //Test: delete setting api
-            checkDeleteMethod(getItemEndpointSuffix() + "/" + id).then().body("response.status", equalTo(0));
-        });
+        for (int count = 0; count < NUM; count++) {
+            final String id = getIdList(searchBody).get(0);
+            checkDeleteMethod(getItemEndpointSuffix() + "/" + id.toString()).then().body("response.status", equalTo(0));
+            refresh();
+        }
 
-        // Test: NUMber of settings.
+        // Test: number of settings.
         checkGetMethod(searchBody, getListEndpointSuffix()).then().body(getJsonPath() + ".size()", equalTo(0));
     }
 
@@ -206,6 +220,10 @@ public abstract class CrudTestBase extends ITBase {
         return JsonPath.from(response).getList(getJsonPath());
     }
 
+    protected List<String> getIdList(final Map<String, Object> body) {
+        return getPropList(body, getIdKey());
+    }
+
     protected List<String> getPropList(final Map<String, Object> body, final String prop) {
         String response = checkGetMethod(body, getListEndpointSuffix()).asString();
         return JsonPath.from(response).getList(getJsonPath() + "." + prop);
@@ -214,4 +232,10 @@ public abstract class CrudTestBase extends ITBase {
     protected String getJsonPath() {
         return "response." + getListEndpointSuffix() + ".findAll {it." + getKeyProperty() + ".startsWith(\"" + getNamePrefix() + "\")}";
     }
+
+    protected Map<String, Object> createSearchBody(final int size) {
+        final Map<String, Object> searchBody = new HashMap<>();
+        searchBody.put("size", size);
+        return searchBody;
+    }
 }

+ 18 - 10
src/test/java/org/codelibs/fess/it/admin/CrawlerLogTests.java

@@ -41,7 +41,7 @@ import io.restassured.path.json.JsonPath;
 import io.restassured.response.Response;
 
 /**
- * Integration Tests for
+ * Integration Tests which need an execution of crawler
  * - /api/admin/joblog
  * - /api/admin/crawlinginfo
  * - /api/admin/failureurl
@@ -65,7 +65,7 @@ public class CrawlerLogTests extends ITBase {
             createWebConfig();
             logger.info("WebConfig is created");
             refresh();
-            webConfigId = getWebConfigId();
+            webConfigId = getWebConfigIds().get(0);
 
             createJob();
             logger.info("Job is created");
@@ -74,6 +74,7 @@ public class CrawlerLogTests extends ITBase {
             startJob();
 
             waitJob();
+            refresh();
         } catch (InterruptedException e) {
             e.printStackTrace();
             assertTrue(false);
@@ -82,6 +83,7 @@ public class CrawlerLogTests extends ITBase {
 
     @BeforeEach
     protected void init() {
+        refresh();
     }
 
     @AfterEach
@@ -108,9 +110,15 @@ public class CrawlerLogTests extends ITBase {
         final Map<String, Object> requestBody = new HashMap<>();
         requestBody.put("q", "Example Domain");
         checkMethodBase(requestBody).delete("/api/admin/searchlist/query");
+        refresh();
 
-        deleteMethod("/api/admin/scheduler/setting/" + getSchedulerId());
-        deleteMethod("/api/admin/webconfig/setting/" + webConfigId);
+        for (String sId : getSchedulerIds()) {
+            deleteMethod("/api/admin/scheduler/setting/" + sId);
+        }
+
+        for (String wId : getWebConfigIds()) {
+            deleteMethod("/api/admin/webconfig/setting/" + wId);
+        }
 
         deleteTestToken();
     }
@@ -177,7 +185,7 @@ public class CrawlerLogTests extends ITBase {
     private static void startJob() {
         for (int i = 0; i < 30; i++) {
             final Map<String, Object> requestBody = new HashMap<>();
-            final String schedulerId = getSchedulerId();
+            final String schedulerId = getSchedulerIds().get(0);
             final Response response = checkMethodBase(requestBody).post("/api/admin/scheduler/" + schedulerId + "/start");
             if (response.getBody().jsonPath().getInt("response.status") == 0) {
                 logger.info("Start scheduler \"" + schedulerId + "\"");
@@ -341,7 +349,7 @@ public class CrawlerLogTests extends ITBase {
         requestBody.put("q", "Example Domain");
 
         final String response = checkMethodBase(requestBody).get("/api/admin/searchlist/docs").asString();
-        final List<Map<String, Object>> results = JsonPath.from(response).getList("response.result");
+        final List<Map<String, Object>> results = JsonPath.from(response).getList("response.docs");
         return results;
     }
 
@@ -365,16 +373,16 @@ public class CrawlerLogTests extends ITBase {
         return "response.settings.findAll {it.name.startsWith(\"" + NAME_PREFIX + "\")}";
     }
 
-    private static String getWebConfigId() {
+    private static List<String> getWebConfigIds() {
         final String response = getJsonResponse("/api/admin/webconfig/settings");
         final List<String> idList = JsonPath.from(response).getList(getResponsePath() + ".id");
-        return idList.get(0);
+        return idList;
     }
 
-    private static String getSchedulerId() {
+    private static List<String> getSchedulerIds() {
         final String response = getJsonResponse("/api/admin/scheduler/settings");
         final List<String> idList = JsonPath.from(response).getList(getResponsePath() + ".id");
-        return idList.get(0);
+        return idList;
     }
 
     private static Map<String, Object> getSchedulerItem() {

+ 107 - 0
src/test/java/org/codelibs/fess/it/admin/SearchListTests.java

@@ -0,0 +1,107 @@
+/*
+ * Copyright 2012-2017 CodeLibs Project and the Others.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific language
+ * governing permissions and limitations under the License.
+ */
+package org.codelibs.fess.it.admin;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.codelibs.fess.it.CrudTestBase;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+
+@Tag("it")
+public class SearchListTests extends CrudTestBase {
+
+    private static final String NAME_PREFIX = "searchListTest_";
+    private static final String API_PATH = "/api/admin/searchlist";
+    private static final String LIST_ENDPOINT_SUFFIX = "docs";
+    private static final String ITEM_ENDPOINT_SUFFIX = "doc";
+
+    private static final String KEY_PROPERTY = "title";
+
+    @Override
+    protected String getNamePrefix() {
+        return NAME_PREFIX;
+    }
+
+    @Override
+    protected String getApiPath() {
+        return API_PATH;
+    }
+
+    @Override
+    protected String getKeyProperty() {
+        return KEY_PROPERTY;
+    }
+
+    @Override
+    protected String getListEndpointSuffix() {
+        return LIST_ENDPOINT_SUFFIX;
+    }
+
+    @Override
+    protected String getItemEndpointSuffix() {
+        return ITEM_ENDPOINT_SUFFIX;
+    }
+
+    @Override
+    protected String getIdKey() {
+        return "doc_id";
+    }
+
+    @Override
+    protected Map<String, Object> createTestParam(int id) {
+
+        final Map<String, Object> doc = new HashMap<>();
+        final String keyProp = NAME_PREFIX + id;
+        doc.put(KEY_PROPERTY, keyProp);
+        doc.put("url", "http://example.com/" + id);
+        doc.put("boost", id);
+        doc.put("role", "Rguest");
+
+        final Map<String, Object> requestBody = new HashMap<>();
+        requestBody.put("doc", doc);
+        return requestBody;
+    }
+
+    @Override
+    protected Map<String, Object> createSearchBody(final int size) {
+        final Map<String, Object> searchBody = new HashMap<>();
+        searchBody.put("size", size);
+        searchBody.put("q", NAME_PREFIX);
+        return searchBody;
+    }
+
+    @Override
+    protected Map<String, Object> getUpdateMap() {
+        // TODO
+        assertTrue(false);
+
+        final Map<String, Object> updateMap = new HashMap<>();
+        updateMap.put("click_count", 100);
+        return updateMap;
+    }
+
+    @Test
+    void crudTest() {
+        testCreate();
+        testRead();
+        //testUpdate(); // TODO
+        testDelete();
+    }
+}

+ 12 - 0
src/test/java/org/codelibs/fess/it/admin/dict/DictCrudTestBase.java

@@ -18,6 +18,7 @@ package org.codelibs.fess.it.admin.dict;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -68,6 +69,17 @@ public abstract class DictCrudTestBase extends CrudTestBase {
         return "response." + LIST_ENDPOINT_SUFFIX + ".findAll {it." + getKeyProperty() + ".startsWith(\"" + getNamePrefix() + "\")}";
     }
 
+    @Override
+    protected List<String> getIdList(final Map<String, Object> body) {
+        String response = checkGetMethod(body, getListEndpointSuffix()).asString();
+        List<Object> objList = JsonPath.from(response).getList(getJsonPath() + "." + getIdKey());
+        List<String> ret = new ArrayList<>();
+        for (Object obj : objList) {
+            ret.add(obj.toString());
+        }
+        return ret;
+    }
+
     @Override
     protected void testRead() {
         final Map<String, Object> searchBody = new HashMap<>();

+ 0 - 3
src/test/java/org/codelibs/fess/it/admin/dict/KuromojiTests.java

@@ -76,10 +76,7 @@ public class KuromojiTests extends DictCrudTestBase {
     @Override
     protected Map<String, Object> getUpdateMap() {
         final Map<String, Object> updateMap = new HashMap<>();
-        updateMap.put(KEY_PROPERTY, "new_token");
         updateMap.put("segmentation", "new_segment");
-        updateMap.put("reading", "new_reading");
-        updateMap.put("pos", "new_pos");
         return updateMap;
     }
 

+ 0 - 1
src/test/java/org/codelibs/fess/it/admin/dict/MappingTests.java

@@ -74,7 +74,6 @@ public class MappingTests extends DictCrudTestBase {
     @Override
     protected Map<String, Object> getUpdateMap() {
         final Map<String, Object> updateMap = new HashMap<>();
-        updateMap.put(KEY_PROPERTY, "new_inputs");
         updateMap.put("output", "new_output");
         return updateMap;
     }

+ 4 - 4
src/test/java/org/codelibs/fess/it/admin/dict/ProtwordsTests.java

@@ -15,6 +15,8 @@
  */
 package org.codelibs.fess.it.admin.dict;
 
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
 import java.util.HashMap;
 import java.util.Map;
 
@@ -72,16 +74,14 @@ public class ProtwordsTests extends DictCrudTestBase {
 
     @Override
     protected Map<String, Object> getUpdateMap() {
-        final Map<String, Object> updateMap = new HashMap<>();
-        updateMap.put(KEY_PROPERTY, "new_input");
-        return updateMap;
+        assertTrue(false); // Unreachable
+        return null;
     }
 
     @Test
     void crudTest() {
         testCreate();
         testRead();
-        testUpdate();
         testDelete();
     }
 }

+ 4 - 4
src/test/java/org/codelibs/fess/it/admin/dict/SeunjeonTests.java

@@ -15,6 +15,8 @@
  */
 package org.codelibs.fess.it.admin.dict;
 
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
 import java.util.HashMap;
 import java.util.Map;
 
@@ -72,16 +74,14 @@ public class SeunjeonTests extends DictCrudTestBase {
 
     @Override
     protected Map<String, Object> getUpdateMap() {
-        final Map<String, Object> updateMap = new HashMap<>();
-        updateMap.put(KEY_PROPERTY, "new_inputs");
-        return updateMap;
+        assertTrue(false); // Unreachable
+        return null;
     }
 
     @Test
     void crudTest() {
         testCreate();
         testRead();
-        testUpdate();
         testDelete();
     }
 }

+ 0 - 1
src/test/java/org/codelibs/fess/it/admin/dict/SynonymTests.java

@@ -74,7 +74,6 @@ public class SynonymTests extends DictCrudTestBase {
     @Override
     protected Map<String, Object> getUpdateMap() {
         final Map<String, Object> updateMap = new HashMap<>();
-        updateMap.put(KEY_PROPERTY, "new_inputs");
         updateMap.put("outputs", "new_outputs");
         return updateMap;
     }