Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#28896 Creating API Level class to search Categories on the entire tree #29081

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -484,4 +484,17 @@ Category findByVariable(final String variable, final User user,
final boolean respectFrontendRoles) throws DotDataException, DotSecurityException;

List<Category> getCategoriesFromContent(final Contentlet contentlet, final User user, boolean respectFrontendRoles ) throws DotDataException, DotSecurityException;

/**
* Return a list of Categories regardless of their levels.
*
* @param searchCriteria Searching criteria
* @param user User to check Permission
* @param respectFrontendRoles true if you must respect Frontend Roles
*
* @return List of Category filtered
*/
PaginatedCategories findAll(final CategoryFactory.CategorySearchCriteria searchCriteria,
final User user, boolean respectFrontendRoles)
throws DotDataException, DotSecurityException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import com.dotmarketing.util.InodeUtils;
import com.dotmarketing.util.Logger;
import com.dotmarketing.util.UtilMethods;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import com.liferay.portal.model.User;
import java.util.ArrayList;
Expand All @@ -48,8 +49,13 @@ public class CategoryAPIImpl implements CategoryAPI {
private final PermissionAPI permissionAPI;

public CategoryAPIImpl () {
categoryFactory = FactoryLocator.getCategoryFactory();
permissionAPI = APILocator.getPermissionAPI();
this(FactoryLocator.getCategoryFactory(), APILocator.getPermissionAPI());
}

@VisibleForTesting
public CategoryAPIImpl (final CategoryFactory categoryFactory, final PermissionAPI permissionAPI) {
this.categoryFactory = categoryFactory;
this.permissionAPI = permissionAPI;
}

/**
Expand Down Expand Up @@ -943,4 +949,31 @@ private boolean hasCategoryFields(final ContentType contentType) {

}

/**
* Default implementation.
*
* @param searchCriteria Searching criteria
* @param user User to check Permission
* @param respectFrontendRoles true if you must respect Frontend Roles
*
* @return
* @throws DotDataException
* @throws DotSecurityException
*/
@CloseDBIfOpened
@Override
public PaginatedCategories findAll(final CategoryFactory.CategorySearchCriteria searchCriteria,
final User user, boolean respectFrontendRoles)
throws DotDataException, DotSecurityException {

if (searchCriteria.limit < 1) {
throw new IllegalArgumentException("Limit must be greater than 0");
}

final List<Category> categories = permissionAPI.filterCollection(categoryFactory.findAll(searchCriteria),
PermissionAPI.PERMISSION_READ, respectFrontendRoles, user);

return getCategoriesSubList(searchCriteria.offset, searchCriteria.limit, categories, null);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ public abstract class CategoryFactory {
*
* @return List of Category filtered
*/
public abstract Collection<Category> findAll(final CategorySearchCriteria searchCriteria) throws DotDataException;
public abstract List<Category> findAll(final CategorySearchCriteria searchCriteria) throws DotDataException;

/**
* Represents Search Criteria for {@link Category} searching, you cans set the follow:
Expand All @@ -304,19 +304,24 @@ public static class CategorySearchCriteria {
final String filter;
final String orderBy;
final OrderDirection direction;

final int limit;
final int offset;
private CategorySearchCriteria (final Builder builder) {
this.rootInode = builder.rootInode;
this.filter = builder.filter;
this.orderBy = builder.orderBy;
this.direction = builder.direction;
this.limit = builder.limit;
this.offset = builder.offset;
}

public static class Builder {
private String rootInode;
private String filter;
private String orderBy = "category_name";
private OrderDirection direction = OrderDirection.ASC;
private int limit = -1;
private int offset = 0;

public Builder rootInode(String rootInode) {
this.rootInode = rootInode;
Expand All @@ -338,6 +343,17 @@ public Builder direction(OrderDirection direction) {
return this;
}

public Builder limit(int limit) {
this.limit = limit;
return this;
}

public Builder offset(int offset) {
this.offset = offset;
return this;
}


public CategorySearchCriteria build() {
return new CategorySearchCriteria(this);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package com.dotmarketing.portlets.categories.business;

import static com.dotcms.util.CollectionsUtils.list;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import com.dotcms.IntegrationTestBase;
import com.dotcms.contenttype.business.ContentTypeAPIImpl;
Expand All @@ -21,6 +24,7 @@
import com.dotcms.datagen.SiteDataGen;
import com.dotcms.datagen.UserDataGen;
import com.dotcms.util.IntegrationTestInitService;
import com.dotcms.util.pagination.OrderDirection;
import com.dotmarketing.beans.Host;
import com.dotmarketing.beans.Permission;
import com.dotmarketing.business.APILocator;
Expand All @@ -45,6 +49,8 @@
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import net.bytebuddy.utility.RandomString;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
Expand Down Expand Up @@ -91,7 +97,7 @@ public void findTopLevelCategories() throws DotSecurityException, DotDataExcepti
int count = 10;//TODO: A -1 or 0 wont work in order to request all que records
String filter = null;
String sort = null;

//Test the category API
PaginatedCategories categories = categoryAPI.findTopLevelCategories(user, false, start, count, filter, sort);

Expand Down Expand Up @@ -1537,4 +1543,123 @@ public void test_save_createTopLevelCategory_asLimitedUser_fail()

categoryAPI.save(null, newCategory, limitedUser, false);
}

/**
* Method to test: {@link CategoryAPIImpl#findAll(CategoryFactory.CategorySearchCriteria, User, boolean)}
* When: Call the API method
* Should: it should
* - Use the {@link CategoryFactoryImpl#findAll(CategoryFactory.CategorySearchCriteria)} to search the {@link Category}
* - Use the {@link PermissionAPI#filterCollection(List, int, boolean, User)} method to check permission
*/
@Test
public void getAllCategoriesFiltered() throws DotDataException, DotSecurityException {
final String inode = new RandomString().nextString();
final String filter = new RandomString().nextString();
final String orderBy = "category_key";

final CategoryFactory.CategorySearchCriteria searchingCriteria =
new CategoryFactory.CategorySearchCriteria.Builder()
.rootInode(inode)
.direction(OrderDirection.DESC)
.orderBy(orderBy)
.filter(filter)
.limit(10)
.build();

final User user = mock();

final Category category1 = mock(Category.class);
final Category category2 = mock(Category.class);
final Category category3 = mock(Category.class);

final List<Category> categoriesAfterSearch = list(category1, category2, category3);
final List<Category> categoriesAfterPermission = list(category1, category2);

final CategoryFactory categoryFactory = mock();
when(categoryFactory.findAll(searchingCriteria)).thenReturn(categoriesAfterSearch);

final PermissionAPI permissionAPI = mock();
when(permissionAPI.filterCollection(categoriesAfterSearch, PermissionAPI.PERMISSION_READ, false, user))
.thenReturn(categoriesAfterPermission);

final CategoryAPI categoryAPI = new CategoryAPIImpl(categoryFactory, permissionAPI);
PaginatedCategories paginatedCategories = categoryAPI.findAll(searchingCriteria, user, false);

assertEquals(categoriesAfterPermission.size(), (int) paginatedCategories.getTotalCount());
assertTrue(categoriesAfterPermission.containsAll(paginatedCategories.getCategories()));
}

/**
* Method to test: {@link CategoryAPIImpl#findAll(CategoryFactory.CategorySearchCriteria, User, boolean)}
* When: Create 9 Category, call the two times:
* first: limit =5, offset =0
* second: limit =5, offset =5
*
* Should: Return All the Categories with the 2 called
*/
@Test
public void getAllCategoriesFilteredWithPagination() throws DotDataException, DotSecurityException {
final String inode = new RandomString().nextString();
final String filter = new RandomString().nextString();
final String orderBy = "category_key";

final CategoryFactory.CategorySearchCriteria searchingCriteria_1 =
new CategoryFactory.CategorySearchCriteria.Builder()
.rootInode(inode)
.direction(OrderDirection.DESC)
.orderBy(orderBy)
.filter(filter)
.limit(5)
.offset(0)
.build();

final CategoryFactory.CategorySearchCriteria searchingCriteria_2 =
new CategoryFactory.CategorySearchCriteria.Builder()
.rootInode(inode)
.direction(OrderDirection.DESC)
.orderBy(orderBy)
.filter(filter)
.limit(5)
.offset(5)
.build();

final Category category1 = mock(Category.class);
final Category category2 = mock(Category.class);
final Category category3 = mock(Category.class);
final Category category4 = mock(Category.class);
final Category category5 = mock(Category.class);
final Category category6 = mock(Category.class);
final Category category7 = mock(Category.class);
final Category category8 = mock(Category.class);
final Category category9 = mock(Category.class);

final User user = mock();

final List<Category> categories = list(category1, category2, category3, category4, category5, category6,
category7, category8, category9);

final CategoryFactory categoryFactory = mock();
when(categoryFactory.findAll(searchingCriteria_1)).thenReturn(categories);
when(categoryFactory.findAll(searchingCriteria_2)).thenReturn(categories);

final PermissionAPI permissionAPI = mock();
when(permissionAPI.filterCollection(categories, PermissionAPI.PERMISSION_READ, false, user))
.thenReturn(categories);



final CategoryAPI categoryAPI = new CategoryAPIImpl(categoryFactory, permissionAPI);
PaginatedCategories firstPage = categoryAPI.findAll(searchingCriteria_1, user, false);

assertEquals(9, (int) firstPage.getTotalCount());
assertEquals(5, firstPage.getCategories().size());
assertTrue(list(category1, category2, category3, category4, category5).containsAll(firstPage.getCategories()));


PaginatedCategories secondPage = categoryAPI.findAll(searchingCriteria_2, user, false);

assertEquals(9, (int) secondPage.getTotalCount());
assertEquals(4, secondPage.getCategories().size());
assertTrue(list(category6, category7, category8, category9).containsAll(secondPage.getCategories()));
}
}
Loading