diff --git a/docs-parent/TODO b/docs-parent/TODO index 32bd748b..e69de29b 100644 --- a/docs-parent/TODO +++ b/docs-parent/TODO @@ -1,2 +0,0 @@ -- Search criterias: if a date do not parse, returns no documents (server) -- Raise file deleted event on document deletion (server) \ No newline at end of file diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/DocumentResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/DocumentResource.java index 9797c8a1..4dce379e 100644 --- a/docs-web/src/main/java/com/sismics/docs/rest/resource/DocumentResource.java +++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/DocumentResource.java @@ -34,6 +34,7 @@ import com.google.common.base.Joiner; import com.google.common.base.Strings; import com.sismics.docs.core.constant.Constants; import com.sismics.docs.core.dao.jpa.DocumentDao; +import com.sismics.docs.core.dao.jpa.FileDao; import com.sismics.docs.core.dao.jpa.ShareDao; import com.sismics.docs.core.dao.jpa.TagDao; import com.sismics.docs.core.dao.jpa.criteria.DocumentCriteria; @@ -42,8 +43,10 @@ import com.sismics.docs.core.dao.jpa.dto.TagDto; import com.sismics.docs.core.event.DocumentCreatedAsyncEvent; import com.sismics.docs.core.event.DocumentDeletedAsyncEvent; import com.sismics.docs.core.event.DocumentUpdatedAsyncEvent; +import com.sismics.docs.core.event.FileDeletedAsyncEvent; import com.sismics.docs.core.model.context.AppContext; import com.sismics.docs.core.model.jpa.Document; +import com.sismics.docs.core.model.jpa.File; import com.sismics.docs.core.model.jpa.Share; import com.sismics.docs.core.model.jpa.Tag; import com.sismics.docs.core.util.jpa.PaginatedList; @@ -243,7 +246,9 @@ public class DocumentResource extends BaseResource { if (params[0].equals("before")) documentCriteria.setCreateDateMax(date.toDate()); else documentCriteria.setCreateDateMin(date.toDate()); } catch (IllegalArgumentException e) { - // NOP + // Invalid date, returns no documents + if (params[0].equals("before")) documentCriteria.setCreateDateMax(new Date(0)); + else documentCriteria.setCreateDateMin(new Date(Long.MAX_VALUE / 2)); } } else if (params[0].equals("at")) { // New specific date criteria @@ -262,7 +267,9 @@ public class DocumentResource extends BaseResource { documentCriteria.setCreateDateMax(date.plusYears(1).minusSeconds(1).toDate()); } } catch (IllegalArgumentException e) { - // NOP + // Invalid date, returns no documents + documentCriteria.setCreateDateMin(new Date(0)); + documentCriteria.setCreateDateMax(new Date(0)); } } else if (params[0].equals("shared")) { // New shared state criteria @@ -455,21 +462,31 @@ public class DocumentResource extends BaseResource { // Get the document DocumentDao documentDao = new DocumentDao(); + FileDao fileDao = new FileDao(); Document document; + List fileList; try { document = documentDao.getDocument(id, principal.getId()); + fileList = fileDao.getByDocumentId(id); } catch (NoResultException e) { throw new ClientException("DocumentNotFound", MessageFormat.format("Document not found: {0}", id)); } + // Delete the document + documentDao.delete(document.getId()); + + // Raise file deleted events + for (File file : fileList) { + FileDeletedAsyncEvent fileDeletedAsyncEvent = new FileDeletedAsyncEvent(); + fileDeletedAsyncEvent.setFile(file); + AppContext.getInstance().getAsyncEventBus().post(fileDeletedAsyncEvent); + } + // Raise a document deleted event DocumentDeletedAsyncEvent documentDeletedAsyncEvent = new DocumentDeletedAsyncEvent(); documentDeletedAsyncEvent.setDocument(document); AppContext.getInstance().getAsyncEventBus().post(documentDeletedAsyncEvent); - // Delete the document - documentDao.delete(document.getId()); - // Always return ok JSONObject response = new JSONObject(); response.put("status", "ok"); diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/FileResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/FileResource.java index dd36e662..7d1258e9 100644 --- a/docs-web/src/main/java/com/sismics/docs/rest/resource/FileResource.java +++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/FileResource.java @@ -249,14 +249,14 @@ public class FileResource extends BaseResource { throw new ClientException("FileNotFound", MessageFormat.format("File not found: {0}", id)); } + // Delete the file + fileDao.delete(file.getId()); + // Raise a new file deleted event FileDeletedAsyncEvent fileDeletedAsyncEvent = new FileDeletedAsyncEvent(); fileDeletedAsyncEvent.setFile(file); AppContext.getInstance().getAsyncEventBus().post(fileDeletedAsyncEvent); - // Delete the file - fileDao.delete(file.getId()); - // Always return ok JSONObject response = new JSONObject(); response.put("status", "ok"); diff --git a/docs-web/src/test/java/com/sismics/docs/rest/TestDocumentResource.java b/docs-web/src/test/java/com/sismics/docs/rest/TestDocumentResource.java index 74cad3eb..003f4b80 100644 --- a/docs-web/src/test/java/com/sismics/docs/rest/TestDocumentResource.java +++ b/docs-web/src/test/java/com/sismics/docs/rest/TestDocumentResource.java @@ -3,6 +3,7 @@ package com.sismics.docs.rest; import java.io.BufferedInputStream; import java.io.InputStream; +import java.nio.file.Paths; import java.util.Date; import javax.ws.rs.core.MediaType; @@ -10,12 +11,12 @@ import javax.ws.rs.core.MediaType; import junit.framework.Assert; import org.codehaus.jettison.json.JSONArray; -import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; import org.joda.time.format.DateTimeFormat; import org.junit.Test; import com.google.common.io.ByteStreams; +import com.sismics.docs.core.util.DirectoryUtil; import com.sismics.docs.rest.filter.CookieAuthenticationFilter; import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.ClientResponse.Status; @@ -32,11 +33,10 @@ import com.sun.jersey.multipart.FormDataMultiPart; public class TestDocumentResource extends BaseJerseyTest { /** * Test the document resource. - * - * @throws JSONException + * @throws Exception */ @Test - public void testDocumentResource() throws JSONException { + public void testDocumentResource() throws Exception { // Login document1 clientUtil.createUser("document1"); String document1Token = clientUtil.login("document1"); @@ -82,6 +82,7 @@ public class TestDocumentResource extends BaseJerseyTest { response = fileResource.type(MediaType.MULTIPART_FORM_DATA).put(ClientResponse.class, form); Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus())); json = response.getEntity(JSONObject.class); + String file1Id = json.getString("id"); // Share this document WebResource fileShareResource = resource().path("/share"); @@ -111,179 +112,31 @@ public class TestDocumentResource extends BaseJerseyTest { Assert.assertEquals("SuperTag", tags.getJSONObject(0).getString("name")); Assert.assertEquals("#ffff00", tags.getJSONObject(0).getString("color")); - // Search documents by query in full content - documentResource = resource().path("/document/list"); - documentResource.addFilter(new CookieAuthenticationFilter(document1Token)); - getParams = new MultivaluedMapImpl(); - getParams.putSingle("search", "full:uranium"); - response = documentResource.queryParams(getParams).get(ClientResponse.class); - json = response.getEntity(JSONObject.class); - Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus())); - documents = json.getJSONArray("documents"); - Assert.assertTrue(documents.length() == 1); - - // Search documents by query in full content - documentResource = resource().path("/document/list"); - documentResource.addFilter(new CookieAuthenticationFilter(document1Token)); - getParams = new MultivaluedMapImpl(); - getParams.putSingle("search", "full:title"); - response = documentResource.queryParams(getParams).get(ClientResponse.class); - json = response.getEntity(JSONObject.class); - Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus())); - documents = json.getJSONArray("documents"); - Assert.assertTrue(documents.length() == 1); - - // Search documents by query in title/description - documentResource = resource().path("/document/list"); - documentResource.addFilter(new CookieAuthenticationFilter(document1Token)); - getParams = new MultivaluedMapImpl(); - getParams.putSingle("search", "title"); - response = documentResource.queryParams(getParams).get(ClientResponse.class); - json = response.getEntity(JSONObject.class); - Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus())); - documents = json.getJSONArray("documents"); - Assert.assertTrue(documents.length() == 1); + // Search documents + Assert.assertEquals(1, searchDocuments("full:uranium full:einstein", document1Token)); + Assert.assertEquals(1, searchDocuments("full:title", document1Token)); + Assert.assertEquals(1, searchDocuments("title", document1Token)); + Assert.assertEquals(1, searchDocuments("super description", document1Token)); + Assert.assertEquals(1, searchDocuments("at:" + DateTimeFormat.forPattern("yyyy").print(new Date().getTime()), document1Token)); + Assert.assertEquals(1, searchDocuments("at:" + DateTimeFormat.forPattern("yyyy-MM").print(new Date().getTime()), document1Token)); + Assert.assertEquals(1, searchDocuments("at:" + DateTimeFormat.forPattern("yyyy-MM-dd").print(new Date().getTime()), document1Token)); + Assert.assertEquals(1, searchDocuments("after:2010 before:2040-08", document1Token)); + Assert.assertEquals(1, searchDocuments("tag:super", document1Token)); + Assert.assertEquals(1, searchDocuments("shared:yes", document1Token)); + Assert.assertEquals(1, searchDocuments("lang:eng", document1Token)); + Assert.assertEquals(1, searchDocuments("after:2010 before:2040-08 tag:super shared:yes lang:eng title description full:uranium", document1Token)); - // Search documents by query in title/description - documentResource = resource().path("/document/list"); - documentResource.addFilter(new CookieAuthenticationFilter(document1Token)); - getParams = new MultivaluedMapImpl(); - getParams.putSingle("search", "description"); - response = documentResource.queryParams(getParams).get(ClientResponse.class); - json = response.getEntity(JSONObject.class); - Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus())); - documents = json.getJSONArray("documents"); - Assert.assertTrue(documents.length() == 1); - - // Search documents by specific date - documentResource = resource().path("/document/list"); - documentResource.addFilter(new CookieAuthenticationFilter(document1Token)); - getParams = new MultivaluedMapImpl(); - getParams.putSingle("search", "at:" + DateTimeFormat.forPattern("yyyy-MM").print(new Date().getTime())); - response = documentResource.queryParams(getParams).get(ClientResponse.class); - json = response.getEntity(JSONObject.class); - Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus())); - documents = json.getJSONArray("documents"); - Assert.assertTrue(documents.length() == 1); - Assert.assertEquals(document1Id, documents.getJSONObject(0).getString("id")); - - // Search documents by date span - documentResource = resource().path("/document/list"); - documentResource.addFilter(new CookieAuthenticationFilter(document1Token)); - getParams = new MultivaluedMapImpl(); - getParams.putSingle("search", "after:2010 before:2040-08"); - response = documentResource.queryParams(getParams).get(ClientResponse.class); - json = response.getEntity(JSONObject.class); - Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus())); - documents = json.getJSONArray("documents"); - Assert.assertTrue(documents.length() == 1); - Assert.assertEquals(document1Id, documents.getJSONObject(0).getString("id")); - - // Search documents by tag - documentResource = resource().path("/document/list"); - documentResource.addFilter(new CookieAuthenticationFilter(document1Token)); - getParams = new MultivaluedMapImpl(); - getParams.putSingle("search", "tag:super"); - response = documentResource.queryParams(getParams).get(ClientResponse.class); - json = response.getEntity(JSONObject.class); - Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus())); - documents = json.getJSONArray("documents"); - Assert.assertTrue(documents.length() == 1); - Assert.assertEquals(document1Id, documents.getJSONObject(0).getString("id")); - - // Search documents by shared status - documentResource = resource().path("/document/list"); - documentResource.addFilter(new CookieAuthenticationFilter(document1Token)); - getParams = new MultivaluedMapImpl(); - getParams.putSingle("search", "shared:yes"); - response = documentResource.queryParams(getParams).get(ClientResponse.class); - json = response.getEntity(JSONObject.class); - Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus())); - documents = json.getJSONArray("documents"); - Assert.assertTrue(documents.length() == 1); - Assert.assertEquals(document1Id, documents.getJSONObject(0).getString("id")); - Assert.assertEquals(true, documents.getJSONObject(0).getBoolean("shared")); - - // Search documents by language - documentResource = resource().path("/document/list"); - documentResource.addFilter(new CookieAuthenticationFilter(document1Token)); - getParams = new MultivaluedMapImpl(); - getParams.putSingle("search", "lang:eng"); - response = documentResource.queryParams(getParams).get(ClientResponse.class); - json = response.getEntity(JSONObject.class); - Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus())); - documents = json.getJSONArray("documents"); - Assert.assertTrue(documents.length() == 1); - Assert.assertEquals(document1Id, documents.getJSONObject(0).getString("id")); - Assert.assertEquals("eng", documents.getJSONObject(0).getString("language")); - - // Search documents with multiple criteria - documentResource = resource().path("/document/list"); - documentResource.addFilter(new CookieAuthenticationFilter(document1Token)); - getParams = new MultivaluedMapImpl(); - getParams.putSingle("search", "after:2010 before:2040-08 tag:super shared:yes lang:eng title description full:uranium"); - response = documentResource.queryParams(getParams).get(ClientResponse.class); - json = response.getEntity(JSONObject.class); - Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus())); - documents = json.getJSONArray("documents"); - Assert.assertTrue(documents.length() == 1); - Assert.assertEquals(document1Id, documents.getJSONObject(0).getString("id")); - // Search documents (nothing) - documentResource = resource().path("/document/list"); - documentResource.addFilter(new CookieAuthenticationFilter(document1Token)); - getParams = new MultivaluedMapImpl(); - getParams.putSingle("search", "random"); - response = documentResource.queryParams(getParams).get(ClientResponse.class); - json = response.getEntity(JSONObject.class); - Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus())); - documents = json.getJSONArray("documents"); - Assert.assertTrue(documents.length() == 0); - - // Search documents (nothing) - documentResource = resource().path("/document/list"); - documentResource.addFilter(new CookieAuthenticationFilter(document1Token)); - getParams = new MultivaluedMapImpl(); - getParams.putSingle("search", "full:random"); - response = documentResource.queryParams(getParams).get(ClientResponse.class); - json = response.getEntity(JSONObject.class); - Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus())); - documents = json.getJSONArray("documents"); - Assert.assertTrue(documents.length() == 0); - - // Search documents (nothing) - documentResource = resource().path("/document/list"); - documentResource.addFilter(new CookieAuthenticationFilter(document1Token)); - getParams = new MultivaluedMapImpl(); - getParams.putSingle("search", "after:2010 before:2011-05-20"); - response = documentResource.queryParams(getParams).get(ClientResponse.class); - json = response.getEntity(JSONObject.class); - Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus())); - documents = json.getJSONArray("documents"); - Assert.assertTrue(documents.length() == 0); - - // Search documents (nothing) - documentResource = resource().path("/document/list"); - documentResource.addFilter(new CookieAuthenticationFilter(document1Token)); - getParams = new MultivaluedMapImpl(); - getParams.putSingle("search", "tag:Nop"); - response = documentResource.queryParams(getParams).get(ClientResponse.class); - json = response.getEntity(JSONObject.class); - Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus())); - documents = json.getJSONArray("documents"); - Assert.assertTrue(documents.length() == 0); - - // Search documents (nothing) - documentResource = resource().path("/document/list"); - documentResource.addFilter(new CookieAuthenticationFilter(document1Token)); - getParams = new MultivaluedMapImpl(); - getParams.putSingle("search", "lang:fra"); - response = documentResource.queryParams(getParams).get(ClientResponse.class); - json = response.getEntity(JSONObject.class); - Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus())); - documents = json.getJSONArray("documents"); - Assert.assertTrue(documents.length() == 0); - + Assert.assertEquals(0, searchDocuments("random", document1Token)); + Assert.assertEquals(0, searchDocuments("full:random", document1Token)); + Assert.assertEquals(0, searchDocuments("after:2010 before:2011-05-20", document1Token)); + Assert.assertEquals(0, searchDocuments("at:2040-05-35", document1Token)); + Assert.assertEquals(0, searchDocuments("after:2010-18 before:2040-05-38", document1Token)); + Assert.assertEquals(0, searchDocuments("after:2010-18", document1Token)); + Assert.assertEquals(0, searchDocuments("before:2040-05-38", document1Token)); + Assert.assertEquals(0, searchDocuments("tag:Nop", document1Token)); + Assert.assertEquals(0, searchDocuments("lang:fra", document1Token)); + // Get a document documentResource = resource().path("/document/" + document1Id); documentResource.addFilter(new CookieAuthenticationFilter(document1Token)); @@ -348,6 +201,14 @@ public class TestDocumentResource extends BaseJerseyTest { json = response.getEntity(JSONObject.class); Assert.assertEquals("ok", json.getString("status")); + // Check that the associated files are deleted from FS + java.io.File storedFile = Paths.get(DirectoryUtil.getStorageDirectory().getPath(), file1Id).toFile(); + java.io.File webFile = Paths.get(DirectoryUtil.getStorageDirectory().getPath(), file1Id + "_web").toFile(); + java.io.File thumbnailFile = Paths.get(DirectoryUtil.getStorageDirectory().getPath(), file1Id + "_thumb").toFile(); + Assert.assertFalse(storedFile.exists()); + Assert.assertFalse(webFile.exists()); + Assert.assertFalse(thumbnailFile.exists()); + // Get a document (KO) documentResource = resource().path("/document/" + document1Id); documentResource.addFilter(new CookieAuthenticationFilter(document1Token)); @@ -356,6 +217,25 @@ public class TestDocumentResource extends BaseJerseyTest { Assert.assertEquals(Status.BAD_REQUEST, Status.fromStatusCode(response.getStatus())); } + /** + * Search documents and returns the number found. + * + * @param query Search query + * @param token Authentication token + * @return Number of documents found + * @throws Exception + */ + private int searchDocuments(String query, String token) throws Exception { + WebResource documentResource = resource().path("/document/list"); + documentResource.addFilter(new CookieAuthenticationFilter(token)); + MultivaluedMapImpl getParams = new MultivaluedMapImpl(); + getParams.putSingle("search", query); + ClientResponse response = documentResource.queryParams(getParams).get(ClientResponse.class); + JSONObject json = response.getEntity(JSONObject.class); + Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus())); + return json.getJSONArray("documents").length(); + } + /** * Test PDF extraction. *