mirror of
https://github.com/sismics/docs.git
synced 2024-11-21 21:47:57 +01:00
Unified documents search, tag validation
This commit is contained in:
parent
b4e58212f0
commit
988f55de3f
@ -155,12 +155,12 @@ public class TagDao {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a tag by user ID and name.
|
* Returns a tag by name.
|
||||||
* @param userId User ID
|
* @param userId User ID
|
||||||
* @param name Name
|
* @param name Name
|
||||||
* @return Tag
|
* @return Tag
|
||||||
*/
|
*/
|
||||||
public Tag getByUserIdAndName(String userId, String name) {
|
public Tag getByName(String userId, String name) {
|
||||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||||
Query q = em.createQuery("select t from Tag t where t.name = :name and t.userId = :userId and t.deleteDate is null");
|
Query q = em.createQuery("select t from Tag t where t.name = :name and t.userId = :userId and t.deleteDate is null");
|
||||||
q.setParameter("userId", userId);
|
q.setParameter("userId", userId);
|
||||||
@ -173,12 +173,12 @@ public class TagDao {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a tag by user ID and name.
|
* Returns a tag by ID.
|
||||||
* @param userId User ID
|
* @param userId User ID
|
||||||
* @param tagId Tag ID
|
* @param tagId Tag ID
|
||||||
* @return Tag
|
* @return Tag
|
||||||
*/
|
*/
|
||||||
public Tag getByUserIdAndTagId(String userId, String tagId) {
|
public Tag getByTagId(String userId, String tagId) {
|
||||||
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||||
Query q = em.createQuery("select t from Tag t where t.id = :tagId and t.userId = :userId and t.deleteDate is null");
|
Query q = em.createQuery("select t from Tag t where t.id = :tagId and t.userId = :userId and t.deleteDate is null");
|
||||||
q.setParameter("userId", userId);
|
q.setParameter("userId", userId);
|
||||||
@ -212,4 +212,19 @@ public class TagDao {
|
|||||||
q.setParameter("tagId", tagId);
|
q.setParameter("tagId", tagId);
|
||||||
q.executeUpdate();
|
q.executeUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search tags by name.
|
||||||
|
*
|
||||||
|
* @param name Tag name
|
||||||
|
* @return List of found tags
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public List<Tag> findByName(String userId, String name) {
|
||||||
|
EntityManager em = ThreadLocalContext.get().getEntityManager();
|
||||||
|
Query q = em.createQuery("select t from Tag t where t.name like :name and t.userId = :userId and t.deleteDate is null");
|
||||||
|
q.setParameter("userId", userId);
|
||||||
|
q.setParameter("name", "%" + name + "%");
|
||||||
|
return q.getResultList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,2 +1 @@
|
|||||||
- Remove advanced search form and put it in an unified search field (eg. tag:assurance tag:other before:2012 after:2011-09 shared:yes thing) (client/server)
|
- Loading feedback for document (list), document.view, tag.default
|
||||||
- Loading feedback for document (list), document.view, tag.default
|
|
||||||
|
@ -6,6 +6,7 @@ import java.util.Date;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import javax.persistence.NoResultException;
|
import javax.persistence.NoResultException;
|
||||||
import javax.ws.rs.DELETE;
|
import javax.ws.rs.DELETE;
|
||||||
@ -23,6 +24,11 @@ import javax.ws.rs.core.Response;
|
|||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.codehaus.jettison.json.JSONException;
|
import org.codehaus.jettison.json.JSONException;
|
||||||
import org.codehaus.jettison.json.JSONObject;
|
import org.codehaus.jettison.json.JSONObject;
|
||||||
|
import org.joda.time.DateTime;
|
||||||
|
import org.joda.time.format.DateTimeFormat;
|
||||||
|
import org.joda.time.format.DateTimeFormatter;
|
||||||
|
import org.joda.time.format.DateTimeFormatterBuilder;
|
||||||
|
import org.joda.time.format.DateTimeParser;
|
||||||
|
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import com.sismics.docs.core.dao.jpa.DocumentDao;
|
import com.sismics.docs.core.dao.jpa.DocumentDao;
|
||||||
@ -126,19 +132,11 @@ public class DocumentResource extends BaseResource {
|
|||||||
@QueryParam("offset") Integer offset,
|
@QueryParam("offset") Integer offset,
|
||||||
@QueryParam("sort_column") Integer sortColumn,
|
@QueryParam("sort_column") Integer sortColumn,
|
||||||
@QueryParam("asc") Boolean asc,
|
@QueryParam("asc") Boolean asc,
|
||||||
@QueryParam("search") String search,
|
@QueryParam("search") String search) throws JSONException {
|
||||||
@QueryParam("create_date_min") String createDateMinStr,
|
|
||||||
@QueryParam("create_date_max") String createDateMaxStr,
|
|
||||||
@QueryParam("tags") List<String> tagIdList,
|
|
||||||
@QueryParam("shared") Boolean shared) throws JSONException {
|
|
||||||
if (!authenticate()) {
|
if (!authenticate()) {
|
||||||
throw new ForbiddenClientException();
|
throw new ForbiddenClientException();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate input data
|
|
||||||
Date createDateMin = ValidationUtil.validateDate(createDateMinStr, "create_date_min", true);
|
|
||||||
Date createDateMax = ValidationUtil.validateDate(createDateMaxStr, "create_date_max", true);
|
|
||||||
|
|
||||||
JSONObject response = new JSONObject();
|
JSONObject response = new JSONObject();
|
||||||
List<JSONObject> documents = new ArrayList<>();
|
List<JSONObject> documents = new ArrayList<>();
|
||||||
|
|
||||||
@ -146,15 +144,8 @@ public class DocumentResource extends BaseResource {
|
|||||||
TagDao tagDao = new TagDao();
|
TagDao tagDao = new TagDao();
|
||||||
PaginatedList<DocumentDto> paginatedList = PaginatedLists.create(limit, offset);
|
PaginatedList<DocumentDto> paginatedList = PaginatedLists.create(limit, offset);
|
||||||
SortCriteria sortCriteria = new SortCriteria(sortColumn, asc);
|
SortCriteria sortCriteria = new SortCriteria(sortColumn, asc);
|
||||||
DocumentCriteria documentCriteria = new DocumentCriteria();
|
DocumentCriteria documentCriteria = parseSearchQuery(search);
|
||||||
documentCriteria.setUserId(principal.getId());
|
documentCriteria.setUserId(principal.getId());
|
||||||
documentCriteria.setCreateDateMin(createDateMin);
|
|
||||||
documentCriteria.setCreateDateMax(createDateMax);
|
|
||||||
documentCriteria.setTagIdList(tagIdList);
|
|
||||||
documentCriteria.setShared(shared);
|
|
||||||
if (!Strings.isNullOrEmpty(search)) {
|
|
||||||
documentCriteria.setSearch(search);
|
|
||||||
}
|
|
||||||
documentDao.findByCriteria(paginatedList, documentCriteria, sortCriteria);
|
documentDao.findByCriteria(paginatedList, documentCriteria, sortCriteria);
|
||||||
|
|
||||||
for (DocumentDto documentDto : paginatedList.getResultList()) {
|
for (DocumentDto documentDto : paginatedList.getResultList()) {
|
||||||
@ -185,6 +176,72 @@ public class DocumentResource extends BaseResource {
|
|||||||
return Response.ok().entity(response).build();
|
return Response.ok().entity(response).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a query according to the specified syntax, eg.:
|
||||||
|
* tag:assurance tag:other before:2012 after:2011-09 shared:yes thing
|
||||||
|
*
|
||||||
|
* @param search Search query
|
||||||
|
* @return DocumentCriteria
|
||||||
|
*/
|
||||||
|
private DocumentCriteria parseSearchQuery(String search) {
|
||||||
|
DocumentCriteria documentCriteria = new DocumentCriteria();
|
||||||
|
if (Strings.isNullOrEmpty(search)) {
|
||||||
|
return documentCriteria;
|
||||||
|
}
|
||||||
|
|
||||||
|
TagDao tagDao = new TagDao();
|
||||||
|
DateTimeParser[] parsers = {
|
||||||
|
DateTimeFormat.forPattern("yyyy").getParser(),
|
||||||
|
DateTimeFormat.forPattern("yyyy-MM").getParser(),
|
||||||
|
DateTimeFormat.forPattern("yyyy-MM-dd").getParser() };
|
||||||
|
DateTimeFormatter formatter = new DateTimeFormatterBuilder().append( null, parsers ).toFormatter();
|
||||||
|
|
||||||
|
String[] criteriaList = search.split(" *");
|
||||||
|
StringBuilder query = new StringBuilder();
|
||||||
|
for (String criteria : criteriaList) {
|
||||||
|
String[] params = criteria.split(":");
|
||||||
|
if (params.length != 2 || Strings.isNullOrEmpty(params[0]) || Strings.isNullOrEmpty(params[1])) {
|
||||||
|
// This is not a special criteria
|
||||||
|
query.append(criteria);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params[0].equals("tag")) {
|
||||||
|
// New tag criteria
|
||||||
|
List<Tag> tagList = tagDao.findByName(principal.getId(), params[1]);
|
||||||
|
if (documentCriteria.getTagIdList() == null) {
|
||||||
|
documentCriteria.setTagIdList(new ArrayList<String>());
|
||||||
|
}
|
||||||
|
if (tagList.size() == 0) {
|
||||||
|
// No tag found, the request must returns nothing
|
||||||
|
documentCriteria.getTagIdList().add(UUID.randomUUID().toString());
|
||||||
|
}
|
||||||
|
for (Tag tag : tagList) {
|
||||||
|
documentCriteria.getTagIdList().add(tag.getId());
|
||||||
|
}
|
||||||
|
} else if (params[0].equals("after") || params[0].equals("before")) {
|
||||||
|
// New date criteria
|
||||||
|
try {
|
||||||
|
DateTime date = formatter.parseDateTime(params[1]);
|
||||||
|
if (params[0].equals("before")) documentCriteria.setCreateDateMax(date.toDate());
|
||||||
|
else documentCriteria.setCreateDateMin(date.toDate());
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
// NOP
|
||||||
|
}
|
||||||
|
} else if (params[0].equals("shared")) {
|
||||||
|
// New shared state criteria
|
||||||
|
if (params[1].equals("yes")) {
|
||||||
|
documentCriteria.setShared(true);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
query.append(criteria);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
documentCriteria.setSearch(query.toString());
|
||||||
|
return documentCriteria;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new document.
|
* Creates a new document.
|
||||||
*
|
*
|
||||||
|
@ -103,9 +103,14 @@ public class TagResource extends BaseResource {
|
|||||||
name = ValidationUtil.validateLength(name, "name", 1, 36, false);
|
name = ValidationUtil.validateLength(name, "name", 1, 36, false);
|
||||||
ValidationUtil.validateHexColor(color, "color", true);
|
ValidationUtil.validateHexColor(color, "color", true);
|
||||||
|
|
||||||
|
// Don't allow spaces
|
||||||
|
if (name.contains(" ")) {
|
||||||
|
throw new ClientException("SpacesNotAllowed", "Spaces are not allowed in tag name");
|
||||||
|
}
|
||||||
|
|
||||||
// Get the tag
|
// Get the tag
|
||||||
TagDao tagDao = new TagDao();
|
TagDao tagDao = new TagDao();
|
||||||
Tag tag = tagDao.getByUserIdAndName(principal.getId(), name);
|
Tag tag = tagDao.getByName(principal.getId(), name);
|
||||||
if (tag != null) {
|
if (tag != null) {
|
||||||
throw new ClientException("AlreadyExistingTag", MessageFormat.format("Tag already exists: {0}", name));
|
throw new ClientException("AlreadyExistingTag", MessageFormat.format("Tag already exists: {0}", name));
|
||||||
}
|
}
|
||||||
@ -144,13 +149,24 @@ public class TagResource extends BaseResource {
|
|||||||
name = ValidationUtil.validateLength(name, "name", 1, 36, true);
|
name = ValidationUtil.validateLength(name, "name", 1, 36, true);
|
||||||
ValidationUtil.validateHexColor(color, "color", true);
|
ValidationUtil.validateHexColor(color, "color", true);
|
||||||
|
|
||||||
|
// Don't allow spaces
|
||||||
|
if (name.contains(" ")) {
|
||||||
|
throw new ClientException("SpacesNotAllowed", "Spaces are not allowed in tag name");
|
||||||
|
}
|
||||||
|
|
||||||
// Get the tag
|
// Get the tag
|
||||||
TagDao tagDao = new TagDao();
|
TagDao tagDao = new TagDao();
|
||||||
Tag tag = tagDao.getByUserIdAndTagId(principal.getId(), id);
|
Tag tag = tagDao.getByTagId(principal.getId(), id);
|
||||||
if (tag == null) {
|
if (tag == null) {
|
||||||
throw new ClientException("TagNotFound", MessageFormat.format("Tag not found: {0}", id));
|
throw new ClientException("TagNotFound", MessageFormat.format("Tag not found: {0}", id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for name duplicate
|
||||||
|
Tag tagDuplicate = tagDao.getByName(principal.getId(), name);
|
||||||
|
if (tagDuplicate != null && !tagDuplicate.getId().equals(id)) {
|
||||||
|
throw new ClientException("AlreadyExistingTag", MessageFormat.format("Tag already exists: {0}", name));
|
||||||
|
}
|
||||||
|
|
||||||
// Update the tag
|
// Update the tag
|
||||||
if (!StringUtils.isEmpty(name)) {
|
if (!StringUtils.isEmpty(name)) {
|
||||||
tag.setName(name);
|
tag.setName(name);
|
||||||
@ -182,7 +198,7 @@ public class TagResource extends BaseResource {
|
|||||||
|
|
||||||
// Get the tag
|
// Get the tag
|
||||||
TagDao tagDao = new TagDao();
|
TagDao tagDao = new TagDao();
|
||||||
Tag tag = tagDao.getByUserIdAndTagId(principal.getId(), tagId);
|
Tag tag = tagDao.getByTagId(principal.getId(), tagId);
|
||||||
if (tag == null) {
|
if (tag == null) {
|
||||||
throw new ClientException("TagNotFound", MessageFormat.format("Tag not found: {0}", tagId));
|
throw new ClientException("TagNotFound", MessageFormat.format("Tag not found: {0}", tagId));
|
||||||
}
|
}
|
||||||
|
@ -12,21 +12,7 @@ App.controller('Document', function($scope, $state, Restangular) {
|
|||||||
$scope.offset = 0;
|
$scope.offset = 0;
|
||||||
$scope.currentPage = 1;
|
$scope.currentPage = 1;
|
||||||
$scope.limit = 10;
|
$scope.limit = 10;
|
||||||
$scope.isAdvancedSearchCollapsed = true;
|
$scope.search = '';
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialize search criterias.
|
|
||||||
*/
|
|
||||||
$scope.initSearch = function() {
|
|
||||||
$scope.search = {
|
|
||||||
query: '',
|
|
||||||
createDateMin: null,
|
|
||||||
createDateMax: null,
|
|
||||||
tags: [],
|
|
||||||
shared: false
|
|
||||||
};
|
|
||||||
};
|
|
||||||
$scope.initSearch();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load new documents page.
|
* Load new documents page.
|
||||||
@ -38,11 +24,7 @@ App.controller('Document', function($scope, $state, Restangular) {
|
|||||||
limit: $scope.limit,
|
limit: $scope.limit,
|
||||||
sort_column: $scope.sortColumn,
|
sort_column: $scope.sortColumn,
|
||||||
asc: $scope.asc,
|
asc: $scope.asc,
|
||||||
search: $scope.search.query,
|
search: $scope.search
|
||||||
create_date_min: $scope.isAdvancedSearchCollapsed || !$scope.search.createDateMin ? null : $scope.search.createDateMin.getTime(),
|
|
||||||
create_date_max: $scope.isAdvancedSearchCollapsed || !$scope.search.createDateMax ? null : $scope.search.createDateMax.getTime(),
|
|
||||||
'tags': $scope.isAdvancedSearchCollapsed ? null : _.pluck($scope.search.tags, 'id'),
|
|
||||||
'shared': $scope.isAdvancedSearchCollapsed ? null : $scope.search.shared
|
|
||||||
})
|
})
|
||||||
.then(function(data) {
|
.then(function(data) {
|
||||||
$scope.documents = data.documents;
|
$scope.documents = data.documents;
|
||||||
|
@ -95,7 +95,6 @@ App.controller('DocumentView', function ($scope, $state, $stateParams, $location
|
|||||||
*/
|
*/
|
||||||
$scope.share = function () {
|
$scope.share = function () {
|
||||||
$dialog.dialog({
|
$dialog.dialog({
|
||||||
backdrop: false,
|
|
||||||
keyboard: true,
|
keyboard: true,
|
||||||
templateUrl: 'partial/docs/document.share.html',
|
templateUrl: 'partial/docs/document.share.html',
|
||||||
controller: function ($scope, dialog) {
|
controller: function ($scope, dialog) {
|
||||||
|
@ -25,6 +25,15 @@ App.controller('Tag', function($scope, $dialog, $state, Tag, Restangular) {
|
|||||||
}, 0);
|
}, 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate a tag.
|
||||||
|
*/
|
||||||
|
$scope.validateTag = function(name) {
|
||||||
|
return !_.find($scope.tags, function(tag) {
|
||||||
|
return tag.name == name;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a tag.
|
* Add a tag.
|
||||||
*/
|
*/
|
||||||
@ -65,7 +74,7 @@ App.controller('Tag', function($scope, $dialog, $state, Tag, Restangular) {
|
|||||||
*/
|
*/
|
||||||
$scope.updateTag = function(tag) {
|
$scope.updateTag = function(tag) {
|
||||||
// Update the server
|
// Update the server
|
||||||
Restangular.one('tag', tag.id).post('', tag).then(function () {
|
return Restangular.one('tag', tag.id).post('', tag).then(function () {
|
||||||
// Update the stat object
|
// Update the stat object
|
||||||
var stat = _.find($scope.stats, function (t) {
|
var stat = _.find($scope.stats, function (t) {
|
||||||
return tag.id == t.id;
|
return tag.id == t.id;
|
||||||
|
@ -47,7 +47,13 @@ App.directive('inlineEdit', function() {
|
|||||||
// Invoke parent scope callback
|
// Invoke parent scope callback
|
||||||
if (scope.editCallback && scope.oldValue != el.value) {
|
if (scope.editCallback && scope.oldValue != el.value) {
|
||||||
scope.$apply(function() {
|
scope.$apply(function() {
|
||||||
scope.editCallback();
|
if (scope.value) {
|
||||||
|
scope.editCallback().then(null, function() {
|
||||||
|
scope.value = scope.oldValue;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
scope.value = scope.oldValue;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -6,42 +6,11 @@
|
|||||||
<button class="btn btn-primary" type="button" ng-click="addDocument()"><span class="icon-plus icon-white"></span> Add a document</button>
|
<button class="btn btn-primary" type="button" ng-click="addDocument()"><span class="icon-plus icon-white"></span> Add a document</button>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p class="input-prepend input-append text-center input-block-level">
|
<p class="input-prepend text-center input-block-level">
|
||||||
<span class="add-on"><span class="icon-search"></span></span>
|
<span class="add-on"><span class="icon-search"></span></span>
|
||||||
<input type="text" placeholder="Search" ng-model="search.query" />
|
<input type="text" placeholder="Search" ng-model="search" />
|
||||||
<button class="btn" ng-click="isAdvancedSearchCollapsed = !isAdvancedSearchCollapsed">More <span class="caret"></span></button>
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div collapse="isAdvancedSearchCollapsed">
|
|
||||||
<div class="well well-small">
|
|
||||||
<form class="form-horizontal">
|
|
||||||
<div class="control-group">
|
|
||||||
<label class="control-label" for="inputCreateDateMin">Creation date</label>
|
|
||||||
<div class="controls">
|
|
||||||
<input class="span5" ng-readonly="true" ng-change="loadDocuments()" type="text" id="inputCreateDateMin" datepicker-popup="yyyy-MM-dd" ng-model="search.createDateMin" starting-day="1" show-weeks="false" />
|
|
||||||
to
|
|
||||||
<input class="span5" ng-readonly="true" ng-change="loadDocuments()" type="text" id="inputCreateDateMax" datepicker-popup="yyyy-MM-dd" ng-model="search.createDateMax" starting-day="1" show-weeks="false" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="control-group">
|
|
||||||
<label class="control-label" for="inputTags">Tags</label>
|
|
||||||
<div class="controls">
|
|
||||||
<select-tag tags="search.tags" class="input-block-level" ref="inputTags" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="control-group">
|
|
||||||
<label class="control-label" for="inputShared">Shared</label>
|
|
||||||
<div class="controls">
|
|
||||||
<input type="checkbox" ng-model="search.shared" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-actions">
|
|
||||||
<button ng-click="initSearch()" class="btn btn-warning" type="submit">Reset search</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<table class="table table-striped table-hover table-documents">
|
<table class="table table-striped table-hover table-documents">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="row-fluid">
|
<div class="row-fluid">
|
||||||
<div class="span4 well text-center">
|
<div class="span4 well text-center">
|
||||||
<div class="input-prepend input-append input-block-level">
|
<form name="tagForm" novalidate>
|
||||||
<span colorpicker class="btn" data-color="#3a87ad" ng-model="tag.color" ng-style="{ 'background': tag.color }"> </span>
|
<div class="control-group input-prepend input-append input-block-level" ng-class="{ error: !tagForm.name.$valid }">
|
||||||
<input type="text" placeholder="Tag name" ng-model="tag.name" ui-keyup="{'enter':'addTag()'}">
|
<span colorpicker class="btn" data-color="#3a87ad" ng-model="tag.color" ng-style="{ 'background': tag.color }"> </span>
|
||||||
<button type="submit" class="btn btn-primary" ng-click="addTag()">Add</button>
|
<input type="text" name="name" placeholder="New tag"
|
||||||
</div>
|
ng-maxlength="36" required ng-model="tag.name" ui-validate="'validateTag($value)'">
|
||||||
|
<button type="submit" class="btn btn-primary" ng-disabled="!tagForm.$valid" ng-click="addTag()">Add</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
<div class="input-prepend input-block-level">
|
<div class="input-prepend input-block-level">
|
||||||
<span class="add-on"><span class="icon-search"></span></span>
|
<span class="add-on"><span class="icon-search"></span></span>
|
||||||
|
@ -35,7 +35,7 @@ public class TestDocumentResource extends BaseJerseyTest {
|
|||||||
WebResource tagResource = resource().path("/tag");
|
WebResource tagResource = resource().path("/tag");
|
||||||
tagResource.addFilter(new CookieAuthenticationFilter(document1Token));
|
tagResource.addFilter(new CookieAuthenticationFilter(document1Token));
|
||||||
MultivaluedMapImpl postParams = new MultivaluedMapImpl();
|
MultivaluedMapImpl postParams = new MultivaluedMapImpl();
|
||||||
postParams.add("name", "Super tag");
|
postParams.add("name", "SuperTag");
|
||||||
postParams.add("color", "#ffff00");
|
postParams.add("color", "#ffff00");
|
||||||
ClientResponse response = tagResource.put(ClientResponse.class, postParams);
|
ClientResponse response = tagResource.put(ClientResponse.class, postParams);
|
||||||
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
||||||
@ -82,7 +82,7 @@ public class TestDocumentResource extends BaseJerseyTest {
|
|||||||
Assert.assertEquals(document1Id, documents.getJSONObject(0).getString("id"));
|
Assert.assertEquals(document1Id, documents.getJSONObject(0).getString("id"));
|
||||||
Assert.assertEquals(1, tags.length());
|
Assert.assertEquals(1, tags.length());
|
||||||
Assert.assertEquals(tag1Id, tags.getJSONObject(0).getString("id"));
|
Assert.assertEquals(tag1Id, tags.getJSONObject(0).getString("id"));
|
||||||
Assert.assertEquals("Super tag", tags.getJSONObject(0).getString("name"));
|
Assert.assertEquals("SuperTag", tags.getJSONObject(0).getString("name"));
|
||||||
Assert.assertEquals("#ffff00", tags.getJSONObject(0).getString("color"));
|
Assert.assertEquals("#ffff00", tags.getJSONObject(0).getString("color"));
|
||||||
|
|
||||||
// Search documents by query
|
// Search documents by query
|
||||||
@ -102,8 +102,7 @@ public class TestDocumentResource extends BaseJerseyTest {
|
|||||||
documentResource = resource().path("/document/list");
|
documentResource = resource().path("/document/list");
|
||||||
documentResource.addFilter(new CookieAuthenticationFilter(document1Token));
|
documentResource.addFilter(new CookieAuthenticationFilter(document1Token));
|
||||||
getParams = new MultivaluedMapImpl();
|
getParams = new MultivaluedMapImpl();
|
||||||
getParams.putSingle("create_date_min", create1Date - 3600000);
|
getParams.putSingle("search", "after:2010 before:2040-08");
|
||||||
getParams.putSingle("create_date_max", create1Date + 1800000);
|
|
||||||
response = documentResource.queryParams(getParams).get(ClientResponse.class);
|
response = documentResource.queryParams(getParams).get(ClientResponse.class);
|
||||||
json = response.getEntity(JSONObject.class);
|
json = response.getEntity(JSONObject.class);
|
||||||
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
||||||
@ -115,7 +114,7 @@ public class TestDocumentResource extends BaseJerseyTest {
|
|||||||
documentResource = resource().path("/document/list");
|
documentResource = resource().path("/document/list");
|
||||||
documentResource.addFilter(new CookieAuthenticationFilter(document1Token));
|
documentResource.addFilter(new CookieAuthenticationFilter(document1Token));
|
||||||
getParams = new MultivaluedMapImpl();
|
getParams = new MultivaluedMapImpl();
|
||||||
getParams.putSingle("tags", tag1Id);
|
getParams.putSingle("search", "tag:super");
|
||||||
response = documentResource.queryParams(getParams).get(ClientResponse.class);
|
response = documentResource.queryParams(getParams).get(ClientResponse.class);
|
||||||
json = response.getEntity(JSONObject.class);
|
json = response.getEntity(JSONObject.class);
|
||||||
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
||||||
@ -127,7 +126,20 @@ public class TestDocumentResource extends BaseJerseyTest {
|
|||||||
documentResource = resource().path("/document/list");
|
documentResource = resource().path("/document/list");
|
||||||
documentResource.addFilter(new CookieAuthenticationFilter(document1Token));
|
documentResource.addFilter(new CookieAuthenticationFilter(document1Token));
|
||||||
getParams = new MultivaluedMapImpl();
|
getParams = new MultivaluedMapImpl();
|
||||||
getParams.putSingle("shared", true);
|
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 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 for");
|
||||||
response = documentResource.queryParams(getParams).get(ClientResponse.class);
|
response = documentResource.queryParams(getParams).get(ClientResponse.class);
|
||||||
json = response.getEntity(JSONObject.class);
|
json = response.getEntity(JSONObject.class);
|
||||||
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
||||||
@ -147,6 +159,28 @@ public class TestDocumentResource extends BaseJerseyTest {
|
|||||||
documents = json.getJSONArray("documents");
|
documents = json.getJSONArray("documents");
|
||||||
Assert.assertTrue(documents.length() == 0);
|
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);
|
||||||
|
|
||||||
// Get a document
|
// Get a document
|
||||||
documentResource = resource().path("/document/" + document1Id);
|
documentResource = resource().path("/document/" + document1Id);
|
||||||
documentResource.addFilter(new CookieAuthenticationFilter(document1Token));
|
documentResource.addFilter(new CookieAuthenticationFilter(document1Token));
|
||||||
@ -162,7 +196,7 @@ public class TestDocumentResource extends BaseJerseyTest {
|
|||||||
tagResource = resource().path("/tag");
|
tagResource = resource().path("/tag");
|
||||||
tagResource.addFilter(new CookieAuthenticationFilter(document1Token));
|
tagResource.addFilter(new CookieAuthenticationFilter(document1Token));
|
||||||
postParams = new MultivaluedMapImpl();
|
postParams = new MultivaluedMapImpl();
|
||||||
postParams.add("name", "Super tag 2");
|
postParams.add("name", "SuperTag2");
|
||||||
postParams.add("color", "#00ffff");
|
postParams.add("color", "#00ffff");
|
||||||
response = tagResource.put(ClientResponse.class, postParams);
|
response = tagResource.put(ClientResponse.class, postParams);
|
||||||
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
||||||
|
@ -32,7 +32,7 @@ public class TestTagResource extends BaseJerseyTest {
|
|||||||
WebResource tagResource = resource().path("/tag");
|
WebResource tagResource = resource().path("/tag");
|
||||||
tagResource.addFilter(new CookieAuthenticationFilter(tag1Token));
|
tagResource.addFilter(new CookieAuthenticationFilter(tag1Token));
|
||||||
MultivaluedMapImpl postParams = new MultivaluedMapImpl();
|
MultivaluedMapImpl postParams = new MultivaluedMapImpl();
|
||||||
postParams.add("name", "Tag 3");
|
postParams.add("name", "Tag3");
|
||||||
postParams.add("color", "#ff0000");
|
postParams.add("color", "#ff0000");
|
||||||
ClientResponse response = tagResource.put(ClientResponse.class, postParams);
|
ClientResponse response = tagResource.put(ClientResponse.class, postParams);
|
||||||
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
||||||
@ -44,7 +44,7 @@ public class TestTagResource extends BaseJerseyTest {
|
|||||||
tagResource = resource().path("/tag");
|
tagResource = resource().path("/tag");
|
||||||
tagResource.addFilter(new CookieAuthenticationFilter(tag1Token));
|
tagResource.addFilter(new CookieAuthenticationFilter(tag1Token));
|
||||||
postParams = new MultivaluedMapImpl();
|
postParams = new MultivaluedMapImpl();
|
||||||
postParams.add("name", "Tag 4");
|
postParams.add("name", "Tag4");
|
||||||
postParams.add("color", "#00ff00");
|
postParams.add("color", "#00ff00");
|
||||||
response = tagResource.put(ClientResponse.class, postParams);
|
response = tagResource.put(ClientResponse.class, postParams);
|
||||||
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
||||||
@ -52,6 +52,14 @@ public class TestTagResource extends BaseJerseyTest {
|
|||||||
String tag4Id = json.optString("id");
|
String tag4Id = json.optString("id");
|
||||||
Assert.assertNotNull(tag4Id);
|
Assert.assertNotNull(tag4Id);
|
||||||
|
|
||||||
|
// Create a tag with space (not allowed)
|
||||||
|
tagResource = resource().path("/tag");
|
||||||
|
tagResource.addFilter(new CookieAuthenticationFilter(tag1Token));
|
||||||
|
postParams = new MultivaluedMapImpl();
|
||||||
|
postParams.add("name", "Tag 4");
|
||||||
|
response = tagResource.put(ClientResponse.class, postParams);
|
||||||
|
Assert.assertEquals(Status.BAD_REQUEST, Status.fromStatusCode(response.getStatus()));
|
||||||
|
|
||||||
// Create a document
|
// Create a document
|
||||||
WebResource documentResource = resource().path("/document");
|
WebResource documentResource = resource().path("/document");
|
||||||
documentResource.addFilter(new CookieAuthenticationFilter(tag1Token));
|
documentResource.addFilter(new CookieAuthenticationFilter(tag1Token));
|
||||||
@ -91,14 +99,14 @@ public class TestTagResource extends BaseJerseyTest {
|
|||||||
json = response.getEntity(JSONObject.class);
|
json = response.getEntity(JSONObject.class);
|
||||||
JSONArray tags = json.getJSONArray("tags");
|
JSONArray tags = json.getJSONArray("tags");
|
||||||
Assert.assertTrue(tags.length() > 0);
|
Assert.assertTrue(tags.length() > 0);
|
||||||
Assert.assertEquals("Tag 4", tags.getJSONObject(1).getString("name"));
|
Assert.assertEquals("Tag4", tags.getJSONObject(1).getString("name"));
|
||||||
Assert.assertEquals("#00ff00", tags.getJSONObject(1).getString("color"));
|
Assert.assertEquals("#00ff00", tags.getJSONObject(1).getString("color"));
|
||||||
|
|
||||||
// Update a tag
|
// Update a tag
|
||||||
tagResource = resource().path("/tag/" + tag4Id);
|
tagResource = resource().path("/tag/" + tag4Id);
|
||||||
tagResource.addFilter(new CookieAuthenticationFilter(tag1Token));
|
tagResource.addFilter(new CookieAuthenticationFilter(tag1Token));
|
||||||
postParams = new MultivaluedMapImpl();
|
postParams = new MultivaluedMapImpl();
|
||||||
postParams.add("name", "Updated name");
|
postParams.add("name", "UpdatedName");
|
||||||
postParams.add("color", "#0000ff");
|
postParams.add("color", "#0000ff");
|
||||||
response = tagResource.post(ClientResponse.class, postParams);
|
response = tagResource.post(ClientResponse.class, postParams);
|
||||||
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
Assert.assertEquals(Status.OK, Status.fromStatusCode(response.getStatus()));
|
||||||
@ -113,7 +121,7 @@ public class TestTagResource extends BaseJerseyTest {
|
|||||||
json = response.getEntity(JSONObject.class);
|
json = response.getEntity(JSONObject.class);
|
||||||
tags = json.getJSONArray("tags");
|
tags = json.getJSONArray("tags");
|
||||||
Assert.assertTrue(tags.length() > 0);
|
Assert.assertTrue(tags.length() > 0);
|
||||||
Assert.assertEquals("Updated name", tags.getJSONObject(1).getString("name"));
|
Assert.assertEquals("UpdatedName", tags.getJSONObject(1).getString("name"));
|
||||||
Assert.assertEquals("#0000ff", tags.getJSONObject(1).getString("color"));
|
Assert.assertEquals("#0000ff", tags.getJSONObject(1).getString("color"));
|
||||||
|
|
||||||
// Deletes a tag
|
// Deletes a tag
|
||||||
|
Loading…
Reference in New Issue
Block a user