mirror of
				https://github.com/Alfresco/alfresco-community-repo.git
				synced 2025-10-29 15:21:53 +00:00 
			
		
		
		
	Compare commits
	
		
			1 Commits
		
	
	
		
			20.42
			...
			rm-7187-ev
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					3875f0b170 | 
@@ -7,7 +7,7 @@
 | 
			
		||||
   <parent>
 | 
			
		||||
      <groupId>org.alfresco</groupId>
 | 
			
		||||
      <artifactId>alfresco-community-repo-amps</artifactId>
 | 
			
		||||
      <version>20.42</version>
 | 
			
		||||
      <version>20.36-SNAPSHOT</version>
 | 
			
		||||
   </parent>
 | 
			
		||||
 | 
			
		||||
   <modules>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
   <parent>
 | 
			
		||||
      <groupId>org.alfresco</groupId>
 | 
			
		||||
      <artifactId>alfresco-governance-services-community-parent</artifactId>
 | 
			
		||||
      <version>20.42</version>
 | 
			
		||||
      <version>20.36-SNAPSHOT</version>
 | 
			
		||||
   </parent>
 | 
			
		||||
 | 
			
		||||
   <modules>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
   <parent>
 | 
			
		||||
      <groupId>org.alfresco</groupId>
 | 
			
		||||
      <artifactId>alfresco-governance-services-automation-community-repo</artifactId>
 | 
			
		||||
      <version>20.42</version>
 | 
			
		||||
      <version>20.36-SNAPSHOT</version>
 | 
			
		||||
   </parent>
 | 
			
		||||
 | 
			
		||||
   <build>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
   <parent>
 | 
			
		||||
      <groupId>org.alfresco</groupId>
 | 
			
		||||
      <artifactId>alfresco-governance-services-community-parent</artifactId>
 | 
			
		||||
      <version>20.42</version>
 | 
			
		||||
      <version>20.36-SNAPSHOT</version>
 | 
			
		||||
   </parent>
 | 
			
		||||
 | 
			
		||||
   <modules>
 | 
			
		||||
 
 | 
			
		||||
@@ -175,6 +175,14 @@
 | 
			
		||||
       <property name="nodesModelFactory" ref="nodesModelFactory" />
 | 
			
		||||
    </bean>
 | 
			
		||||
 | 
			
		||||
    <bean class="org.alfresco.rm.rest.api.events.EventEntityResource">
 | 
			
		||||
        <property name="recordsManagementEventService" ref="RecordsManagementEventService" />
 | 
			
		||||
    </bean>
 | 
			
		||||
 | 
			
		||||
    <bean class="org.alfresco.rm.rest.api.events.EventTypeEntityResource">
 | 
			
		||||
        <property name="recordsManagementEventService" ref="RecordsManagementEventService" />
 | 
			
		||||
    </bean>
 | 
			
		||||
 | 
			
		||||
   <!-- extended sites bean definition -->
 | 
			
		||||
   <bean id="rm.sites" class="org.alfresco.rm.rest.api.impl.RMSitesImpl" parent="sites">
 | 
			
		||||
        <property name="siteSurfConfig" ref="rm.siteSurfConfig" />
 | 
			
		||||
@@ -209,6 +217,8 @@
 | 
			
		||||
                <entry key="org.alfresco.service.cmr.attributes.DuplicateAttributeException" value="#{T(org.springframework.extensions.webscripts.Status).STATUS_CONFLICT}" />
 | 
			
		||||
                <entry key="org.alfresco.module.org_alfresco_module_rm.record.RecordCreationException" value="422" />
 | 
			
		||||
                <entry key="org.alfresco.service.cmr.model.FileExistsException" value="409" />
 | 
			
		||||
                <entry key="org.alfresco.rest.framework.core.exceptions.EventAlreadyExistsException" value="409" />
 | 
			
		||||
                <entry key="org.alfresco.rest.framework.core.exceptions.EntityNotFoundException" value="404" />
 | 
			
		||||
            </map>
 | 
			
		||||
        </property>
 | 
			
		||||
   </bean>
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
   <parent>
 | 
			
		||||
      <groupId>org.alfresco</groupId>
 | 
			
		||||
      <artifactId>alfresco-governance-services-community-repo-parent</artifactId>
 | 
			
		||||
      <version>20.42</version>
 | 
			
		||||
      <version>20.36-SNAPSHOT</version>
 | 
			
		||||
   </parent>
 | 
			
		||||
 | 
			
		||||
   <properties>
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,222 @@
 | 
			
		||||
/*
 | 
			
		||||
 * #%L
 | 
			
		||||
 * Alfresco Records Management Module
 | 
			
		||||
 * %%
 | 
			
		||||
 * Copyright (C) 2005 - 2022 Alfresco Software Limited
 | 
			
		||||
 * %%
 | 
			
		||||
 * This file is part of the Alfresco software.
 | 
			
		||||
 * -
 | 
			
		||||
 * If the software was purchased under a paid Alfresco license, the terms of
 | 
			
		||||
 * the paid license agreement will prevail.  Otherwise, the software is
 | 
			
		||||
 * provided under the following open source license terms:
 | 
			
		||||
 * -
 | 
			
		||||
 * Alfresco is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Lesser General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * -
 | 
			
		||||
 * Alfresco is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Lesser General Public License for more details.
 | 
			
		||||
 * -
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 * #L%
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.alfresco.rm.rest.api.events;
 | 
			
		||||
 | 
			
		||||
import org.alfresco.error.AlfrescoRuntimeException;
 | 
			
		||||
import org.alfresco.module.org_alfresco_module_rm.event.RecordsManagementEvent;
 | 
			
		||||
import org.alfresco.module.org_alfresco_module_rm.event.RecordsManagementEventService;
 | 
			
		||||
import org.alfresco.rest.framework.WebApiDescription;
 | 
			
		||||
import org.alfresco.rest.framework.WebApiParam;
 | 
			
		||||
import org.alfresco.rest.framework.core.ResourceParameter;
 | 
			
		||||
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
 | 
			
		||||
import org.alfresco.rest.framework.core.exceptions.EventAlreadyExistsException;
 | 
			
		||||
import org.alfresco.rest.framework.resource.EntityResource;
 | 
			
		||||
import org.alfresco.rest.framework.resource.actions.interfaces.EntityResourceAction;
 | 
			
		||||
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
 | 
			
		||||
import org.alfresco.rest.framework.resource.parameters.Paging;
 | 
			
		||||
import org.alfresco.rest.framework.resource.parameters.Parameters;
 | 
			
		||||
import org.alfresco.rm.rest.api.model.EventBody;
 | 
			
		||||
import org.alfresco.rm.rest.api.model.EventInfo;
 | 
			
		||||
import org.alfresco.util.GUID;
 | 
			
		||||
import org.apache.commons.lang3.StringUtils;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
 | 
			
		||||
import static org.alfresco.util.ParameterCheck.mandatory;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Event entity resource
 | 
			
		||||
 */
 | 
			
		||||
@EntityResource(name = "events", title = "Events")
 | 
			
		||||
public class EventEntityResource implements EntityResourceAction.Read<EventInfo>,
 | 
			
		||||
                                            EntityResourceAction.ReadById<EventInfo>,
 | 
			
		||||
                                            EntityResourceAction.Update<EventBody>,
 | 
			
		||||
                                            EntityResourceAction.Create<EventBody> {
 | 
			
		||||
 | 
			
		||||
    private RecordsManagementEventService recordsManagementEventService;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the records management event service
 | 
			
		||||
     *
 | 
			
		||||
     * @param rmEventService
 | 
			
		||||
     */
 | 
			
		||||
    public void setRecordsManagementEventService(RecordsManagementEventService rmEventService)
 | 
			
		||||
    {
 | 
			
		||||
        this.recordsManagementEventService = rmEventService;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    @WebApiDescription(title = "Return a single event identified by 'eventId'")
 | 
			
		||||
    @WebApiParam(name = "eventId", title = "The event id", kind = ResourceParameter.KIND.URL_PATH)
 | 
			
		||||
    public EventInfo readById(String eventId, Parameters parameters) throws EntityNotFoundException
 | 
			
		||||
    {
 | 
			
		||||
        mandatory("eventId", eventId);
 | 
			
		||||
 | 
			
		||||
        RecordsManagementEvent event = null;
 | 
			
		||||
        if (eventExists(eventId))
 | 
			
		||||
        {
 | 
			
		||||
            // Get the event
 | 
			
		||||
            event = recordsManagementEventService.getEvent(eventId);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return EventInfo.fromRecordsManagementEvent(event);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    @WebApiDescription(title = "Return a list of events")
 | 
			
		||||
    public CollectionWithPagingInfo<EventInfo> readAll(Parameters params)
 | 
			
		||||
    {
 | 
			
		||||
        Paging paging = params.getPaging();
 | 
			
		||||
 | 
			
		||||
        List<EventInfo> eventInfoList = recordsManagementEventService.getEvents().stream()
 | 
			
		||||
                .map(EventInfo::fromRecordsManagementEvent)
 | 
			
		||||
                .collect(Collectors.toList());
 | 
			
		||||
 | 
			
		||||
        int totalCount = eventInfoList.size();
 | 
			
		||||
        boolean hasMoreItems = paging.getSkipCount() + paging.getMaxItems() < totalCount;
 | 
			
		||||
        return CollectionWithPagingInfo.asPaged(paging, eventInfoList.stream()
 | 
			
		||||
                .skip(paging.getSkipCount())
 | 
			
		||||
                .limit(paging.getMaxItems())
 | 
			
		||||
                .collect(Collectors.toList()), hasMoreItems, totalCount);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    @WebApiDescription(title = "Create a new event")
 | 
			
		||||
    public List<EventBody> create(List<EventBody> eventBodyList, Parameters parameters)
 | 
			
		||||
    {
 | 
			
		||||
        //TODO: 403 User not allowed to update event error still needs to be implemented
 | 
			
		||||
        mandatory("eventBodyList", eventBodyList);
 | 
			
		||||
        for (EventBody eventBody : eventBodyList) {
 | 
			
		||||
            mandatory("eventName", eventBody.getName());
 | 
			
		||||
            mandatory("eventType", eventBody.getType());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        List<EventBody> responseEventBodyList = new ArrayList<>();
 | 
			
		||||
        for (EventBody eventBody : eventBodyList) {
 | 
			
		||||
            String eventId = GUID.generate();
 | 
			
		||||
            String eventName = eventBody.getName();
 | 
			
		||||
            String eventType = eventBody.getType();
 | 
			
		||||
 | 
			
		||||
            if(canCreateEvent(eventId, eventName)) {
 | 
			
		||||
                RecordsManagementEvent event = recordsManagementEventService.addEvent(eventType, eventId, eventName);
 | 
			
		||||
                responseEventBodyList.add(EventBody.fromRecordsManagementEvent(event));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return responseEventBodyList;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    @WebApiDescription(title = "Update a single event identified by 'eventId'")
 | 
			
		||||
    @WebApiParam(name = "eventId", title = "The event id", kind = ResourceParameter.KIND.URL_PATH)
 | 
			
		||||
    public EventBody update(String eventId, EventBody eventBody, Parameters parameters)
 | 
			
		||||
    {
 | 
			
		||||
        //TODO: 403 User not allowed to update event error still needs to be implemented
 | 
			
		||||
        mandatory("eventId", eventId);
 | 
			
		||||
        mandatory("eventName", eventBody.getName());
 | 
			
		||||
        mandatory("eventType", eventBody.getType());
 | 
			
		||||
 | 
			
		||||
        RecordsManagementEvent event = null;
 | 
			
		||||
        if (canEditEvent(eventBody.getName(), eventId, eventBody.getType()))
 | 
			
		||||
        {
 | 
			
		||||
            // Create event
 | 
			
		||||
            event = recordsManagementEventService.addEvent(eventBody.getType(), eventId, eventBody.getName());
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            // Get event
 | 
			
		||||
            event = recordsManagementEventService.getEvent(eventId);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return EventBody.fromRecordsManagementEvent(event);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Helper method for checking if an event exists or not. Throws an
 | 
			
		||||
     * error if the event does not exist.
 | 
			
		||||
     *
 | 
			
		||||
     * @param eventId The id of the event
 | 
			
		||||
     */
 | 
			
		||||
    private boolean eventExists(String eventId)
 | 
			
		||||
    {
 | 
			
		||||
        boolean eventExists = true;
 | 
			
		||||
 | 
			
		||||
        // Check the event exists
 | 
			
		||||
        if (!recordsManagementEventService.existsEvent(eventId))
 | 
			
		||||
        {
 | 
			
		||||
            throw new EntityNotFoundException(eventId);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return eventExists;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Helper method for checking if an event can be created or not. Throws an
 | 
			
		||||
     * error if the event already exists.
 | 
			
		||||
     *
 | 
			
		||||
     * @param eventId The id of the event
 | 
			
		||||
     * @param eventName The name of the event
 | 
			
		||||
     */
 | 
			
		||||
    private boolean canCreateEvent(String eventId, String eventName)
 | 
			
		||||
    {
 | 
			
		||||
        boolean canCreateEvent = true;
 | 
			
		||||
 | 
			
		||||
        if (!recordsManagementEventService.canCreateEvent(eventName, eventId))
 | 
			
		||||
        {
 | 
			
		||||
            throw new EventAlreadyExistsException("framework.exception.CreateEventAlreadyExists", new Object[] {eventName});
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return canCreateEvent;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Helper method for checking if an event can be edited or not. Throws an
 | 
			
		||||
     * error if an event with the same display label already exists.
 | 
			
		||||
     *
 | 
			
		||||
     * @param eventName The name of the event
 | 
			
		||||
     * @param eventId The id of the event
 | 
			
		||||
     * @param eventType The type of the event
 | 
			
		||||
     * @return true if the event can be edited, false otherwise
 | 
			
		||||
     */
 | 
			
		||||
    private boolean canEditEvent(String eventName, String eventId, String eventType)
 | 
			
		||||
    {
 | 
			
		||||
        boolean canEditEvent = false;
 | 
			
		||||
        if (eventExists(eventId)) {
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                canEditEvent = recordsManagementEventService.canEditEvent(eventName, eventId, eventType);
 | 
			
		||||
            }
 | 
			
		||||
            catch (AlfrescoRuntimeException are)
 | 
			
		||||
            {
 | 
			
		||||
                throw new EventAlreadyExistsException("framework.exception.UpdateEventAlreadyExists", new Object[] {eventName});
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return canEditEvent;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,76 @@
 | 
			
		||||
/*
 | 
			
		||||
 * #%L
 | 
			
		||||
 * Alfresco Records Management Module
 | 
			
		||||
 * %%
 | 
			
		||||
 * Copyright (C) 2005 - 2022 Alfresco Software Limited
 | 
			
		||||
 * %%
 | 
			
		||||
 * This file is part of the Alfresco software.
 | 
			
		||||
 * -
 | 
			
		||||
 * If the software was purchased under a paid Alfresco license, the terms of
 | 
			
		||||
 * the paid license agreement will prevail.  Otherwise, the software is
 | 
			
		||||
 * provided under the following open source license terms:
 | 
			
		||||
 * -
 | 
			
		||||
 * Alfresco is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Lesser General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * -
 | 
			
		||||
 * Alfresco is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Lesser General Public License for more details.
 | 
			
		||||
 * -
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 * #L%
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.alfresco.rm.rest.api.events;
 | 
			
		||||
 | 
			
		||||
import org.alfresco.module.org_alfresco_module_rm.event.RecordsManagementEventService;
 | 
			
		||||
import org.alfresco.rest.framework.WebApiDescription;
 | 
			
		||||
import org.alfresco.rest.framework.resource.EntityResource;
 | 
			
		||||
import org.alfresco.rest.framework.resource.actions.interfaces.EntityResourceAction;
 | 
			
		||||
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
 | 
			
		||||
import org.alfresco.rest.framework.resource.parameters.Paging;
 | 
			
		||||
import org.alfresco.rest.framework.resource.parameters.Parameters;
 | 
			
		||||
import org.alfresco.rm.rest.api.model.EventTypeInfo;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Event Type entity resource
 | 
			
		||||
 */
 | 
			
		||||
@EntityResource(name = "event-types", title = "Event Types")
 | 
			
		||||
public class EventTypeEntityResource implements EntityResourceAction.Read<EventTypeInfo> {
 | 
			
		||||
    private RecordsManagementEventService recordsManagementEventService;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the records management event service
 | 
			
		||||
     * @param rmEventService
 | 
			
		||||
     */
 | 
			
		||||
    public void setRecordsManagementEventService(RecordsManagementEventService rmEventService)
 | 
			
		||||
    {
 | 
			
		||||
        this.recordsManagementEventService = rmEventService;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    @WebApiDescription(title = "Return a list of different event types")
 | 
			
		||||
    public CollectionWithPagingInfo<EventTypeInfo> readAll(Parameters params)
 | 
			
		||||
    {
 | 
			
		||||
        // TODO: AssociationName and ActionOnAssociatedNode properties still need to be assigned.
 | 
			
		||||
        Paging paging = params.getPaging();
 | 
			
		||||
 | 
			
		||||
        List<EventTypeInfo> eventTypeInfoList = recordsManagementEventService.getEventTypes().stream()
 | 
			
		||||
                .map(EventTypeInfo::fromRecordsManagementEventType)
 | 
			
		||||
                .collect(Collectors.toList());
 | 
			
		||||
 | 
			
		||||
        int totalCount = eventTypeInfoList.size();
 | 
			
		||||
        boolean hasMoreItems = paging.getSkipCount() + paging.getMaxItems() < totalCount;
 | 
			
		||||
        return CollectionWithPagingInfo.asPaged(paging, eventTypeInfoList.stream()
 | 
			
		||||
                .skip(paging.getSkipCount())
 | 
			
		||||
                .limit(paging.getMaxItems())
 | 
			
		||||
                .collect(Collectors.toList()), hasMoreItems, totalCount);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,35 +1,34 @@
 | 
			
		||||
/*
 | 
			
		||||
 * #%L
 | 
			
		||||
 * Alfresco Remote API
 | 
			
		||||
 * Alfresco Records Management Module
 | 
			
		||||
 * %%
 | 
			
		||||
 * Copyright (C) 2005 - 2022 Alfresco Software Limited
 | 
			
		||||
 * Copyright (C) 2005 - 2016 Alfresco Software Limited
 | 
			
		||||
 * %%
 | 
			
		||||
 * This file is part of the Alfresco software.
 | 
			
		||||
 * -
 | 
			
		||||
 * If the software was purchased under a paid Alfresco license, the terms of
 | 
			
		||||
 * the paid license agreement will prevail.  Otherwise, the software is
 | 
			
		||||
 * provided under the following open source license terms:
 | 
			
		||||
 *
 | 
			
		||||
 * -
 | 
			
		||||
 * Alfresco is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Lesser General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * -
 | 
			
		||||
 * Alfresco is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 *  GNU Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * GNU Lesser General Public License for more details.
 | 
			
		||||
 * -
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 * #L%
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.alfresco.rest.model;
 | 
			
		||||
 | 
			
		||||
import org.alfresco.rest.core.RestModels;
 | 
			
		||||
 | 
			
		||||
public class RestCategoryModelsCollection extends RestModels<RestCategoryModel, RestCandidateModelsCollection>
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
/**
 | 
			
		||||
 * Package info that defines the Information Governance Events REST API
 | 
			
		||||
 */
 | 
			
		||||
@WebApi(name="gs", scope=Api.SCOPE.PUBLIC, version=1)
 | 
			
		||||
package org.alfresco.rm.rest.api.events;
 | 
			
		||||
import org.alfresco.rest.framework.Api;
 | 
			
		||||
import org.alfresco.rest.framework.WebApi;
 | 
			
		||||
@@ -0,0 +1,71 @@
 | 
			
		||||
/*
 | 
			
		||||
 * #%L
 | 
			
		||||
 * Alfresco Records Management Module
 | 
			
		||||
 * %%
 | 
			
		||||
 * Copyright (C) 2005 - 2022 Alfresco Software Limited
 | 
			
		||||
 * %%
 | 
			
		||||
 * This file is part of the Alfresco software.
 | 
			
		||||
 * -
 | 
			
		||||
 * If the software was purchased under a paid Alfresco license, the terms of
 | 
			
		||||
 * the paid license agreement will prevail.  Otherwise, the software is
 | 
			
		||||
 * provided under the following open source license terms:
 | 
			
		||||
 * -
 | 
			
		||||
 * Alfresco is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Lesser General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * -
 | 
			
		||||
 * Alfresco is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Lesser General Public License for more details.
 | 
			
		||||
 * -
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 * #L%
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.alfresco.rm.rest.api.model;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import org.alfresco.module.org_alfresco_module_rm.event.RecordsManagementEvent;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The EventBody model to be exposed through REST API.
 | 
			
		||||
 */
 | 
			
		||||
public class EventBody {
 | 
			
		||||
    private String name;
 | 
			
		||||
    private String type;
 | 
			
		||||
 | 
			
		||||
    public static EventBody fromRecordsManagementEvent(RecordsManagementEvent event)
 | 
			
		||||
    {
 | 
			
		||||
        EventBody eventBody = new EventBody();
 | 
			
		||||
        if(event != null) {
 | 
			
		||||
            eventBody.setName(event.getDisplayLabel());
 | 
			
		||||
            eventBody.setType(event.getType());
 | 
			
		||||
        }
 | 
			
		||||
        return eventBody;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public EventBody() {}
 | 
			
		||||
 | 
			
		||||
    public String getName()
 | 
			
		||||
    {
 | 
			
		||||
        return name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setName(String name)
 | 
			
		||||
    {
 | 
			
		||||
        this.name = name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getType()
 | 
			
		||||
    {
 | 
			
		||||
        return type;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setType(String type)
 | 
			
		||||
    {
 | 
			
		||||
        this.type = type;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,82 @@
 | 
			
		||||
/*
 | 
			
		||||
 * #%L
 | 
			
		||||
 * Alfresco Records Management Module
 | 
			
		||||
 * %%
 | 
			
		||||
 * Copyright (C) 2005 - 2022 Alfresco Software Limited
 | 
			
		||||
 * %%
 | 
			
		||||
 * This file is part of the Alfresco software.
 | 
			
		||||
 * -
 | 
			
		||||
 * If the software was purchased under a paid Alfresco license, the terms of
 | 
			
		||||
 * the paid license agreement will prevail.  Otherwise, the software is
 | 
			
		||||
 * provided under the following open source license terms:
 | 
			
		||||
 * -
 | 
			
		||||
 * Alfresco is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Lesser General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * -
 | 
			
		||||
 * Alfresco is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Lesser General Public License for more details.
 | 
			
		||||
 * -
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 * #L%
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.alfresco.rm.rest.api.model;
 | 
			
		||||
 | 
			
		||||
import org.alfresco.module.org_alfresco_module_rm.event.RecordsManagementEvent;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The EventInfo model to be exposed through REST API.
 | 
			
		||||
 */
 | 
			
		||||
public class EventInfo {
 | 
			
		||||
    private String id;
 | 
			
		||||
    private String name;
 | 
			
		||||
    private String type;
 | 
			
		||||
 | 
			
		||||
    public static EventInfo fromRecordsManagementEvent(RecordsManagementEvent event)
 | 
			
		||||
    {
 | 
			
		||||
        EventInfo eventInfo = new EventInfo();
 | 
			
		||||
        if (event != null) {
 | 
			
		||||
            eventInfo.setName(event.getDisplayLabel());
 | 
			
		||||
            eventInfo.setId(event.getName());
 | 
			
		||||
            eventInfo.setType(event.getType());
 | 
			
		||||
        }
 | 
			
		||||
        return eventInfo;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public EventInfo() {}
 | 
			
		||||
 | 
			
		||||
    public String getId()
 | 
			
		||||
    {
 | 
			
		||||
        return id;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setId(String id)
 | 
			
		||||
    {
 | 
			
		||||
        this.id = id;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getName()
 | 
			
		||||
    {
 | 
			
		||||
        return name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setName(String name)
 | 
			
		||||
    {
 | 
			
		||||
        this.name = name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getType()
 | 
			
		||||
    {
 | 
			
		||||
        return type;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setType(String type)
 | 
			
		||||
    {
 | 
			
		||||
        this.type = type;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,105 @@
 | 
			
		||||
/*
 | 
			
		||||
 * #%L
 | 
			
		||||
 * Alfresco Records Management Module
 | 
			
		||||
 * %%
 | 
			
		||||
 * Copyright (C) 2005 - 2022 Alfresco Software Limited
 | 
			
		||||
 * %%
 | 
			
		||||
 * This file is part of the Alfresco software.
 | 
			
		||||
 * -
 | 
			
		||||
 * If the software was purchased under a paid Alfresco license, the terms of
 | 
			
		||||
 * the paid license agreement will prevail.  Otherwise, the software is
 | 
			
		||||
 * provided under the following open source license terms:
 | 
			
		||||
 * -
 | 
			
		||||
 * Alfresco is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Lesser General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 * -
 | 
			
		||||
 * Alfresco is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Lesser General Public License for more details.
 | 
			
		||||
 * -
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 * #L%
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.alfresco.rm.rest.api.model;
 | 
			
		||||
 | 
			
		||||
import org.alfresco.module.org_alfresco_module_rm.event.RecordsManagementEventType;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The EventTypeInfo model to be exposed through REST API.
 | 
			
		||||
 */
 | 
			
		||||
public class EventTypeInfo {
 | 
			
		||||
    private String id;
 | 
			
		||||
    private String name;
 | 
			
		||||
    private boolean isAutomatic;
 | 
			
		||||
    private String associationName;
 | 
			
		||||
    private String actionOnAssociatedNode;
 | 
			
		||||
 | 
			
		||||
    public static EventTypeInfo fromRecordsManagementEventType(RecordsManagementEventType eventType)
 | 
			
		||||
    {
 | 
			
		||||
        EventTypeInfo eventTypeInfo = new EventTypeInfo();
 | 
			
		||||
        if (eventType != null) {
 | 
			
		||||
            eventTypeInfo.setName(eventType.getDisplayLabel());
 | 
			
		||||
            eventTypeInfo.setId(eventType.getName());
 | 
			
		||||
            eventTypeInfo.setAutomatic(eventType.isAutomaticEvent());
 | 
			
		||||
        }
 | 
			
		||||
        return eventTypeInfo;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public EventTypeInfo() {}
 | 
			
		||||
 | 
			
		||||
    public String getId()
 | 
			
		||||
    {
 | 
			
		||||
        return id;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setId(String id)
 | 
			
		||||
    {
 | 
			
		||||
        this.id = id;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getName()
 | 
			
		||||
    {
 | 
			
		||||
        return name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setName(String name)
 | 
			
		||||
    {
 | 
			
		||||
        this.name = name;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isAutomatic()
 | 
			
		||||
    {
 | 
			
		||||
        return isAutomatic;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setAutomatic(boolean automatic)
 | 
			
		||||
    {
 | 
			
		||||
        isAutomatic = automatic;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getAssociationName()
 | 
			
		||||
    {
 | 
			
		||||
        return associationName;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setAssociationName(String associationName)
 | 
			
		||||
    {
 | 
			
		||||
        this.associationName = associationName;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getActionOnAssociatedNode()
 | 
			
		||||
    {
 | 
			
		||||
        return actionOnAssociatedNode;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setActionOnAssociatedNode(String actionOnAssociatedNode)
 | 
			
		||||
    {
 | 
			
		||||
        this.actionOnAssociatedNode = actionOnAssociatedNode;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-governance-services-community-repo-parent</artifactId>
 | 
			
		||||
        <version>20.42</version>
 | 
			
		||||
        <version>20.36-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <build>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo</artifactId>
 | 
			
		||||
        <version>20.42</version>
 | 
			
		||||
        <version>20.36-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <modules>
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo-amps</artifactId>
 | 
			
		||||
        <version>20.42</version>
 | 
			
		||||
        <version>20.36-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <properties>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
   <parent>
 | 
			
		||||
      <groupId>org.alfresco</groupId>
 | 
			
		||||
      <artifactId>alfresco-community-repo</artifactId>
 | 
			
		||||
      <version>20.42</version>
 | 
			
		||||
      <version>20.36-SNAPSHOT</version>
 | 
			
		||||
   </parent>
 | 
			
		||||
 | 
			
		||||
   <dependencies>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo</artifactId>
 | 
			
		||||
        <version>20.42</version>
 | 
			
		||||
        <version>20.36-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <properties>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo</artifactId>
 | 
			
		||||
        <version>20.42</version>
 | 
			
		||||
        <version>20.36-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <dependencies>
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,6 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo-packaging</artifactId>
 | 
			
		||||
        <version>20.42</version>
 | 
			
		||||
        <version>20.36-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
</project>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo-packaging</artifactId>
 | 
			
		||||
        <version>20.42</version>
 | 
			
		||||
        <version>20.36-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <properties>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo</artifactId>
 | 
			
		||||
        <version>20.42</version>
 | 
			
		||||
        <version>20.36-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <modules>
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo-packaging</artifactId>
 | 
			
		||||
        <version>20.42</version>
 | 
			
		||||
        <version>20.36-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <modules>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo-tests</artifactId>
 | 
			
		||||
        <version>20.42</version>
 | 
			
		||||
        <version>20.36-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <organization>
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo-tests</artifactId>
 | 
			
		||||
        <version>20.42</version>
 | 
			
		||||
        <version>20.36-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <developers>
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo-tests</artifactId>
 | 
			
		||||
        <version>20.42</version>
 | 
			
		||||
        <version>20.36-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <developers>
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo-tests</artifactId>
 | 
			
		||||
        <version>20.42</version>
 | 
			
		||||
        <version>20.36-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <properties>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,5 @@
 | 
			
		||||
package org.alfresco.rest.model;
 | 
			
		||||
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
import com.fasterxml.jackson.annotation.JsonProperty;
 | 
			
		||||
import org.alfresco.rest.core.IRestModel;
 | 
			
		||||
import org.alfresco.utility.model.TestModel;
 | 
			
		||||
@@ -49,7 +47,8 @@ This must be unique within the parent category.
 | 
			
		||||
    private boolean hasChildren;	    
 | 
			
		||||
    /**
 | 
			
		||||
    The number of nodes that are assigned to this category.
 | 
			
		||||
    */
 | 
			
		||||
    */	        
 | 
			
		||||
 | 
			
		||||
    private long count;
 | 
			
		||||
 | 
			
		||||
    public String getId()
 | 
			
		||||
@@ -100,33 +99,6 @@ This must be unique within the parent category.
 | 
			
		||||
    public void setCount(long count)
 | 
			
		||||
    {
 | 
			
		||||
        this.count = count;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean equals(Object o)
 | 
			
		||||
    {
 | 
			
		||||
        if (this == o) return true;
 | 
			
		||||
        if (o == null || getClass() != o.getClass()) return false;
 | 
			
		||||
        RestCategoryModel that = (RestCategoryModel) o;
 | 
			
		||||
        return Objects.equals(id, that.id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int hashCode()
 | 
			
		||||
    {
 | 
			
		||||
        return Objects.hash(id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String toString()
 | 
			
		||||
    {
 | 
			
		||||
        return "RestCategoryModel{" +
 | 
			
		||||
                "id='" + id + '\'' +
 | 
			
		||||
                ", name='" + name + '\'' +
 | 
			
		||||
                ", parentId='" + parentId + '\'' +
 | 
			
		||||
                ", hasChildren=" + hasChildren +
 | 
			
		||||
                ", count=" + count +
 | 
			
		||||
                '}';
 | 
			
		||||
    }
 | 
			
		||||
    }				
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
@@ -25,14 +25,9 @@
 | 
			
		||||
 */
 | 
			
		||||
package org.alfresco.rest.requests;
 | 
			
		||||
 | 
			
		||||
import static org.alfresco.rest.core.JsonBodyGenerator.arrayToJson;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import org.alfresco.rest.core.RestRequest;
 | 
			
		||||
import org.alfresco.rest.core.RestWrapper;
 | 
			
		||||
import org.alfresco.rest.model.RestCategoryModel;
 | 
			
		||||
import org.alfresco.rest.model.RestCategoryModelsCollection;
 | 
			
		||||
import org.springframework.http.HttpMethod;
 | 
			
		||||
 | 
			
		||||
public class Categories extends ModelRequest<Categories>
 | 
			
		||||
@@ -46,9 +41,9 @@ public class Categories extends ModelRequest<Categories>
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Retrieves a category with ID using GET call on "/categories/{categoryId}"
 | 
			
		||||
     * Retrieves a category with ID using GET call on using GET call on "/tags/{tagId}"
 | 
			
		||||
     *
 | 
			
		||||
     * @return RestCategoryModel
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    public RestCategoryModel getCategory()
 | 
			
		||||
    {
 | 
			
		||||
@@ -57,51 +52,4 @@ public class Categories extends ModelRequest<Categories>
 | 
			
		||||
        return restWrapper.processModel(RestCategoryModel.class, request);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create several categories in one request.
 | 
			
		||||
     *
 | 
			
		||||
     * @param restCategoryModels The list of categories to create.
 | 
			
		||||
     * @return The list of created categories with additional data populated by the repository.
 | 
			
		||||
     */
 | 
			
		||||
    public RestCategoryModelsCollection createCategoriesList(List<RestCategoryModel> restCategoryModels) {
 | 
			
		||||
        RestRequest request = RestRequest.requestWithBody(HttpMethod.POST, arrayToJson(restCategoryModels), "categories/{categoryId}/subcategories", category.getId());
 | 
			
		||||
        return restWrapper.processModels(RestCategoryModelsCollection.class, request);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Create single category.
 | 
			
		||||
     *
 | 
			
		||||
     * @param restCategoryModel The categories to create.
 | 
			
		||||
     * @return Created category with additional data populated by the repository.
 | 
			
		||||
     */
 | 
			
		||||
    public RestCategoryModel createSingleCategory(RestCategoryModel restCategoryModel)
 | 
			
		||||
    {
 | 
			
		||||
        RestRequest request = RestRequest
 | 
			
		||||
                .requestWithBody(HttpMethod.POST, restCategoryModel.toJson(), "categories/{categoryId}/subcategories", category.getId());
 | 
			
		||||
        return restWrapper.processModel(RestCategoryModel.class, request);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get parent category children.
 | 
			
		||||
     *
 | 
			
		||||
     * @return The list of child categories.
 | 
			
		||||
     */
 | 
			
		||||
    public RestCategoryModelsCollection getCategoryChildren()
 | 
			
		||||
    {
 | 
			
		||||
        RestRequest request = RestRequest.simpleRequest(HttpMethod.GET, "categories/{categoryId}/subcategories", category.getId());
 | 
			
		||||
        return restWrapper.processModels(RestCategoryModelsCollection.class, request);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Delete category.
 | 
			
		||||
     *
 | 
			
		||||
     * - DELETE /categories/{categoryId}
 | 
			
		||||
     */
 | 
			
		||||
    public void deleteCategory()
 | 
			
		||||
    {
 | 
			
		||||
        RestRequest request = RestRequest.
 | 
			
		||||
                simpleRequest(HttpMethod.DELETE, "/categories/{categoryId}", category.getId());
 | 
			
		||||
        restWrapper.processEmptyModel(request);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,273 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * #%L
 | 
			
		||||
 * Alfresco Remote API
 | 
			
		||||
 * %%
 | 
			
		||||
 * Copyright (C) 2005 - 2022 Alfresco Software Limited
 | 
			
		||||
 * %%
 | 
			
		||||
 * This file is part of the Alfresco software.
 | 
			
		||||
 * If the software was purchased under a paid Alfresco license, the terms of
 | 
			
		||||
 * the paid license agreement will prevail.  Otherwise, the software is
 | 
			
		||||
 * provided under the following open source license terms:
 | 
			
		||||
 *
 | 
			
		||||
 * Alfresco is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Lesser General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * Alfresco is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 *  GNU Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 * #L%
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.alfresco.rest.categories;
 | 
			
		||||
 | 
			
		||||
import static org.alfresco.utility.report.log.Step.STEP;
 | 
			
		||||
import static org.springframework.http.HttpStatus.BAD_REQUEST;
 | 
			
		||||
import static org.springframework.http.HttpStatus.CREATED;
 | 
			
		||||
import static org.springframework.http.HttpStatus.FORBIDDEN;
 | 
			
		||||
import static org.springframework.http.HttpStatus.NOT_FOUND;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
import java.util.stream.IntStream;
 | 
			
		||||
 | 
			
		||||
import org.alfresco.rest.RestTest;
 | 
			
		||||
import org.alfresco.rest.model.RestCategoryModel;
 | 
			
		||||
import org.alfresco.rest.model.RestCategoryModelsCollection;
 | 
			
		||||
import org.alfresco.utility.data.RandomData;
 | 
			
		||||
import org.alfresco.utility.model.FolderModel;
 | 
			
		||||
import org.alfresco.utility.model.SiteModel;
 | 
			
		||||
import org.alfresco.utility.model.TestGroup;
 | 
			
		||||
import org.alfresco.utility.model.UserModel;
 | 
			
		||||
import org.apache.commons.lang3.StringUtils;
 | 
			
		||||
import org.testng.annotations.BeforeClass;
 | 
			
		||||
import org.testng.annotations.Test;
 | 
			
		||||
 | 
			
		||||
public class CreateCategoriesTests extends RestTest
 | 
			
		||||
{
 | 
			
		||||
    private static final String FIELD_NAME = "name";
 | 
			
		||||
    private static final String FIELD_PARENT_ID = "parentId";
 | 
			
		||||
    private static final String FIELD_HAS_CHILDREN = "hasChildren";
 | 
			
		||||
    private static final String FIELD_ID = "id";
 | 
			
		||||
    private UserModel user;
 | 
			
		||||
 | 
			
		||||
    @BeforeClass(alwaysRun = true)
 | 
			
		||||
    public void dataPreparation() throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        STEP("Create a user");
 | 
			
		||||
        user = dataUser.createRandomTestUser();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check we can create a category as direct child of root category
 | 
			
		||||
     */
 | 
			
		||||
    @Test(groups = {TestGroup.REST_API})
 | 
			
		||||
    public void testCreateCategoryUnderRoot()
 | 
			
		||||
    {
 | 
			
		||||
        STEP("Create a category under root category (as admin)");
 | 
			
		||||
        final RestCategoryModel rootCategory = new RestCategoryModel();
 | 
			
		||||
        rootCategory.setId("-root-");
 | 
			
		||||
        final RestCategoryModel aCategory = new RestCategoryModel();
 | 
			
		||||
        aCategory.setName(RandomData.getRandomName("Category"));
 | 
			
		||||
        final RestCategoryModel createdCategory = restClient.authenticateUser(dataUser.getAdminUser())
 | 
			
		||||
                .withCoreAPI()
 | 
			
		||||
                .usingCategory(rootCategory)
 | 
			
		||||
                .createSingleCategory(aCategory);
 | 
			
		||||
        restClient.assertStatusCodeIs(CREATED);
 | 
			
		||||
 | 
			
		||||
        createdCategory.assertThat().field(FIELD_NAME).is(aCategory.getName());
 | 
			
		||||
        createdCategory.assertThat().field(FIELD_PARENT_ID).is(rootCategory.getId());
 | 
			
		||||
        createdCategory.assertThat().field(FIELD_HAS_CHILDREN).is(false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check we get 400 error when attempting to create a category with empty name
 | 
			
		||||
     */
 | 
			
		||||
    @Test(groups = {TestGroup.REST_API})
 | 
			
		||||
    public void testCreateCategoryWithoutName_andFail()
 | 
			
		||||
    {
 | 
			
		||||
        STEP("Create a category under root category (as admin)");
 | 
			
		||||
        final RestCategoryModel rootCategory = new RestCategoryModel();
 | 
			
		||||
        rootCategory.setId("-root-");
 | 
			
		||||
        final RestCategoryModel aCategory = new RestCategoryModel();
 | 
			
		||||
        aCategory.setName(StringUtils.EMPTY);
 | 
			
		||||
        restClient.authenticateUser(dataUser.getAdminUser())
 | 
			
		||||
                .withCoreAPI()
 | 
			
		||||
                .usingCategory(rootCategory)
 | 
			
		||||
                .createSingleCategory(aCategory);
 | 
			
		||||
        restClient.assertStatusCodeIs(BAD_REQUEST).assertLastError().containsSummary("Category name must not be null or empty");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check we can create several categories as children of a created category
 | 
			
		||||
     */
 | 
			
		||||
    @Test(groups = {TestGroup.REST_API})
 | 
			
		||||
    public void testCreateSeveralSubCategories()
 | 
			
		||||
    {
 | 
			
		||||
        STEP("Create a category under root category (as admin)");
 | 
			
		||||
        final RestCategoryModel rootCategory = new RestCategoryModel();
 | 
			
		||||
        rootCategory.setId("-root-");
 | 
			
		||||
        final RestCategoryModel aCategory = new RestCategoryModel();
 | 
			
		||||
        aCategory.setName(RandomData.getRandomName("Category"));
 | 
			
		||||
        final RestCategoryModel createdCategory = restClient.authenticateUser(dataUser.getAdminUser())
 | 
			
		||||
                .withCoreAPI()
 | 
			
		||||
                .usingCategory(rootCategory)
 | 
			
		||||
                .createSingleCategory(aCategory);
 | 
			
		||||
        restClient.assertStatusCodeIs(CREATED);
 | 
			
		||||
 | 
			
		||||
        createdCategory.assertThat().field(FIELD_NAME).is(aCategory.getName())
 | 
			
		||||
                .assertThat().field(FIELD_PARENT_ID).is(rootCategory.getId())
 | 
			
		||||
                .assertThat().field(FIELD_HAS_CHILDREN).is(false)
 | 
			
		||||
                .assertThat().field(FIELD_ID).isNotEmpty();
 | 
			
		||||
 | 
			
		||||
        STEP("Create two categories under the previously created (as admin)");
 | 
			
		||||
        final int categoriesNumber = 2;
 | 
			
		||||
        final List<RestCategoryModel> categoriesToCreate = getCategoriesToCreate(categoriesNumber);
 | 
			
		||||
        final RestCategoryModelsCollection createdSubCategories = restClient.authenticateUser(dataUser.getAdminUser())
 | 
			
		||||
                .withCoreAPI()
 | 
			
		||||
                .usingCategory(createdCategory)
 | 
			
		||||
                .createCategoriesList(categoriesToCreate);
 | 
			
		||||
        restClient.assertStatusCodeIs(CREATED);
 | 
			
		||||
 | 
			
		||||
        createdSubCategories.assertThat()
 | 
			
		||||
                .entriesListCountIs(categoriesToCreate.size());
 | 
			
		||||
        IntStream.range(0, categoriesNumber)
 | 
			
		||||
                .forEach(i -> createdSubCategories.getEntries().get(i).onModel()
 | 
			
		||||
                    .assertThat().field(FIELD_NAME).is(categoriesToCreate.get(i).getName())
 | 
			
		||||
                    .assertThat().field(FIELD_PARENT_ID).is(createdCategory.getId())
 | 
			
		||||
                    .assertThat().field(FIELD_HAS_CHILDREN).is(false)
 | 
			
		||||
                    .assertThat().field(FIELD_ID).isNotEmpty()
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
        STEP("Get the parent category and check if it now has children (as regular user)");
 | 
			
		||||
        final RestCategoryModel parentCategoryFromGet = restClient.authenticateUser(user)
 | 
			
		||||
                .withCoreAPI()
 | 
			
		||||
                .usingCategory(createdCategory)
 | 
			
		||||
                .getCategory();
 | 
			
		||||
 | 
			
		||||
        parentCategoryFromGet.assertThat().field(FIELD_HAS_CHILDREN).is(true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check we can create over 100 categories as children of a created category and pagination information is proper.
 | 
			
		||||
     */
 | 
			
		||||
    @Test(groups = {TestGroup.REST_API})
 | 
			
		||||
    public void testCreateOver100SubCategories()
 | 
			
		||||
    {
 | 
			
		||||
        STEP("Create a category under root category (as admin)");
 | 
			
		||||
        final RestCategoryModel rootCategory = new RestCategoryModel();
 | 
			
		||||
        rootCategory.setId("-root-");
 | 
			
		||||
        final RestCategoryModel aCategory = new RestCategoryModel();
 | 
			
		||||
        aCategory.setName(RandomData.getRandomName("Category"));
 | 
			
		||||
        final RestCategoryModel createdCategory = restClient.authenticateUser(dataUser.getAdminUser())
 | 
			
		||||
                .withCoreAPI()
 | 
			
		||||
                .usingCategory(rootCategory)
 | 
			
		||||
                .createSingleCategory(aCategory);
 | 
			
		||||
        restClient.assertStatusCodeIs(CREATED);
 | 
			
		||||
 | 
			
		||||
        createdCategory.assertThat().field(FIELD_NAME).is(aCategory.getName())
 | 
			
		||||
                .assertThat().field(FIELD_PARENT_ID).is(rootCategory.getId())
 | 
			
		||||
                .assertThat().field(FIELD_HAS_CHILDREN).is(false)
 | 
			
		||||
                .assertThat().field(FIELD_ID).isNotEmpty();
 | 
			
		||||
 | 
			
		||||
        STEP("Create more than a hundred categories under the previously created (as admin)");
 | 
			
		||||
        final int categoriesNumber = 120;
 | 
			
		||||
        final List<RestCategoryModel> categoriesToCreate = getCategoriesToCreate(categoriesNumber);
 | 
			
		||||
        final RestCategoryModelsCollection createdSubCategories = restClient.authenticateUser(dataUser.getAdminUser())
 | 
			
		||||
                .withCoreAPI()
 | 
			
		||||
                .usingCategory(createdCategory)
 | 
			
		||||
                .createCategoriesList(categoriesToCreate);
 | 
			
		||||
        restClient.assertStatusCodeIs(CREATED);
 | 
			
		||||
 | 
			
		||||
        createdSubCategories.assertThat()
 | 
			
		||||
                .entriesListCountIs(categoriesToCreate.size());
 | 
			
		||||
        IntStream.range(0, categoriesNumber)
 | 
			
		||||
                .forEach(i -> createdSubCategories.getEntries().get(i).onModel()
 | 
			
		||||
                        .assertThat().field(FIELD_NAME).is(categoriesToCreate.get(i).getName())
 | 
			
		||||
                        .assertThat().field(FIELD_PARENT_ID).is(createdCategory.getId())
 | 
			
		||||
                        .assertThat().field(FIELD_HAS_CHILDREN).is(false)
 | 
			
		||||
                        .assertThat().field(FIELD_ID).isNotEmpty()
 | 
			
		||||
                );
 | 
			
		||||
        createdSubCategories.getPagination().assertThat().field("count").is(categoriesNumber)
 | 
			
		||||
            .assertThat().field("totalItems").is(categoriesNumber)
 | 
			
		||||
            .assertThat().field("maxItems").is(categoriesNumber)
 | 
			
		||||
            .assertThat().field("skipCount").is(0)
 | 
			
		||||
            .assertThat().field("hasMoreItems").is(false);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check we cannot create a category as direct child of root category as non-admin user
 | 
			
		||||
     */
 | 
			
		||||
    @Test(groups = {TestGroup.REST_API})
 | 
			
		||||
    public void testCreateCategoryUnderRootAsRegularUser_andFail()
 | 
			
		||||
    {
 | 
			
		||||
        STEP("Create a category under root category (as user)");
 | 
			
		||||
        final RestCategoryModel rootCategory = new RestCategoryModel();
 | 
			
		||||
        rootCategory.setId("-root-");
 | 
			
		||||
        final RestCategoryModel aCategory = new RestCategoryModel();
 | 
			
		||||
        aCategory.setName(RandomData.getRandomName("Category"));
 | 
			
		||||
        restClient.authenticateUser(user)
 | 
			
		||||
                .withCoreAPI()
 | 
			
		||||
                .usingCategory(rootCategory)
 | 
			
		||||
                .createSingleCategory(aCategory);
 | 
			
		||||
        restClient.assertStatusCodeIs(FORBIDDEN).assertLastError().containsSummary("Current user does not have permission to create a category");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check we cannot create a category under non existing parent node
 | 
			
		||||
     */
 | 
			
		||||
    @Test(groups = {TestGroup.REST_API})
 | 
			
		||||
    public void testCreateCategoryUnderNonExistingParent_andFail()
 | 
			
		||||
    {
 | 
			
		||||
        STEP("Create a category under non existing category node (as admin)");
 | 
			
		||||
        final RestCategoryModel rootCategory = new RestCategoryModel();
 | 
			
		||||
        final String id = "non-existing-node-id";
 | 
			
		||||
        rootCategory.setId(id);
 | 
			
		||||
        final RestCategoryModel aCategory = new RestCategoryModel();
 | 
			
		||||
        aCategory.setName(RandomData.getRandomName("Category"));
 | 
			
		||||
        restClient.authenticateUser(dataUser.getAdminUser())
 | 
			
		||||
                .withCoreAPI()
 | 
			
		||||
                .usingCategory(rootCategory)
 | 
			
		||||
                .createSingleCategory(aCategory);
 | 
			
		||||
        restClient.assertStatusCodeIs(NOT_FOUND).assertLastError().containsSummary("The entity with id: " + id + " was not found");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check we cannot create a category under a node which is not a category
 | 
			
		||||
     */
 | 
			
		||||
    @Test(groups = {TestGroup.REST_API})
 | 
			
		||||
    public void testCreateCategoryUnderFolderNode_andFail()
 | 
			
		||||
    {
 | 
			
		||||
        STEP("Create a site and a folder inside it");
 | 
			
		||||
        final SiteModel site = dataSite.usingUser(user).createPublicRandomSite();
 | 
			
		||||
        final FolderModel folder = dataContent.usingUser(user).usingSite(site).createFolder();
 | 
			
		||||
 | 
			
		||||
        STEP("Create a category under folder node (as admin)");
 | 
			
		||||
        final RestCategoryModel rootCategory = new RestCategoryModel();
 | 
			
		||||
        rootCategory.setId(folder.getNodeRef());
 | 
			
		||||
        final RestCategoryModel aCategory = new RestCategoryModel();
 | 
			
		||||
        aCategory.setName(RandomData.getRandomName("Category"));
 | 
			
		||||
        restClient.authenticateUser(dataUser.getAdminUser())
 | 
			
		||||
                .withCoreAPI()
 | 
			
		||||
                .usingCategory(rootCategory)
 | 
			
		||||
                .createSingleCategory(aCategory);
 | 
			
		||||
        restClient.assertStatusCodeIs(BAD_REQUEST).assertLastError().containsSummary("Node id does not refer to a valid category");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static List<RestCategoryModel> getCategoriesToCreate(final int count)
 | 
			
		||||
    {
 | 
			
		||||
        return IntStream.range(0, count)
 | 
			
		||||
                .mapToObj(i -> {
 | 
			
		||||
                    final RestCategoryModel aSubCategory = new RestCategoryModel();
 | 
			
		||||
                    aSubCategory.setName((RandomData.getRandomName("SubCategory")));
 | 
			
		||||
                    return aSubCategory;
 | 
			
		||||
                })
 | 
			
		||||
                .collect(Collectors.toList());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,133 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * #%L
 | 
			
		||||
 * Alfresco Remote API
 | 
			
		||||
 * %%
 | 
			
		||||
 * Copyright (C) 2005 - 2022 Alfresco Software Limited
 | 
			
		||||
 * %%
 | 
			
		||||
 * This file is part of the Alfresco software.
 | 
			
		||||
 * If the software was purchased under a paid Alfresco license, the terms of
 | 
			
		||||
 * the paid license agreement will prevail.  Otherwise, the software is
 | 
			
		||||
 * provided under the following open source license terms:
 | 
			
		||||
 *
 | 
			
		||||
 * Alfresco is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Lesser General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * Alfresco is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 *  GNU Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 * #L%
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.alfresco.rest.categories;
 | 
			
		||||
 | 
			
		||||
import org.alfresco.rest.RestTest;
 | 
			
		||||
import org.alfresco.rest.model.RestCategoryModel;
 | 
			
		||||
import org.alfresco.utility.data.RandomData;
 | 
			
		||||
import org.alfresco.utility.model.FolderModel;
 | 
			
		||||
import org.alfresco.utility.model.SiteModel;
 | 
			
		||||
import org.alfresco.utility.model.TestGroup;
 | 
			
		||||
import org.alfresco.utility.model.UserModel;
 | 
			
		||||
import org.testng.annotations.BeforeClass;
 | 
			
		||||
import org.testng.annotations.Test;
 | 
			
		||||
 | 
			
		||||
import static org.alfresco.utility.report.log.Step.STEP;
 | 
			
		||||
import static org.springframework.http.HttpStatus.BAD_REQUEST;
 | 
			
		||||
import static org.springframework.http.HttpStatus.CREATED;
 | 
			
		||||
import static org.springframework.http.HttpStatus.FORBIDDEN;
 | 
			
		||||
import static org.springframework.http.HttpStatus.NOT_FOUND;
 | 
			
		||||
import static org.springframework.http.HttpStatus.NO_CONTENT;
 | 
			
		||||
 | 
			
		||||
public class DeleteCategoriesTests extends RestTest {
 | 
			
		||||
 | 
			
		||||
    private UserModel user;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    @BeforeClass(alwaysRun = true)
 | 
			
		||||
    public void dataPreparation() throws Exception
 | 
			
		||||
    {
 | 
			
		||||
        STEP("Create a user");
 | 
			
		||||
        user = dataUser.createRandomTestUser();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check we can delete a category.
 | 
			
		||||
     */
 | 
			
		||||
    @Test(groups = {TestGroup.REST_API})
 | 
			
		||||
    public void testDeleteCategory()
 | 
			
		||||
    {
 | 
			
		||||
        STEP("Create a category and send a request to delete it.");
 | 
			
		||||
        RestCategoryModel aCategory = createCategory();
 | 
			
		||||
        restClient.authenticateUser(dataUser.getAdminUser()).withCoreAPI().usingCategory(aCategory).deleteCategory();
 | 
			
		||||
        restClient.assertStatusCodeIs(NO_CONTENT);
 | 
			
		||||
 | 
			
		||||
        STEP("Ensure that the category has been deleted by sending a GET request and receiving 404.");
 | 
			
		||||
        restClient.authenticateUser(user).withCoreAPI().usingCategory(aCategory).getCategory();
 | 
			
		||||
        restClient.assertStatusCodeIs(NOT_FOUND);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check we get an error when trying to delete a category as a non-admin user.
 | 
			
		||||
     */
 | 
			
		||||
    @Test(groups = {TestGroup.REST_API})
 | 
			
		||||
    public void testDeleteCategoryAsRegularUser_andFail()
 | 
			
		||||
    {
 | 
			
		||||
        RestCategoryModel aCategory = createCategory();
 | 
			
		||||
        restClient.authenticateUser(user).withCoreAPI().usingCategory(aCategory).deleteCategory();
 | 
			
		||||
        restClient.assertStatusCodeIs(FORBIDDEN).assertLastError().containsSummary("Current user does not have permission to delete a category");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check we receive 404 error when trying to delete a category with a non-existent node id.
 | 
			
		||||
     */
 | 
			
		||||
    @Test(groups = {TestGroup.REST_API})
 | 
			
		||||
    public void testDeleteNonExistentCategory()
 | 
			
		||||
    {
 | 
			
		||||
        STEP("Get category with non-existent id");
 | 
			
		||||
        final RestCategoryModel rootCategory = new RestCategoryModel();
 | 
			
		||||
        final String id = "non-existing-dummy-id";
 | 
			
		||||
        rootCategory.setId(id);
 | 
			
		||||
 | 
			
		||||
        STEP("Attempt to delete category with non-existent id and receive 404");
 | 
			
		||||
        restClient.authenticateUser(dataUser.getAdminUser()).withCoreAPI().usingCategory(rootCategory).deleteCategory();
 | 
			
		||||
        restClient.assertStatusCodeIs(NOT_FOUND);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Attempt to delete a category when providing a node id that doesn't belong to a category
 | 
			
		||||
     */
 | 
			
		||||
    @Test(groups = {TestGroup.REST_API})
 | 
			
		||||
    public void testDeleteCategory_givenNonCategoryNodeId()
 | 
			
		||||
    {
 | 
			
		||||
        STEP("Create a site and a folder inside it");
 | 
			
		||||
        final SiteModel site = dataSite.usingUser(user).createPublicRandomSite();
 | 
			
		||||
        final FolderModel folder = dataContent.usingUser(user).usingSite(site).createFolder();
 | 
			
		||||
        String id = folder.getNodeRef();
 | 
			
		||||
 | 
			
		||||
        STEP("Create a category, set its id to the folder id and attempt to delete it");
 | 
			
		||||
        final RestCategoryModel aCategory = new RestCategoryModel();
 | 
			
		||||
        aCategory.setId(id);
 | 
			
		||||
        restClient.authenticateUser(dataUser.getAdminUser()).withCoreAPI().usingCategory(aCategory).deleteCategory();
 | 
			
		||||
        restClient.assertStatusCodeIs(BAD_REQUEST).assertLastError().containsSummary("Node id does not refer to a valid category");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public RestCategoryModel createCategory()
 | 
			
		||||
    {
 | 
			
		||||
        final RestCategoryModel rootCategory = new RestCategoryModel();
 | 
			
		||||
        rootCategory.setId("-root-");
 | 
			
		||||
        final RestCategoryModel aCategory = new RestCategoryModel();
 | 
			
		||||
        aCategory.setName(RandomData.getRandomName("Category"));
 | 
			
		||||
        final RestCategoryModel createdCategory = restClient.authenticateUser(dataUser.getAdminUser())
 | 
			
		||||
                .withCoreAPI()
 | 
			
		||||
                .usingCategory(rootCategory)
 | 
			
		||||
                .createSingleCategory(aCategory);
 | 
			
		||||
        restClient.assertStatusCodeIs(CREATED);
 | 
			
		||||
 | 
			
		||||
        return createdCategory;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -28,20 +28,10 @@ package org.alfresco.rest.categories;
 | 
			
		||||
 | 
			
		||||
import static org.alfresco.utility.report.log.Step.STEP;
 | 
			
		||||
import static org.springframework.http.HttpStatus.BAD_REQUEST;
 | 
			
		||||
import static org.springframework.http.HttpStatus.CREATED;
 | 
			
		||||
import static org.springframework.http.HttpStatus.NOT_FOUND;
 | 
			
		||||
import static org.springframework.http.HttpStatus.OK;
 | 
			
		||||
import static org.testng.Assert.assertTrue;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
import java.util.stream.IntStream;
 | 
			
		||||
 | 
			
		||||
import org.alfresco.rest.RestTest;
 | 
			
		||||
import org.alfresco.rest.core.RestResponse;
 | 
			
		||||
import org.alfresco.rest.model.RestCategoryModel;
 | 
			
		||||
import org.alfresco.rest.model.RestCategoryModelsCollection;
 | 
			
		||||
import org.alfresco.utility.data.RandomData;
 | 
			
		||||
import org.alfresco.utility.model.FolderModel;
 | 
			
		||||
import org.alfresco.utility.model.SiteModel;
 | 
			
		||||
import org.alfresco.utility.model.TestGroup;
 | 
			
		||||
@@ -51,10 +41,6 @@ import org.testng.annotations.Test;
 | 
			
		||||
 | 
			
		||||
public class GetCategoriesTests extends RestTest
 | 
			
		||||
{
 | 
			
		||||
    private static final List<String> DEFAULT_ROOT_CATEGORIES = List.of("Software Document Classification", "Languages", "Regions", "Tags");
 | 
			
		||||
    private static final String ROOT = "-root-";
 | 
			
		||||
    private static final String NON_EXISTING_CATEGORY_ID = "non-existing-category-id";
 | 
			
		||||
 | 
			
		||||
    private UserModel user;
 | 
			
		||||
 | 
			
		||||
    @BeforeClass(alwaysRun = true)
 | 
			
		||||
@@ -64,52 +50,21 @@ public class GetCategoriesTests extends RestTest
 | 
			
		||||
        user = dataUser.createRandomTestUser();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check we can get a category which we just created in as direct child of root category
 | 
			
		||||
     */
 | 
			
		||||
    @Test(groups = {TestGroup.REST_API})
 | 
			
		||||
    public void testGetCategoryById()
 | 
			
		||||
    {
 | 
			
		||||
        STEP("Create a category under root category (as admin)");
 | 
			
		||||
        final RestCategoryModel rootCategory = new RestCategoryModel();
 | 
			
		||||
        rootCategory.setId(ROOT);
 | 
			
		||||
        final RestCategoryModel aCategory = new RestCategoryModel();
 | 
			
		||||
        aCategory.setName(RandomData.getRandomName("Category"));
 | 
			
		||||
        final RestCategoryModel createdCategory = restClient.authenticateUser(dataUser.getAdminUser())
 | 
			
		||||
                .withCoreAPI()
 | 
			
		||||
                .usingCategory(rootCategory)
 | 
			
		||||
                .createSingleCategory(aCategory);
 | 
			
		||||
        restClient.assertStatusCodeIs(CREATED);
 | 
			
		||||
 | 
			
		||||
        createdCategory.assertThat()
 | 
			
		||||
                .field("name").is(aCategory.getName());
 | 
			
		||||
        createdCategory.assertThat()
 | 
			
		||||
                .field("parentId").is(rootCategory.getId());
 | 
			
		||||
        createdCategory.assertThat()
 | 
			
		||||
                .field("hasChildren").is(false);
 | 
			
		||||
 | 
			
		||||
        STEP("Get the created category (as regular user)");
 | 
			
		||||
        final RestCategoryModel categoryFromGet =
 | 
			
		||||
                restClient.authenticateUser(user).withCoreAPI().usingCategory(createdCategory).getCategory();
 | 
			
		||||
        restClient.assertStatusCodeIs(OK);
 | 
			
		||||
        categoryFromGet.assertThat().isEqualTo(createdCategory);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check we get an error when passing -root- as category id
 | 
			
		||||
     */
 | 
			
		||||
    @Test(groups = {TestGroup.REST_API})
 | 
			
		||||
    public void testGetCategoryByIdProvidingRootAsId()
 | 
			
		||||
    {
 | 
			
		||||
        STEP("Get category with -root- as id");
 | 
			
		||||
        STEP("Get category with -root- as id (which does not exist)");
 | 
			
		||||
        final RestCategoryModel rootCategory = new RestCategoryModel();
 | 
			
		||||
        rootCategory.setId(ROOT);
 | 
			
		||||
        rootCategory.setId("-root-");
 | 
			
		||||
        restClient.authenticateUser(user).withCoreAPI().usingCategory(rootCategory).getCategory();
 | 
			
		||||
        restClient.assertStatusCodeIs(BAD_REQUEST).assertLastError().containsSummary("Node id does not refer to a valid category");
 | 
			
		||||
        restClient.assertStatusCodeIs(NOT_FOUND);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check we get an error when passing folder node id as category id
 | 
			
		||||
     * Check we get an error when passing  as category id
 | 
			
		||||
     */
 | 
			
		||||
    @Test(groups = {TestGroup.REST_API})
 | 
			
		||||
    public void testGetCategoryByIdProvidingFolderAsId()
 | 
			
		||||
@@ -122,101 +77,7 @@ public class GetCategoriesTests extends RestTest
 | 
			
		||||
        final RestCategoryModel rootCategory = new RestCategoryModel();
 | 
			
		||||
        rootCategory.setId(folder.getNodeRef());
 | 
			
		||||
        restClient.authenticateUser(user).withCoreAPI().usingCategory(rootCategory).getCategory();
 | 
			
		||||
        restClient.assertStatusCodeIs(BAD_REQUEST).assertLastError().containsSummary("Node id does not refer to a valid category");
 | 
			
		||||
        restClient.assertStatusCodeIs(BAD_REQUEST);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check we get an error when passing non existing as category id
 | 
			
		||||
     */
 | 
			
		||||
    @Test(groups = {TestGroup.REST_API})
 | 
			
		||||
    public void testGetCategoryByIdProvidingNonExistingId()
 | 
			
		||||
    {
 | 
			
		||||
        STEP("Get category with id which does not exist");
 | 
			
		||||
        final RestCategoryModel rootCategory = new RestCategoryModel();
 | 
			
		||||
        final String id = NON_EXISTING_CATEGORY_ID;
 | 
			
		||||
        rootCategory.setId(id);
 | 
			
		||||
        restClient.authenticateUser(user).withCoreAPI().usingCategory(rootCategory).getCategory();
 | 
			
		||||
        restClient.assertStatusCodeIs(NOT_FOUND).assertLastError().containsSummary(id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check we can get children category of a root category
 | 
			
		||||
     */
 | 
			
		||||
    @Test(groups = {TestGroup.REST_API})
 | 
			
		||||
    public void testGetCategoryChildren()
 | 
			
		||||
    {
 | 
			
		||||
        STEP("Get category children with -root- as parent id");
 | 
			
		||||
        final RestCategoryModel rootCategory = new RestCategoryModel();
 | 
			
		||||
        rootCategory.setId(ROOT);
 | 
			
		||||
        RestCategoryModelsCollection childCategoriesList =
 | 
			
		||||
                restClient.authenticateUser(user).withCoreAPI().usingCategory(rootCategory).getCategoryChildren();
 | 
			
		||||
        restClient.assertStatusCodeIs(OK);
 | 
			
		||||
 | 
			
		||||
        childCategoriesList.assertThat().entriesListIsNotEmpty();
 | 
			
		||||
        assertTrue(childCategoriesList.getEntries().stream()
 | 
			
		||||
                .map(RestCategoryModel::onModel)
 | 
			
		||||
                .map(RestCategoryModel::getName)
 | 
			
		||||
                .collect(Collectors.toList())
 | 
			
		||||
                .containsAll(DEFAULT_ROOT_CATEGORIES));
 | 
			
		||||
        STEP("Create a new category under root and make sure it is returned as one of root's children");
 | 
			
		||||
        final RestCategoryModel aCategory = new RestCategoryModel();
 | 
			
		||||
        aCategory.setName((RandomData.getRandomName("newCategoryUnderRoot")));
 | 
			
		||||
        final RestCategoryModel createdCategory = restClient.authenticateUser(dataUser.getAdminUser())
 | 
			
		||||
                .withCoreAPI()
 | 
			
		||||
                .usingCategory(rootCategory)
 | 
			
		||||
                .createSingleCategory(aCategory);
 | 
			
		||||
        restClient.assertStatusCodeIs(CREATED);
 | 
			
		||||
 | 
			
		||||
        childCategoriesList = restClient.authenticateUser(user).withCoreAPI().usingCategory(rootCategory).getCategoryChildren();
 | 
			
		||||
        restClient.assertStatusCodeIs(OK);
 | 
			
		||||
        assertTrue(childCategoriesList.getEntries().stream()
 | 
			
		||||
                .map(RestCategoryModel::onModel)
 | 
			
		||||
                .map(RestCategoryModel::getId)
 | 
			
		||||
                .collect(Collectors.toList())
 | 
			
		||||
                .contains(createdCategory.getId()));
 | 
			
		||||
 | 
			
		||||
        STEP("Create 2 more categories under newCategoryUnderRoot and make sure they are returned as children");
 | 
			
		||||
        final int categoriesCount = 2;
 | 
			
		||||
        final List<RestCategoryModel> categoriesToCreate = CreateCategoriesTests.getCategoriesToCreate(categoriesCount);
 | 
			
		||||
        final RestCategoryModelsCollection createdSubCategories = restClient.authenticateUser(dataUser.getAdminUser())
 | 
			
		||||
                .withCoreAPI()
 | 
			
		||||
                .usingCategory(createdCategory)
 | 
			
		||||
                .createCategoriesList(categoriesToCreate);
 | 
			
		||||
        restClient.assertStatusCodeIs(CREATED);
 | 
			
		||||
        childCategoriesList = restClient.authenticateUser(user).withCoreAPI().usingCategory(rootCategory).getCategoryChildren();
 | 
			
		||||
        restClient.assertStatusCodeIs(OK);
 | 
			
		||||
        childCategoriesList.getEntries().containsAll(createdSubCategories.getEntries());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check we get an error when passing folder node id as parent category id when getting children.
 | 
			
		||||
     */
 | 
			
		||||
    @Test(groups = {TestGroup.REST_API})
 | 
			
		||||
    public void testGetCategoryChildrenProvidingFolderAsId()
 | 
			
		||||
    {
 | 
			
		||||
        STEP("Create a site and a folder inside it");
 | 
			
		||||
        final SiteModel site = dataSite.usingUser(user).createPublicRandomSite();
 | 
			
		||||
        final FolderModel folder = dataContent.usingUser(user).usingSite(site).createFolder();
 | 
			
		||||
 | 
			
		||||
        STEP("Get category children with folder id passed as parent id");
 | 
			
		||||
        final RestCategoryModel parentCategory = new RestCategoryModel();
 | 
			
		||||
        parentCategory.setId(folder.getNodeRef());
 | 
			
		||||
        restClient.authenticateUser(user).withCoreAPI().usingCategory(parentCategory).getCategoryChildren();
 | 
			
		||||
        restClient.assertStatusCodeIs(BAD_REQUEST).assertLastError().containsSummary("Node id does not refer to a valid category");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check we get an error when passing a non-existent node id as parent category id when getting children.
 | 
			
		||||
     */
 | 
			
		||||
    @Test(groups = {TestGroup.REST_API})
 | 
			
		||||
    public void testGetCategoryChildrenProvidingNonExistingParent()
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        STEP("Get category with folder id passed as id");
 | 
			
		||||
        final RestCategoryModel parentCategory = new RestCategoryModel();
 | 
			
		||||
        final String parentId = NON_EXISTING_CATEGORY_ID;
 | 
			
		||||
        parentCategory.setId(parentId);
 | 
			
		||||
        restClient.authenticateUser(user).withCoreAPI().usingCategory(parentCategory).getCategoryChildren();
 | 
			
		||||
        restClient.assertStatusCodeIs(NOT_FOUND).assertLastError().containsSummary(parentId);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -56,7 +56,6 @@ import java.util.Collections;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
import java.util.stream.IntStream;
 | 
			
		||||
import javax.json.Json;
 | 
			
		||||
import javax.json.JsonObject;
 | 
			
		||||
@@ -64,7 +63,6 @@ import javax.json.JsonObject;
 | 
			
		||||
import org.alfresco.rest.model.RestActionBodyExecTemplateModel;
 | 
			
		||||
import org.alfresco.rest.model.RestActionConstraintModel;
 | 
			
		||||
import org.alfresco.rest.model.RestCompositeConditionDefinitionModel;
 | 
			
		||||
import org.alfresco.rest.model.RestPaginationModel;
 | 
			
		||||
import org.alfresco.rest.model.RestRuleModel;
 | 
			
		||||
import org.alfresco.rest.model.RestRuleModelsCollection;
 | 
			
		||||
import org.alfresco.utility.constants.UserRole;
 | 
			
		||||
@@ -269,38 +267,6 @@ public class CreateRulesTests extends RulesRestTest
 | 
			
		||||
                    .assertThat().field("name").is(ruleNames.get(i)));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** Check we can create over 100 rules and get them all back in response. */
 | 
			
		||||
    @Test (groups = { TestGroup.REST_API, TestGroup.RULES })
 | 
			
		||||
    public void createOver100Rules()
 | 
			
		||||
    {
 | 
			
		||||
        STEP("Create a list of 120 rules in one POST request");
 | 
			
		||||
        final int ruleCount = 120;
 | 
			
		||||
        final String ruleNamePrefix = "multiRule";
 | 
			
		||||
        final List<RestRuleModel> ruleModels = IntStream.rangeClosed(1, ruleCount)
 | 
			
		||||
                .mapToObj(i -> rulesUtils.createRuleModel(ruleNamePrefix + i))
 | 
			
		||||
                .collect(Collectors.toList());
 | 
			
		||||
 | 
			
		||||
        final FolderModel aFolder = dataContent.usingUser(user).usingSite(site).createFolder();
 | 
			
		||||
        final RestRuleModelsCollection rules = restClient.authenticateUser(user).withPrivateAPI().usingNode(aFolder).usingDefaultRuleSet()
 | 
			
		||||
                .createListOfRules(ruleModels);
 | 
			
		||||
 | 
			
		||||
        restClient.assertStatusCodeIs(CREATED);
 | 
			
		||||
 | 
			
		||||
        assertEquals("Unexpected number of rules received in response.", ruleCount, rules.getEntries().size());
 | 
			
		||||
        IntStream.range(0, ruleModels.size()).forEach(i ->
 | 
			
		||||
                rules.getEntries().get(i).onModel()
 | 
			
		||||
                        .assertThat().field("id").isNotNull()
 | 
			
		||||
                        .assertThat().field("name").is(ruleNamePrefix + (i + 1)));
 | 
			
		||||
 | 
			
		||||
        rules.getPagination()
 | 
			
		||||
                .assertThat().field("count").is(ruleCount)
 | 
			
		||||
                .assertThat().field("totalItems").is(ruleCount)
 | 
			
		||||
                .assertThat().field("maxItems").is(ruleCount)
 | 
			
		||||
                .assertThat().field("skipCount").is(0)
 | 
			
		||||
                .assertThat().field("hasMoreItems").is(false);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** Try to create several rules with an error in one of them. */
 | 
			
		||||
    @Test (groups = { TestGroup.REST_API, TestGroup.RULES })
 | 
			
		||||
    public void createRulesWithOneError()
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo-tests</artifactId>
 | 
			
		||||
        <version>20.42</version>
 | 
			
		||||
        <version>20.36-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <developers>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo-packaging</artifactId>
 | 
			
		||||
        <version>20.42</version>
 | 
			
		||||
        <version>20.36-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <properties>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								pom.xml
									
									
									
									
									
								
							@@ -2,7 +2,7 @@
 | 
			
		||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 | 
			
		||||
    <modelVersion>4.0.0</modelVersion>
 | 
			
		||||
    <artifactId>alfresco-community-repo</artifactId>
 | 
			
		||||
    <version>20.42</version>
 | 
			
		||||
    <version>20.36-SNAPSHOT</version>
 | 
			
		||||
    <packaging>pom</packaging>
 | 
			
		||||
    <name>Alfresco Community Repo Parent</name>
 | 
			
		||||
 | 
			
		||||
@@ -109,8 +109,8 @@
 | 
			
		||||
        <dependency.jakarta-json-path.version>2.7.0</dependency.jakarta-json-path.version>
 | 
			
		||||
        <dependency.jakarta-rpc-api.version>1.1.4</dependency.jakarta-rpc-api.version>
 | 
			
		||||
 | 
			
		||||
        <alfresco.googledrive.version>3.4.0-A1</alfresco.googledrive.version>
 | 
			
		||||
        <alfresco.aos-module.version>1.6.0-A1</alfresco.aos-module.version>
 | 
			
		||||
        <alfresco.googledrive.version>3.3.1-DEV-LOG4J2</alfresco.googledrive.version>
 | 
			
		||||
        <alfresco.aos-module.version>1.5.0-DEV-LOG4J2</alfresco.aos-module.version>
 | 
			
		||||
        <alfresco.api-explorer.version>7.3.0</alfresco.api-explorer.version> <!-- Also in alfresco-enterprise-share -->
 | 
			
		||||
 | 
			
		||||
        <alfresco.maven-plugin.version>2.2.0</alfresco.maven-plugin.version>
 | 
			
		||||
@@ -148,7 +148,7 @@
 | 
			
		||||
        <connection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</connection>
 | 
			
		||||
        <developerConnection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</developerConnection>
 | 
			
		||||
        <url>https://github.com/Alfresco/alfresco-community-repo</url>
 | 
			
		||||
        <tag>20.42</tag>
 | 
			
		||||
        <tag>HEAD</tag>
 | 
			
		||||
    </scm>
 | 
			
		||||
 | 
			
		||||
    <distributionManagement>
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo</artifactId>
 | 
			
		||||
        <version>20.42</version>
 | 
			
		||||
        <version>20.36-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <dependencies>
 | 
			
		||||
 
 | 
			
		||||
@@ -26,22 +26,13 @@
 | 
			
		||||
 | 
			
		||||
package org.alfresco.rest.api;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import org.alfresco.rest.api.model.Category;
 | 
			
		||||
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
 | 
			
		||||
import org.alfresco.rest.framework.resource.parameters.Parameters;
 | 
			
		||||
import org.alfresco.service.Experimental;
 | 
			
		||||
import org.alfresco.service.cmr.repository.NodeRef;
 | 
			
		||||
 | 
			
		||||
@Experimental
 | 
			
		||||
public interface Categories
 | 
			
		||||
{
 | 
			
		||||
    Category getCategoryById(String id, Parameters params);
 | 
			
		||||
 | 
			
		||||
    List<Category> createSubcategories(String parentCategoryId, List<Category> categories, Parameters parameters);
 | 
			
		||||
 | 
			
		||||
    CollectionWithPagingInfo<Category> getCategoryChildren(String parentCategoryId, Parameters params);
 | 
			
		||||
 | 
			
		||||
    void deleteCategoryById(String id, Parameters params);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -41,8 +41,7 @@ import org.alfresco.rest.framework.resource.parameters.Parameters;
 | 
			
		||||
 * @author mpichura
 | 
			
		||||
 */
 | 
			
		||||
@EntityResource(name = "categories", title = "Categories")
 | 
			
		||||
public class CategoriesEntityResource implements EntityResourceAction.ReadById<Category>,
 | 
			
		||||
                                                EntityResourceAction.Delete
 | 
			
		||||
public class CategoriesEntityResource implements EntityResourceAction.ReadById<Category>
 | 
			
		||||
{
 | 
			
		||||
    private final Categories categories;
 | 
			
		||||
 | 
			
		||||
@@ -59,12 +58,4 @@ public class CategoriesEntityResource implements EntityResourceAction.ReadById<C
 | 
			
		||||
    {
 | 
			
		||||
        return categories.getCategoryById(id, parameters);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @WebApiDescription(title = "Delete category",
 | 
			
		||||
                description = "Delete a category given its node id",
 | 
			
		||||
                successStatus = HttpServletResponse.SC_NO_CONTENT)
 | 
			
		||||
    @Override
 | 
			
		||||
    public void delete(String id, Parameters parameters) {
 | 
			
		||||
        categories.deleteCategoryById(id, parameters);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,69 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * #%L
 | 
			
		||||
 * Alfresco Remote API
 | 
			
		||||
 * %%
 | 
			
		||||
 * Copyright (C) 2005 - 2022 Alfresco Software Limited
 | 
			
		||||
 * %%
 | 
			
		||||
 * This file is part of the Alfresco software.
 | 
			
		||||
 * If the software was purchased under a paid Alfresco license, the terms of
 | 
			
		||||
 * the paid license agreement will prevail.  Otherwise, the software is
 | 
			
		||||
 * provided under the following open source license terms:
 | 
			
		||||
 *
 | 
			
		||||
 * Alfresco is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Lesser General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * Alfresco is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 *  GNU Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 * #L%
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.alfresco.rest.api.categories;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import javax.servlet.http.HttpServletResponse;
 | 
			
		||||
 | 
			
		||||
import org.alfresco.rest.api.Categories;
 | 
			
		||||
import org.alfresco.rest.api.model.Category;
 | 
			
		||||
import org.alfresco.rest.framework.WebApiDescription;
 | 
			
		||||
import org.alfresco.rest.framework.resource.RelationshipResource;
 | 
			
		||||
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction;
 | 
			
		||||
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
 | 
			
		||||
import org.alfresco.rest.framework.resource.parameters.Parameters;
 | 
			
		||||
 | 
			
		||||
@RelationshipResource(name = "subcategories",  entityResource = CategoriesEntityResource.class, title = "Subcategories")
 | 
			
		||||
public class SubcategoriesRelation implements RelationshipResourceAction.Create<Category>, RelationshipResourceAction.Read<Category>
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    private final Categories categories;
 | 
			
		||||
 | 
			
		||||
    public SubcategoriesRelation(Categories categories)
 | 
			
		||||
    {
 | 
			
		||||
        this.categories = categories;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @WebApiDescription(title = "Create a category",
 | 
			
		||||
            description = "Creates one or more categories under a parent category",
 | 
			
		||||
            successStatus = HttpServletResponse.SC_CREATED)
 | 
			
		||||
    @Override
 | 
			
		||||
    public List<Category> create(String parentCategoryId, List<Category> categoryList, Parameters parameters)
 | 
			
		||||
    {
 | 
			
		||||
        return categories.createSubcategories(parentCategoryId, categoryList, parameters);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @WebApiDescription(title = "List category direct children",
 | 
			
		||||
            description = "Lists direct children of a parent category",
 | 
			
		||||
            successStatus = HttpServletResponse.SC_OK)
 | 
			
		||||
    @Override
 | 
			
		||||
    public CollectionWithPagingInfo<Category> readAll(String parentCategoryId, Parameters params)
 | 
			
		||||
    {
 | 
			
		||||
        return categories.getCategoryChildren(parentCategoryId, params);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -29,47 +29,31 @@ package org.alfresco.rest.api.impl;
 | 
			
		||||
import static org.alfresco.rest.api.Nodes.PATH_ROOT;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
 | 
			
		||||
import org.alfresco.model.ContentModel;
 | 
			
		||||
import org.alfresco.rest.api.Categories;
 | 
			
		||||
import org.alfresco.rest.api.Nodes;
 | 
			
		||||
import org.alfresco.rest.api.model.Category;
 | 
			
		||||
import org.alfresco.rest.api.model.Node;
 | 
			
		||||
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
 | 
			
		||||
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
 | 
			
		||||
import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException;
 | 
			
		||||
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
 | 
			
		||||
import org.alfresco.rest.framework.resource.parameters.ListPage;
 | 
			
		||||
import org.alfresco.rest.framework.resource.parameters.Parameters;
 | 
			
		||||
import org.alfresco.service.Experimental;
 | 
			
		||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
 | 
			
		||||
import org.alfresco.service.cmr.repository.NodeRef;
 | 
			
		||||
import org.alfresco.service.cmr.repository.NodeService;
 | 
			
		||||
import org.alfresco.service.cmr.repository.StoreRef;
 | 
			
		||||
import org.alfresco.service.cmr.search.CategoryService;
 | 
			
		||||
import org.alfresco.service.cmr.security.AuthorityService;
 | 
			
		||||
import org.alfresco.service.namespace.RegexQNamePattern;
 | 
			
		||||
import org.apache.commons.collections.CollectionUtils;
 | 
			
		||||
import org.apache.commons.lang3.StringUtils;
 | 
			
		||||
 | 
			
		||||
@Experimental
 | 
			
		||||
public class CategoriesImpl implements Categories
 | 
			
		||||
{
 | 
			
		||||
    static final String NOT_A_VALID_CATEGORY = "Node id does not refer to a valid category";
 | 
			
		||||
    static final String NO_PERMISSION_TO_CREATE_A_CATEGORY = "Current user does not have permission to create a category";
 | 
			
		||||
    static final String NO_PERMISSION_TO_DELETE_A_CATEGORY = "Current user does not have permission to delete a category";
 | 
			
		||||
    private static final String NOT_NULL_OR_EMPTY = "Category name must not be null or empty";
 | 
			
		||||
 | 
			
		||||
    private final AuthorityService authorityService;
 | 
			
		||||
    private final CategoryService categoryService;
 | 
			
		||||
    private final Nodes nodes;
 | 
			
		||||
    private final NodeService nodeService;
 | 
			
		||||
 | 
			
		||||
    public CategoriesImpl(AuthorityService authorityService, CategoryService categoryService, Nodes nodes, NodeService nodeService)
 | 
			
		||||
    public CategoriesImpl(Nodes nodes, NodeService nodeService)
 | 
			
		||||
    {
 | 
			
		||||
        this.authorityService = authorityService;
 | 
			
		||||
        this.categoryService = categoryService;
 | 
			
		||||
        this.nodes = nodes;
 | 
			
		||||
        this.nodeService = nodeService;
 | 
			
		||||
    }
 | 
			
		||||
@@ -77,121 +61,28 @@ public class CategoriesImpl implements Categories
 | 
			
		||||
    @Override
 | 
			
		||||
    public Category getCategoryById(final String id, final Parameters params)
 | 
			
		||||
    {
 | 
			
		||||
        final NodeRef nodeRef = getCategoryNodeRef(id);
 | 
			
		||||
        if (isRootCategory(nodeRef))
 | 
			
		||||
        {
 | 
			
		||||
            throw new InvalidArgumentException(NOT_A_VALID_CATEGORY, new String[]{id});
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return mapToCategory(nodeRef);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public List<Category> createSubcategories(String parentCategoryId, List<Category> categories, Parameters parameters)
 | 
			
		||||
    {
 | 
			
		||||
        if (!authorityService.hasAdminAuthority())
 | 
			
		||||
        {
 | 
			
		||||
            throw new PermissionDeniedException(NO_PERMISSION_TO_CREATE_A_CATEGORY);
 | 
			
		||||
        }
 | 
			
		||||
        final NodeRef parentNodeRef = getCategoryNodeRef(parentCategoryId);
 | 
			
		||||
        final List<NodeRef> categoryNodeRefs = categories.stream()
 | 
			
		||||
                .map(c -> createCategoryNodeRef(parentNodeRef, c))
 | 
			
		||||
                .collect(Collectors.toList());
 | 
			
		||||
        return categoryNodeRefs.stream()
 | 
			
		||||
                .map(this::mapToCategory)
 | 
			
		||||
                .collect(Collectors.toList());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public CollectionWithPagingInfo<Category> getCategoryChildren(String parentCategoryId, Parameters params)
 | 
			
		||||
    {
 | 
			
		||||
        final NodeRef parentNodeRef = getCategoryNodeRef(parentCategoryId);
 | 
			
		||||
        final List<ChildAssociationRef> childCategoriesAssocs = nodeService.getChildAssocs(parentNodeRef).stream()
 | 
			
		||||
                .filter(ca -> ContentModel.ASSOC_SUBCATEGORIES.equals(ca.getTypeQName()))
 | 
			
		||||
                .collect(Collectors.toList());
 | 
			
		||||
        final List<Category> categories = childCategoriesAssocs.stream()
 | 
			
		||||
                .map(c -> mapToCategory(c.getChildRef()))
 | 
			
		||||
                .collect(Collectors.toList());
 | 
			
		||||
        return ListPage.of(categories, params.getPaging());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void deleteCategoryById(String id, Parameters params)
 | 
			
		||||
    {
 | 
			
		||||
        if (!authorityService.hasAdminAuthority())
 | 
			
		||||
        {
 | 
			
		||||
            throw new PermissionDeniedException(NO_PERMISSION_TO_DELETE_A_CATEGORY);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        final NodeRef nodeRef = nodes.validateNode(id);
 | 
			
		||||
        if (isNotACategory(nodeRef) || isRootCategory(nodeRef))
 | 
			
		||||
        final boolean isCategory = nodes.isSubClass(nodeRef, ContentModel.TYPE_CATEGORY, false);
 | 
			
		||||
        if (!isCategory || isRootCategory(nodeRef))
 | 
			
		||||
        {
 | 
			
		||||
            throw new InvalidArgumentException(NOT_A_VALID_CATEGORY, new String[]{id});
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        nodeService.deleteNode(nodeRef);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * This method gets category NodeRef for a given category id.
 | 
			
		||||
     * If '-root-' is passed as category id, then it's retrieved as a call to {@link org.alfresco.service.cmr.search.CategoryService#getRootCategoryNodeRef}
 | 
			
		||||
     * In all other cases it's retrieved as a node of a category type {@link #validateCategoryNode(String)}
 | 
			
		||||
     * @param nodeId category node id
 | 
			
		||||
     * @return NodRef of category node
 | 
			
		||||
     */
 | 
			
		||||
    private NodeRef getCategoryNodeRef(String nodeId)
 | 
			
		||||
    {
 | 
			
		||||
        return PATH_ROOT.equals(nodeId) ?
 | 
			
		||||
                categoryService.getRootCategoryNodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE)
 | 
			
		||||
                        .orElseThrow(() -> new EntityNotFoundException(nodeId)) :
 | 
			
		||||
                validateCategoryNode(nodeId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Validates if the node exists and is a category.
 | 
			
		||||
     * @param nodeId (presumably) category node id
 | 
			
		||||
     * @return category NodeRef
 | 
			
		||||
     */
 | 
			
		||||
    private NodeRef validateCategoryNode(String nodeId)
 | 
			
		||||
    {
 | 
			
		||||
        final NodeRef nodeRef = nodes.validateNode(nodeId);
 | 
			
		||||
        if (isNotACategory(nodeRef))
 | 
			
		||||
        {
 | 
			
		||||
            throw new InvalidArgumentException(NOT_A_VALID_CATEGORY, new String[]{nodeId});
 | 
			
		||||
        }
 | 
			
		||||
        return nodeRef;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private NodeRef createCategoryNodeRef(NodeRef parentNodeRef, Category c)
 | 
			
		||||
    {
 | 
			
		||||
        if (StringUtils.isEmpty(c.getName())) {
 | 
			
		||||
            throw new InvalidArgumentException(NOT_NULL_OR_EMPTY);
 | 
			
		||||
        }
 | 
			
		||||
        return categoryService.createCategory(parentNodeRef, c.getName());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean isNotACategory(NodeRef nodeRef)
 | 
			
		||||
    {
 | 
			
		||||
        return !nodes.isSubClass(nodeRef, ContentModel.TYPE_CATEGORY, false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Category mapToCategory(NodeRef nodeRef)
 | 
			
		||||
    {
 | 
			
		||||
        final Node categoryNode = nodes.getNode(nodeRef.getId());
 | 
			
		||||
        final Category category = new Category();
 | 
			
		||||
        category.setId(nodeRef.getId());
 | 
			
		||||
        category.setName(categoryNode.getName());
 | 
			
		||||
        category.setParentId(getParentId(nodeRef));
 | 
			
		||||
        final boolean hasChildren = CollectionUtils
 | 
			
		||||
                .isNotEmpty(nodeService.getChildAssocs(nodeRef, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false));
 | 
			
		||||
        return Category.builder()
 | 
			
		||||
                .id(nodeRef.getId())
 | 
			
		||||
                .name(categoryNode.getName())
 | 
			
		||||
                .parentId(getParentId(nodeRef))
 | 
			
		||||
                .hasChildren(hasChildren)
 | 
			
		||||
                .create();
 | 
			
		||||
        category.setHasChildren(hasChildren);
 | 
			
		||||
 | 
			
		||||
        return category;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean isRootCategory(final NodeRef nodeRef)
 | 
			
		||||
    {
 | 
			
		||||
        final List<ChildAssociationRef> parentAssocs = nodeService.getParentAssocs(nodeRef);
 | 
			
		||||
        return parentAssocs.stream().anyMatch(pa -> ContentModel.ASPECT_GEN_CLASSIFIABLE.equals(pa.getQName()));
 | 
			
		||||
        return parentAssocs.stream().anyMatch(pa -> pa.getQName().equals(ContentModel.ASPECT_GEN_CLASSIFIABLE));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private String getParentId(final NodeRef nodeRef)
 | 
			
		||||
 
 | 
			
		||||
@@ -26,8 +26,6 @@
 | 
			
		||||
 | 
			
		||||
package org.alfresco.rest.api.model;
 | 
			
		||||
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
public class Category
 | 
			
		||||
{
 | 
			
		||||
    private String id;
 | 
			
		||||
@@ -74,68 +72,4 @@ public class Category
 | 
			
		||||
    {
 | 
			
		||||
        this.hasChildren = hasChildren;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean equals(Object o)
 | 
			
		||||
    {
 | 
			
		||||
        if (this == o) return true;
 | 
			
		||||
        if (o == null || getClass() != o.getClass()) return false;
 | 
			
		||||
        Category category = (Category) o;
 | 
			
		||||
        return hasChildren == category.hasChildren && Objects.equals(id, category.id) && name.equals(category.name) &&
 | 
			
		||||
                Objects.equals(parentId, category.parentId);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int hashCode()
 | 
			
		||||
    {
 | 
			
		||||
        return Objects.hash(id, name, parentId, hasChildren);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static Builder builder()
 | 
			
		||||
    {
 | 
			
		||||
        return new Builder();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class Builder
 | 
			
		||||
    {
 | 
			
		||||
        private String id;
 | 
			
		||||
        private String name;
 | 
			
		||||
        private String parentId;
 | 
			
		||||
        private boolean hasChildren;
 | 
			
		||||
 | 
			
		||||
        public Builder id(String id)
 | 
			
		||||
        {
 | 
			
		||||
            this.id = id;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Builder name(String name)
 | 
			
		||||
        {
 | 
			
		||||
            this.name = name;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Builder parentId(String parentId)
 | 
			
		||||
        {
 | 
			
		||||
            this.parentId = parentId;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Builder hasChildren(boolean hasChildren)
 | 
			
		||||
        {
 | 
			
		||||
            this.hasChildren = hasChildren;
 | 
			
		||||
            return this;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Category create()
 | 
			
		||||
        {
 | 
			
		||||
            final Category category = new Category();
 | 
			
		||||
            category.setId(id);
 | 
			
		||||
            category.setName(name);
 | 
			
		||||
            category.setParentId(parentId);
 | 
			
		||||
            category.setHasChildren(hasChildren);
 | 
			
		||||
            return category;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,39 @@
 | 
			
		||||
/*
 | 
			
		||||
 * #%L
 | 
			
		||||
 * Alfresco Remote API
 | 
			
		||||
 * %%
 | 
			
		||||
 * Copyright (C) 2005 - 2016 Alfresco Software Limited
 | 
			
		||||
 * %%
 | 
			
		||||
 * This file is part of the Alfresco software.
 | 
			
		||||
 * If the software was purchased under a paid Alfresco license, the terms of
 | 
			
		||||
 * the paid license agreement will prevail.  Otherwise, the software is
 | 
			
		||||
 * provided under the following open source license terms:
 | 
			
		||||
 *
 | 
			
		||||
 * Alfresco is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Lesser General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * Alfresco is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 * #L%
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.alfresco.rest.framework.core.exceptions;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * The addressed Relationship Resource was not found
 | 
			
		||||
 */
 | 
			
		||||
public class EventAlreadyExistsException extends ApiException {
 | 
			
		||||
 | 
			
		||||
    private static final long serialVersionUID = -3675294374348951929L;
 | 
			
		||||
 | 
			
		||||
    public EventAlreadyExistsException(String msgId, Object[] msgParams) {
 | 
			
		||||
        super(msgId, msgParams);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -44,7 +44,6 @@ import org.alfresco.rest.framework.resource.actions.interfaces.MultiPartResource
 | 
			
		||||
import org.alfresco.rest.framework.resource.actions.interfaces.MultiPartRelationshipResourceAction;
 | 
			
		||||
import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction;
 | 
			
		||||
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
 | 
			
		||||
import org.alfresco.rest.framework.resource.parameters.Paging;
 | 
			
		||||
import org.alfresco.rest.framework.resource.parameters.Params;
 | 
			
		||||
import org.alfresco.rest.framework.resource.parameters.Params.RecognizedParams;
 | 
			
		||||
import org.alfresco.rest.framework.tools.RecognizedParamsExtractor;
 | 
			
		||||
@@ -378,8 +377,7 @@ public class ResourceWebScriptPost extends AbstractResourceWebScript implements
 | 
			
		||||
    {
 | 
			
		||||
        if (created !=null && created.size() > 1)
 | 
			
		||||
        {
 | 
			
		||||
            final Paging pagingAll = Paging.valueOf(0, created.size());
 | 
			
		||||
            return CollectionWithPagingInfo.asPaged(pagingAll, created);
 | 
			
		||||
            return CollectionWithPagingInfo.asPagedCollection(created.toArray());
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
 
 | 
			
		||||
@@ -7,6 +7,8 @@ framework.exception.InvalidQuery=An invalid WHERE query was received. {0}
 | 
			
		||||
framework.exception.InvalidSelect=An invalid {1} query was received. {0}
 | 
			
		||||
framework.exception.NotFound={0} was not found
 | 
			
		||||
framework.exception.EntityNotFound=The entity with id: {0} was not found
 | 
			
		||||
framework.exception.CreateEventAlreadyExists=Cannot create event. An event with name: {0} already exists
 | 
			
		||||
framework.exception.UpdateEventAlreadyExists=Cannot update event. An event with name: {0} already exists
 | 
			
		||||
framework.exception.RelationshipNotFound=The relationship resource was not found for the entity with id: {0} and a relationship id of {1}
 | 
			
		||||
framework.exception.PermissionDenied=Permission was denied
 | 
			
		||||
framework.exception.StaleEntity=Attempt to update a stale entity
 | 
			
		||||
 
 | 
			
		||||
@@ -830,8 +830,6 @@
 | 
			
		||||
    </bean>
 | 
			
		||||
 | 
			
		||||
    <bean id="categories" class="org.alfresco.rest.api.impl.CategoriesImpl">
 | 
			
		||||
        <constructor-arg name="authorityService" ref="AuthorityService"/>
 | 
			
		||||
        <constructor-arg name="categoryService" ref="CategoryService"/>
 | 
			
		||||
        <constructor-arg name="nodes" ref="nodes"/>
 | 
			
		||||
        <constructor-arg name="nodeService" ref="NodeService"/>
 | 
			
		||||
    </bean>
 | 
			
		||||
@@ -1101,14 +1099,10 @@
 | 
			
		||||
        <constructor-arg name="categories" ref="Categories"/>
 | 
			
		||||
    </bean>
 | 
			
		||||
 | 
			
		||||
    <bean class="org.alfresco.rest.api.categories.SubcategoriesRelation">
 | 
			
		||||
        <constructor-arg name="categories" ref="Categories"/>
 | 
			
		||||
    </bean>
 | 
			
		||||
 | 
			
		||||
    <bean class="org.alfresco.rest.api.tags.TagsEntityResource">
 | 
			
		||||
        <property name="tags" ref="Tags" />
 | 
			
		||||
    </bean>
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
    <bean class="org.alfresco.rest.api.people.PersonSitesRelation">
 | 
			
		||||
        <property name="sites" ref="Sites" />
 | 
			
		||||
    </bean>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,105 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * #%L
 | 
			
		||||
 * Alfresco Remote API
 | 
			
		||||
 * %%
 | 
			
		||||
 * Copyright (C) 2005 - 2022 Alfresco Software Limited
 | 
			
		||||
 * %%
 | 
			
		||||
 * This file is part of the Alfresco software.
 | 
			
		||||
 * If the software was purchased under a paid Alfresco license, the terms of
 | 
			
		||||
 * the paid license agreement will prevail.  Otherwise, the software is
 | 
			
		||||
 * provided under the following open source license terms:
 | 
			
		||||
 *
 | 
			
		||||
 * Alfresco is free software: you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU Lesser General Public License as published by
 | 
			
		||||
 * the Free Software Foundation, either version 3 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * Alfresco is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 *  GNU Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General Public License
 | 
			
		||||
 * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
 | 
			
		||||
 * #L%
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.alfresco.rest.api.categories;
 | 
			
		||||
 | 
			
		||||
import static org.junit.Assert.assertEquals;
 | 
			
		||||
import static org.mockito.BDDMockito.given;
 | 
			
		||||
import static org.mockito.BDDMockito.then;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
import java.util.stream.IntStream;
 | 
			
		||||
 | 
			
		||||
import org.alfresco.rest.api.Categories;
 | 
			
		||||
import org.alfresco.rest.api.model.Category;
 | 
			
		||||
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
 | 
			
		||||
import org.alfresco.rest.framework.resource.parameters.Paging;
 | 
			
		||||
import org.alfresco.rest.framework.resource.parameters.Parameters;
 | 
			
		||||
import org.junit.Test;
 | 
			
		||||
import org.junit.runner.RunWith;
 | 
			
		||||
import org.mockito.InjectMocks;
 | 
			
		||||
import org.mockito.Mock;
 | 
			
		||||
import org.mockito.junit.MockitoJUnitRunner;
 | 
			
		||||
 | 
			
		||||
@RunWith(MockitoJUnitRunner.class)
 | 
			
		||||
public class SubcategoriesRelationTest
 | 
			
		||||
{
 | 
			
		||||
    private static final String PARENT_CATEGORY_ID = "parent-category-node-id";
 | 
			
		||||
    private static final String CATEGORY_ID = "category-node-id";
 | 
			
		||||
    private static final String CATEGORY_NAME = "categoryName";
 | 
			
		||||
    private static final String SUBCATEGORY_NAME_PREFIX = "childCategoryName";
 | 
			
		||||
 | 
			
		||||
    @Mock
 | 
			
		||||
    private Categories categoriesMock;
 | 
			
		||||
    @Mock
 | 
			
		||||
    private Parameters parametersMock;
 | 
			
		||||
 | 
			
		||||
    @InjectMocks
 | 
			
		||||
    private SubcategoriesRelation objectUnderTest;
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testCreateSubcategory()
 | 
			
		||||
    {
 | 
			
		||||
        final Category categoryToCreate = Category.builder().name(CATEGORY_NAME).create();
 | 
			
		||||
        final Category category = Category.builder().name(CATEGORY_NAME).parentId(PARENT_CATEGORY_ID).hasChildren(false).id(CATEGORY_ID).create();
 | 
			
		||||
        final List<Category> categoriesToCreate = List.of(categoryToCreate);
 | 
			
		||||
        given(categoriesMock.createSubcategories(PARENT_CATEGORY_ID, categoriesToCreate, parametersMock)).willReturn(List.of(category));
 | 
			
		||||
 | 
			
		||||
        //when
 | 
			
		||||
        List<Category> categories = objectUnderTest.create(PARENT_CATEGORY_ID, categoriesToCreate, parametersMock);
 | 
			
		||||
 | 
			
		||||
        then(categoriesMock).should().createSubcategories(PARENT_CATEGORY_ID, categoriesToCreate, parametersMock);
 | 
			
		||||
        then(categoriesMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
        assertEquals(List.of(category), categories);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testGetCategoryChildren() {
 | 
			
		||||
        final CollectionWithPagingInfo<Category> categoryChildren = getCategories(3);
 | 
			
		||||
        given(categoriesMock.getCategoryChildren(PARENT_CATEGORY_ID, parametersMock)).willReturn(categoryChildren);
 | 
			
		||||
 | 
			
		||||
        //when
 | 
			
		||||
        final CollectionWithPagingInfo<Category> returnedChildren = objectUnderTest.readAll(PARENT_CATEGORY_ID, parametersMock);
 | 
			
		||||
 | 
			
		||||
        then(categoriesMock).should().getCategoryChildren(PARENT_CATEGORY_ID, parametersMock);
 | 
			
		||||
        then(categoriesMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
        assertEquals(categoryChildren, returnedChildren);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private CollectionWithPagingInfo<Category> getCategories(final int count)
 | 
			
		||||
    {
 | 
			
		||||
        return CollectionWithPagingInfo.asPaged(Paging.DEFAULT,
 | 
			
		||||
                IntStream.range(0, count)
 | 
			
		||||
                        .mapToObj(i -> Category.builder().name(SUBCATEGORY_NAME_PREFIX + "-" + i)
 | 
			
		||||
                            .parentId(PARENT_CATEGORY_ID)
 | 
			
		||||
                            .hasChildren(false)
 | 
			
		||||
                            .id(CATEGORY_ID + "-" + i)
 | 
			
		||||
                            .create())
 | 
			
		||||
                        .collect(Collectors.toList())
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -26,20 +26,15 @@
 | 
			
		||||
 | 
			
		||||
package org.alfresco.rest.api.impl;
 | 
			
		||||
 | 
			
		||||
import static org.alfresco.rest.api.Nodes.PATH_ROOT;
 | 
			
		||||
import static org.junit.Assert.assertEquals;
 | 
			
		||||
import static org.junit.Assert.assertFalse;
 | 
			
		||||
import static org.junit.Assert.assertThrows;
 | 
			
		||||
import static org.junit.Assert.assertTrue;
 | 
			
		||||
import static org.mockito.BDDMockito.given;
 | 
			
		||||
import static org.mockito.BDDMockito.then;
 | 
			
		||||
import static org.mockito.Mockito.mock;
 | 
			
		||||
import static org.mockito.Mockito.times;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Optional;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
import java.util.stream.IntStream;
 | 
			
		||||
 | 
			
		||||
import org.alfresco.model.ContentModel;
 | 
			
		||||
import org.alfresco.rest.api.Nodes;
 | 
			
		||||
@@ -47,15 +42,11 @@ import org.alfresco.rest.api.model.Category;
 | 
			
		||||
import org.alfresco.rest.api.model.Node;
 | 
			
		||||
import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException;
 | 
			
		||||
import org.alfresco.rest.framework.core.exceptions.InvalidArgumentException;
 | 
			
		||||
import org.alfresco.rest.framework.core.exceptions.PermissionDeniedException;
 | 
			
		||||
import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo;
 | 
			
		||||
import org.alfresco.rest.framework.resource.parameters.Parameters;
 | 
			
		||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
 | 
			
		||||
import org.alfresco.service.cmr.repository.NodeRef;
 | 
			
		||||
import org.alfresco.service.cmr.repository.NodeService;
 | 
			
		||||
import org.alfresco.service.cmr.repository.StoreRef;
 | 
			
		||||
import org.alfresco.service.cmr.search.CategoryService;
 | 
			
		||||
import org.alfresco.service.cmr.security.AuthorityService;
 | 
			
		||||
import org.alfresco.service.namespace.RegexQNamePattern;
 | 
			
		||||
import org.junit.Test;
 | 
			
		||||
import org.junit.runner.RunWith;
 | 
			
		||||
@@ -78,10 +69,6 @@ public class CategoriesImplTest
 | 
			
		||||
    @Mock
 | 
			
		||||
    private Parameters parametersMock;
 | 
			
		||||
    @Mock
 | 
			
		||||
    private AuthorityService authorityServiceMock;
 | 
			
		||||
    @Mock
 | 
			
		||||
    private CategoryService categoryServiceMock;
 | 
			
		||||
    @Mock
 | 
			
		||||
    private ChildAssociationRef dummyChildAssociationRefMock;
 | 
			
		||||
    @Mock
 | 
			
		||||
    private ChildAssociationRef categoryChildAssociationRefMock;
 | 
			
		||||
@@ -106,8 +93,6 @@ public class CategoriesImplTest
 | 
			
		||||
        then(nodesMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
        then(nodeServiceMock).should().getParentAssocs(categoryRootNodeRef);
 | 
			
		||||
        then(nodeServiceMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
        then(categoryServiceMock).shouldHaveNoInteractions();
 | 
			
		||||
        then(authorityServiceMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
@@ -141,16 +126,10 @@ public class CategoriesImplTest
 | 
			
		||||
        then(nodeServiceMock).should().getChildAssocs(categoryNodeRef, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false);
 | 
			
		||||
        then(nodeServiceMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
 | 
			
		||||
        then(categoryServiceMock).shouldHaveNoInteractions();
 | 
			
		||||
        then(authorityServiceMock).shouldHaveNoInteractions();
 | 
			
		||||
 | 
			
		||||
        final Category expectedCategory = Category.builder()
 | 
			
		||||
                .id(CATEGORY_ID)
 | 
			
		||||
                .name(categoryNode.getName())
 | 
			
		||||
                .hasChildren(true)
 | 
			
		||||
                .parentId(PARENT_ID)
 | 
			
		||||
                .create();
 | 
			
		||||
        assertEquals(expectedCategory, category);
 | 
			
		||||
        assertEquals(categoryNode.getName(), category.getName());
 | 
			
		||||
        assertEquals(CATEGORY_ID, category.getId());
 | 
			
		||||
        assertEquals(PARENT_ID, category.getParentId());
 | 
			
		||||
        assertTrue(category.getHasChildren());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
@@ -183,16 +162,10 @@ public class CategoriesImplTest
 | 
			
		||||
        then(nodeServiceMock).should().getChildAssocs(categoryNodeRef, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false);
 | 
			
		||||
        then(nodeServiceMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
 | 
			
		||||
        then(categoryServiceMock).shouldHaveNoInteractions();
 | 
			
		||||
        then(authorityServiceMock).shouldHaveNoInteractions();
 | 
			
		||||
 | 
			
		||||
        final Category expectedCategory = Category.builder()
 | 
			
		||||
                .id(CATEGORY_ID)
 | 
			
		||||
                .name(categoryNode.getName())
 | 
			
		||||
                .hasChildren(false)
 | 
			
		||||
                .parentId(PARENT_ID)
 | 
			
		||||
                .create();
 | 
			
		||||
        assertEquals(expectedCategory, category);
 | 
			
		||||
        assertEquals(categoryNode.getName(), category.getName());
 | 
			
		||||
        assertEquals(CATEGORY_ID, category.getId());
 | 
			
		||||
        assertEquals(PARENT_ID, category.getParentId());
 | 
			
		||||
        assertFalse(category.getHasChildren());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
@@ -210,8 +183,6 @@ public class CategoriesImplTest
 | 
			
		||||
        then(nodesMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
 | 
			
		||||
        then(nodeServiceMock).shouldHaveNoInteractions();
 | 
			
		||||
        then(categoryServiceMock).shouldHaveNoInteractions();
 | 
			
		||||
        then(authorityServiceMock).shouldHaveNoInteractions();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
@@ -226,430 +197,5 @@ public class CategoriesImplTest
 | 
			
		||||
        then(nodesMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
 | 
			
		||||
        then(nodeServiceMock).shouldHaveNoInteractions();
 | 
			
		||||
        then(categoryServiceMock).shouldHaveNoInteractions();
 | 
			
		||||
        then(authorityServiceMock).shouldHaveNoInteractions();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testDeleteCategoryById_asAdmin()
 | 
			
		||||
    {
 | 
			
		||||
        given(authorityServiceMock.hasAdminAuthority()).willReturn(true);
 | 
			
		||||
        final NodeRef categoryNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, CATEGORY_ID);
 | 
			
		||||
        given(nodesMock.validateNode(CATEGORY_ID)).willReturn(categoryNodeRef);
 | 
			
		||||
        given(nodesMock.isSubClass(categoryNodeRef, ContentModel.TYPE_CATEGORY, false)).willReturn(true);
 | 
			
		||||
        final Node categoryNode = new Node();
 | 
			
		||||
        categoryNode.setName(CATEGORY_NAME);
 | 
			
		||||
        categoryNode.setNodeId(CATEGORY_ID);
 | 
			
		||||
        final NodeRef parentNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, PARENT_ID);
 | 
			
		||||
        categoryNode.setParentId(parentNodeRef);
 | 
			
		||||
 | 
			
		||||
        //when
 | 
			
		||||
        objectUnderTest.deleteCategoryById(CATEGORY_ID, parametersMock);
 | 
			
		||||
 | 
			
		||||
        then(authorityServiceMock).should().hasAdminAuthority();
 | 
			
		||||
        then(authorityServiceMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
        then(nodesMock).should().validateNode(CATEGORY_ID);
 | 
			
		||||
 | 
			
		||||
        then(nodesMock).should().isSubClass(categoryNodeRef, ContentModel.TYPE_CATEGORY, false);
 | 
			
		||||
        then(nodesMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
 | 
			
		||||
        then(nodeServiceMock).should().getParentAssocs(categoryNodeRef);
 | 
			
		||||
        then(nodeServiceMock).should().deleteNode(categoryNodeRef);
 | 
			
		||||
        then(nodeServiceMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testDeleteCategoryById_asNonAdminUser()
 | 
			
		||||
    {
 | 
			
		||||
        given(authorityServiceMock.hasAdminAuthority()).willReturn(false);
 | 
			
		||||
 | 
			
		||||
        //when
 | 
			
		||||
        assertThrows(PermissionDeniedException.class, () -> objectUnderTest.deleteCategoryById(CATEGORY_ID, parametersMock));
 | 
			
		||||
 | 
			
		||||
        then(authorityServiceMock).should().hasAdminAuthority();
 | 
			
		||||
        then(authorityServiceMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
 | 
			
		||||
        then(nodesMock).shouldHaveNoInteractions();
 | 
			
		||||
        then(nodeServiceMock).shouldHaveNoInteractions();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testDeleteCategoryById_nonCategoryId()
 | 
			
		||||
    {
 | 
			
		||||
        given(authorityServiceMock.hasAdminAuthority()).willReturn(true);
 | 
			
		||||
        final NodeRef categoryNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, CATEGORY_ID);
 | 
			
		||||
        given(nodesMock.validateNode(CATEGORY_ID)).willReturn(categoryNodeRef);
 | 
			
		||||
        given(nodesMock.isSubClass(categoryNodeRef, ContentModel.TYPE_CATEGORY, false)).willReturn(false);
 | 
			
		||||
 | 
			
		||||
        //when
 | 
			
		||||
        assertThrows(InvalidArgumentException.class, () -> objectUnderTest.deleteCategoryById(CATEGORY_ID, parametersMock));
 | 
			
		||||
 | 
			
		||||
        then(authorityServiceMock).should().hasAdminAuthority();
 | 
			
		||||
        then(authorityServiceMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
 | 
			
		||||
        then(nodesMock).should().validateNode(CATEGORY_ID);
 | 
			
		||||
        then(nodesMock).should().isSubClass(categoryNodeRef, ContentModel.TYPE_CATEGORY, false);
 | 
			
		||||
        then(nodesMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testDeleteCategoryById_rootCategory()
 | 
			
		||||
    {
 | 
			
		||||
        given(authorityServiceMock.hasAdminAuthority()).willReturn(true);
 | 
			
		||||
        final NodeRef categoryRootNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, CAT_ROOT_NODE_ID);
 | 
			
		||||
        given(nodesMock.validateNode(CAT_ROOT_NODE_ID)).willReturn(categoryRootNodeRef);
 | 
			
		||||
        given(nodesMock.isSubClass(categoryRootNodeRef, ContentModel.TYPE_CATEGORY, false)).willReturn(true);
 | 
			
		||||
        given(categoryChildAssociationRefMock.getQName()).willReturn(ContentModel.ASPECT_GEN_CLASSIFIABLE);
 | 
			
		||||
        given(nodeServiceMock.getParentAssocs(categoryRootNodeRef)).willReturn(List.of(categoryChildAssociationRefMock));
 | 
			
		||||
 | 
			
		||||
        //when
 | 
			
		||||
        assertThrows(InvalidArgumentException.class, () -> objectUnderTest.deleteCategoryById(CAT_ROOT_NODE_ID, parametersMock));
 | 
			
		||||
 | 
			
		||||
        then(authorityServiceMock).should().hasAdminAuthority();
 | 
			
		||||
        then(authorityServiceMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
 | 
			
		||||
        then(nodesMock).should().validateNode(CAT_ROOT_NODE_ID);
 | 
			
		||||
        then(nodesMock).should().isSubClass(categoryRootNodeRef, ContentModel.TYPE_CATEGORY, false);
 | 
			
		||||
        then(nodesMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
 | 
			
		||||
        then(nodeServiceMock).should().getParentAssocs(categoryRootNodeRef);
 | 
			
		||||
        then(nodeServiceMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testCreateCategoryUnderRoot()
 | 
			
		||||
    {
 | 
			
		||||
        given(authorityServiceMock.hasAdminAuthority()).willReturn(true);
 | 
			
		||||
        final NodeRef parentCategoryNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, PATH_ROOT);
 | 
			
		||||
        given(categoryServiceMock.getRootCategoryNodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE))
 | 
			
		||||
                .willReturn(Optional.of(parentCategoryNodeRef));
 | 
			
		||||
        final NodeRef categoryNodeRef = prepareCategoryNodeRef();
 | 
			
		||||
        given(categoryServiceMock.createCategory(parentCategoryNodeRef, CATEGORY_NAME)).willReturn(categoryNodeRef);
 | 
			
		||||
        given(nodesMock.getNode(CATEGORY_ID)).willReturn(prepareCategoryNode());
 | 
			
		||||
        final ChildAssociationRef parentAssoc = new ChildAssociationRef(null, parentCategoryNodeRef, null, categoryNodeRef);
 | 
			
		||||
        given(nodeServiceMock.getPrimaryParent(categoryNodeRef)).willReturn(parentAssoc);
 | 
			
		||||
        given(nodeServiceMock.getParentAssocs(parentCategoryNodeRef)).willReturn(List.of(parentAssoc));
 | 
			
		||||
        given(nodeServiceMock.getChildAssocs(categoryNodeRef, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false))
 | 
			
		||||
                .willReturn(Collections.emptyList());
 | 
			
		||||
 | 
			
		||||
        //when
 | 
			
		||||
        final List<Category> createdCategories = objectUnderTest.createSubcategories(PATH_ROOT, prepareCategories(), parametersMock);
 | 
			
		||||
 | 
			
		||||
        then(authorityServiceMock).should().hasAdminAuthority();
 | 
			
		||||
        then(authorityServiceMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
        then(nodesMock).should().getNode(CATEGORY_ID);
 | 
			
		||||
        then(nodesMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
        then(nodeServiceMock).should().getPrimaryParent(categoryNodeRef);
 | 
			
		||||
        then(nodeServiceMock).should().getParentAssocs(parentCategoryNodeRef);
 | 
			
		||||
        then(nodeServiceMock).should().getChildAssocs(categoryNodeRef, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false);
 | 
			
		||||
        then(nodeServiceMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
        then(categoryServiceMock).should().getRootCategoryNodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE);
 | 
			
		||||
        then(categoryServiceMock).should().createCategory(parentCategoryNodeRef, CATEGORY_NAME);
 | 
			
		||||
        then(categoryServiceMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
 | 
			
		||||
        assertEquals(1, createdCategories.size());
 | 
			
		||||
        final Category expectedCategory = Category.builder()
 | 
			
		||||
                .id(CATEGORY_ID)
 | 
			
		||||
                .name(CATEGORY_NAME)
 | 
			
		||||
                .hasChildren(false)
 | 
			
		||||
                .parentId(PATH_ROOT)
 | 
			
		||||
                .create();
 | 
			
		||||
        final Category createdCategory = createdCategories.iterator().next();
 | 
			
		||||
        assertEquals(expectedCategory, createdCategory);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testCreateCategory()
 | 
			
		||||
    {
 | 
			
		||||
        given(authorityServiceMock.hasAdminAuthority()).willReturn(true);
 | 
			
		||||
        final NodeRef parentCategoryNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, PARENT_ID);
 | 
			
		||||
        given(nodesMock.validateNode(PARENT_ID)).willReturn(parentCategoryNodeRef);
 | 
			
		||||
        given(nodesMock.isSubClass(parentCategoryNodeRef, ContentModel.TYPE_CATEGORY, false)).willReturn(true);
 | 
			
		||||
        final NodeRef categoryNodeRef = prepareCategoryNodeRef();
 | 
			
		||||
        given(categoryServiceMock.createCategory(parentCategoryNodeRef, CATEGORY_NAME)).willReturn(categoryNodeRef);
 | 
			
		||||
        given(nodesMock.getNode(CATEGORY_ID)).willReturn(prepareCategoryNode());
 | 
			
		||||
        final ChildAssociationRef parentAssoc = new ChildAssociationRef(null, parentCategoryNodeRef, null, categoryNodeRef);
 | 
			
		||||
        given(nodeServiceMock.getPrimaryParent(categoryNodeRef)).willReturn(parentAssoc);
 | 
			
		||||
        given(nodeServiceMock.getParentAssocs(parentCategoryNodeRef)).willReturn(List.of(parentAssoc));
 | 
			
		||||
        given(nodeServiceMock.getChildAssocs(categoryNodeRef, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false))
 | 
			
		||||
                .willReturn(Collections.emptyList());
 | 
			
		||||
 | 
			
		||||
        //when
 | 
			
		||||
        final List<Category> createdCategories = objectUnderTest.createSubcategories(PARENT_ID, prepareCategories(), parametersMock);
 | 
			
		||||
 | 
			
		||||
        then(authorityServiceMock).should().hasAdminAuthority();
 | 
			
		||||
        then(authorityServiceMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
        then(nodesMock).should().validateNode(PARENT_ID);
 | 
			
		||||
        then(nodesMock).should().isSubClass(parentCategoryNodeRef, ContentModel.TYPE_CATEGORY, false);
 | 
			
		||||
        then(nodesMock).should().getNode(CATEGORY_ID);
 | 
			
		||||
        then(nodesMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
        then(nodeServiceMock).should().getPrimaryParent(categoryNodeRef);
 | 
			
		||||
        then(nodeServiceMock).should().getParentAssocs(parentCategoryNodeRef);
 | 
			
		||||
        then(nodeServiceMock).should().getChildAssocs(categoryNodeRef, RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false);
 | 
			
		||||
        then(nodeServiceMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
        then(categoryServiceMock).should().createCategory(parentCategoryNodeRef, CATEGORY_NAME);
 | 
			
		||||
        then(categoryServiceMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
 | 
			
		||||
        assertEquals(1, createdCategories.size());
 | 
			
		||||
        final Category expectedCategory = Category.builder()
 | 
			
		||||
                .id(CATEGORY_ID)
 | 
			
		||||
                .name(CATEGORY_NAME)
 | 
			
		||||
                .hasChildren(false)
 | 
			
		||||
                .parentId(PARENT_ID)
 | 
			
		||||
                .create();
 | 
			
		||||
        final Category createdCategory = createdCategories.iterator().next();
 | 
			
		||||
        assertEquals(expectedCategory, createdCategory);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testCreateCategories_noPermissions()
 | 
			
		||||
    {
 | 
			
		||||
        given(authorityServiceMock.hasAdminAuthority()).willReturn(false);
 | 
			
		||||
 | 
			
		||||
        //when
 | 
			
		||||
        assertThrows(PermissionDeniedException.class,
 | 
			
		||||
                () -> objectUnderTest.createSubcategories(PARENT_ID, prepareCategories(), parametersMock));
 | 
			
		||||
 | 
			
		||||
        then(authorityServiceMock).should().hasAdminAuthority();
 | 
			
		||||
        then(authorityServiceMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
        then(nodesMock).shouldHaveNoInteractions();
 | 
			
		||||
        then(nodeServiceMock).shouldHaveNoInteractions();
 | 
			
		||||
        then(categoryServiceMock).shouldHaveNoInteractions();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testCreateCategories_wrongParentNodeType()
 | 
			
		||||
    {
 | 
			
		||||
        given(authorityServiceMock.hasAdminAuthority()).willReturn(true);
 | 
			
		||||
        final NodeRef parentCategoryNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, PARENT_ID);
 | 
			
		||||
        given(nodesMock.validateNode(PARENT_ID)).willReturn(parentCategoryNodeRef);
 | 
			
		||||
        given(nodesMock.isSubClass(parentCategoryNodeRef, ContentModel.TYPE_CATEGORY, false)).willReturn(false);
 | 
			
		||||
 | 
			
		||||
        //when
 | 
			
		||||
        assertThrows(InvalidArgumentException.class,
 | 
			
		||||
                () -> objectUnderTest.createSubcategories(PARENT_ID, prepareCategories(), parametersMock));
 | 
			
		||||
 | 
			
		||||
        then(authorityServiceMock).should().hasAdminAuthority();
 | 
			
		||||
        then(authorityServiceMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
        then(nodesMock).should().validateNode(PARENT_ID);
 | 
			
		||||
        then(nodesMock).should().isSubClass(parentCategoryNodeRef, ContentModel.TYPE_CATEGORY, false);
 | 
			
		||||
        then(nodesMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
        then(nodeServiceMock).shouldHaveNoInteractions();
 | 
			
		||||
        then(categoryServiceMock).shouldHaveNoInteractions();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testCreateCategories_nonExistingParentNode()
 | 
			
		||||
    {
 | 
			
		||||
        given(authorityServiceMock.hasAdminAuthority()).willReturn(true);
 | 
			
		||||
        given(nodesMock.validateNode(PARENT_ID)).willThrow(EntityNotFoundException.class);
 | 
			
		||||
 | 
			
		||||
        //when
 | 
			
		||||
        assertThrows(EntityNotFoundException.class,
 | 
			
		||||
                () -> objectUnderTest.createSubcategories(PARENT_ID, prepareCategories(), parametersMock));
 | 
			
		||||
 | 
			
		||||
        then(authorityServiceMock).should().hasAdminAuthority();
 | 
			
		||||
        then(authorityServiceMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
        then(nodesMock).should().validateNode(PARENT_ID);
 | 
			
		||||
        then(nodesMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
        then(nodeServiceMock).shouldHaveNoInteractions();
 | 
			
		||||
        then(categoryServiceMock).shouldHaveNoInteractions();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testGetRootCategoryChildren()
 | 
			
		||||
    {
 | 
			
		||||
        final NodeRef parentCategoryNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, PATH_ROOT);
 | 
			
		||||
        given(categoryServiceMock.getRootCategoryNodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE))
 | 
			
		||||
                .willReturn(Optional.of(parentCategoryNodeRef));
 | 
			
		||||
        final int childrenCount = 3;
 | 
			
		||||
        final List<ChildAssociationRef> childAssociationRefMocks = prepareChildAssocMocks(childrenCount, parentCategoryNodeRef);
 | 
			
		||||
        given(nodeServiceMock.getChildAssocs(parentCategoryNodeRef)).willReturn(childAssociationRefMocks);
 | 
			
		||||
        childAssociationRefMocks.forEach(this::prepareCategoryNodeMocks);
 | 
			
		||||
 | 
			
		||||
        //when
 | 
			
		||||
        final CollectionWithPagingInfo<Category> categoryChildren = objectUnderTest.getCategoryChildren(PATH_ROOT, parametersMock);
 | 
			
		||||
 | 
			
		||||
        then(categoryServiceMock).should().getRootCategoryNodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE);
 | 
			
		||||
        then(categoryServiceMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
        then(nodeServiceMock).should().getChildAssocs(parentCategoryNodeRef);
 | 
			
		||||
        childAssociationRefMocks.forEach(ca -> {
 | 
			
		||||
            then(nodesMock).should().getNode(ca.getChildRef().getId());
 | 
			
		||||
            then(nodeServiceMock).should()
 | 
			
		||||
                    .getChildAssocs(ca.getChildRef(), RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false);
 | 
			
		||||
            then(nodeServiceMock).should().getPrimaryParent(ca.getChildRef());
 | 
			
		||||
        });
 | 
			
		||||
        then(nodeServiceMock).should(times(childrenCount)).getParentAssocs(parentCategoryNodeRef);
 | 
			
		||||
 | 
			
		||||
        then(nodesMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
        then(nodeServiceMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
 | 
			
		||||
        then(authorityServiceMock).shouldHaveNoInteractions();
 | 
			
		||||
 | 
			
		||||
        assertEquals(childAssociationRefMocks.size(), categoryChildren.getTotalItems().intValue());
 | 
			
		||||
        final List<Category> categoryChildrenList = new ArrayList<>(categoryChildren.getCollection());
 | 
			
		||||
        assertEquals(childAssociationRefMocks.size(), categoryChildrenList.size());
 | 
			
		||||
        IntStream.range(0, childrenCount).forEach(i -> doCategoryAssertions(categoryChildrenList.get(i), i, PATH_ROOT));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testGetCategoryChildren()
 | 
			
		||||
    {
 | 
			
		||||
        final NodeRef parentCategoryNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, PARENT_ID);
 | 
			
		||||
        given(nodesMock.validateNode(PARENT_ID)).willReturn(parentCategoryNodeRef);
 | 
			
		||||
        given(nodesMock.isSubClass(parentCategoryNodeRef, ContentModel.TYPE_CATEGORY, false)).willReturn(true);
 | 
			
		||||
        final int childrenCount = 3;
 | 
			
		||||
        final List<ChildAssociationRef> childAssociationRefMocks = prepareChildAssocMocks(childrenCount, parentCategoryNodeRef);
 | 
			
		||||
        given(nodeServiceMock.getChildAssocs(parentCategoryNodeRef)).willReturn(childAssociationRefMocks);
 | 
			
		||||
        childAssociationRefMocks.forEach(this::prepareCategoryNodeMocks);
 | 
			
		||||
 | 
			
		||||
        //when
 | 
			
		||||
        final CollectionWithPagingInfo<Category> categoryChildren = objectUnderTest.getCategoryChildren(PARENT_ID, parametersMock);
 | 
			
		||||
 | 
			
		||||
        then(nodesMock).should().validateNode(PARENT_ID);
 | 
			
		||||
        then(nodesMock).should().isSubClass(parentCategoryNodeRef, ContentModel.TYPE_CATEGORY, false);
 | 
			
		||||
        then(nodeServiceMock).should().getChildAssocs(parentCategoryNodeRef);
 | 
			
		||||
        childAssociationRefMocks.forEach(ca -> {
 | 
			
		||||
            then(nodesMock).should().getNode(ca.getChildRef().getId());
 | 
			
		||||
            then(nodeServiceMock).should()
 | 
			
		||||
                    .getChildAssocs(ca.getChildRef(), RegexQNamePattern.MATCH_ALL, RegexQNamePattern.MATCH_ALL, false);
 | 
			
		||||
            then(nodeServiceMock).should().getPrimaryParent(ca.getChildRef());
 | 
			
		||||
        });
 | 
			
		||||
        then(nodeServiceMock).should(times(childrenCount)).getParentAssocs(parentCategoryNodeRef);
 | 
			
		||||
 | 
			
		||||
        then(nodesMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
        then(nodeServiceMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
 | 
			
		||||
        then(authorityServiceMock).shouldHaveNoInteractions();
 | 
			
		||||
        then(categoryServiceMock).shouldHaveNoInteractions();
 | 
			
		||||
 | 
			
		||||
        assertEquals(childAssociationRefMocks.size(), categoryChildren.getTotalItems().intValue());
 | 
			
		||||
        final List<Category> categoryChildrenList = new ArrayList<>(categoryChildren.getCollection());
 | 
			
		||||
        assertEquals(childAssociationRefMocks.size(), categoryChildrenList.size());
 | 
			
		||||
        IntStream.range(0, childrenCount).forEach(i -> doCategoryAssertions(categoryChildrenList.get(i), i, PARENT_ID));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testGetCategoryChildren_noChildren()
 | 
			
		||||
    {
 | 
			
		||||
        final NodeRef parentCategoryNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, PARENT_ID);
 | 
			
		||||
        given(nodesMock.validateNode(PARENT_ID)).willReturn(parentCategoryNodeRef);
 | 
			
		||||
        given(nodesMock.isSubClass(parentCategoryNodeRef, ContentModel.TYPE_CATEGORY, false)).willReturn(true);
 | 
			
		||||
 | 
			
		||||
        given(nodeServiceMock.getChildAssocs(parentCategoryNodeRef)).willReturn(Collections.emptyList());
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        //when
 | 
			
		||||
        final CollectionWithPagingInfo<Category> categoryChildren = objectUnderTest.getCategoryChildren(PARENT_ID, parametersMock);
 | 
			
		||||
 | 
			
		||||
        then(nodesMock).should().validateNode(PARENT_ID);
 | 
			
		||||
        then(nodesMock).should().isSubClass(parentCategoryNodeRef, ContentModel.TYPE_CATEGORY, false);
 | 
			
		||||
        then(nodesMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
        then(nodeServiceMock).should().getChildAssocs(parentCategoryNodeRef);
 | 
			
		||||
        then(nodeServiceMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
 | 
			
		||||
        then(authorityServiceMock).shouldHaveNoInteractions();
 | 
			
		||||
        then(categoryServiceMock).shouldHaveNoInteractions();
 | 
			
		||||
 | 
			
		||||
        assertEquals(0, categoryChildren.getTotalItems().intValue());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testGetCategoryChildren_wrongParentNodeType()
 | 
			
		||||
    {
 | 
			
		||||
        final NodeRef parentCategoryNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, PARENT_ID);
 | 
			
		||||
        given(nodesMock.validateNode(PARENT_ID)).willReturn(parentCategoryNodeRef);
 | 
			
		||||
        given(nodesMock.isSubClass(parentCategoryNodeRef, ContentModel.TYPE_CATEGORY, false)).willReturn(false);
 | 
			
		||||
 | 
			
		||||
        //when
 | 
			
		||||
        assertThrows(InvalidArgumentException.class, () -> objectUnderTest.getCategoryChildren(PARENT_ID, parametersMock));
 | 
			
		||||
 | 
			
		||||
        then(nodesMock).should().validateNode(PARENT_ID);
 | 
			
		||||
        then(nodesMock).should().isSubClass(parentCategoryNodeRef, ContentModel.TYPE_CATEGORY, false);
 | 
			
		||||
        then(nodesMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
 | 
			
		||||
        then(nodeServiceMock).shouldHaveNoInteractions();
 | 
			
		||||
        then(categoryServiceMock).shouldHaveNoInteractions();
 | 
			
		||||
        then(authorityServiceMock).shouldHaveNoInteractions();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    public void testGetCategoryChildren_nonExistingParentNode()
 | 
			
		||||
    {
 | 
			
		||||
        given(nodesMock.validateNode(PARENT_ID)).willThrow(EntityNotFoundException.class);
 | 
			
		||||
 | 
			
		||||
        //when
 | 
			
		||||
        assertThrows(EntityNotFoundException.class, () -> objectUnderTest.getCategoryChildren(PARENT_ID, parametersMock));
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        then(nodesMock).should().validateNode(PARENT_ID);
 | 
			
		||||
        then(nodesMock).shouldHaveNoMoreInteractions();
 | 
			
		||||
 | 
			
		||||
        then(nodeServiceMock).shouldHaveNoInteractions();
 | 
			
		||||
        then(categoryServiceMock).shouldHaveNoInteractions();
 | 
			
		||||
        then(authorityServiceMock).shouldHaveNoInteractions();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Node prepareCategoryNode()
 | 
			
		||||
    {
 | 
			
		||||
        final NodeRef parentNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, PARENT_ID);
 | 
			
		||||
        return prepareCategoryNode(CATEGORY_NAME, CATEGORY_ID, parentNodeRef);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private Node prepareCategoryNode(final String name, final String id, final NodeRef parentNodeRef)
 | 
			
		||||
    {
 | 
			
		||||
        final Node categoryNode = new Node();
 | 
			
		||||
        categoryNode.setName(name);
 | 
			
		||||
        categoryNode.setNodeId(id);
 | 
			
		||||
        categoryNode.setParentId(parentNodeRef);
 | 
			
		||||
        return categoryNode;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private NodeRef prepareCategoryNodeRef()
 | 
			
		||||
    {
 | 
			
		||||
        return new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, CATEGORY_ID);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private List<Category> prepareCategories()
 | 
			
		||||
    {
 | 
			
		||||
        return List.of(Category.builder()
 | 
			
		||||
                .name(CATEGORY_NAME)
 | 
			
		||||
                .create());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private List<ChildAssociationRef> prepareChildAssocMocks(final int count, NodeRef parentCategoryNodeRef)
 | 
			
		||||
    {
 | 
			
		||||
        return IntStream.range(0, count).mapToObj(i -> {
 | 
			
		||||
            ChildAssociationRef dummyChildAssocMock = mock(ChildAssociationRef.class);
 | 
			
		||||
            given(dummyChildAssocMock.getTypeQName()).willReturn(ContentModel.ASSOC_SUBCATEGORIES);
 | 
			
		||||
            given(dummyChildAssocMock.getChildRef())
 | 
			
		||||
                    .willReturn(new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, CATEGORY_ID + "-" + i));
 | 
			
		||||
            given(dummyChildAssocMock.getParentRef()).willReturn(parentCategoryNodeRef);
 | 
			
		||||
            return dummyChildAssocMock;
 | 
			
		||||
        })
 | 
			
		||||
                .collect(Collectors.toList());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void prepareCategoryNodeMocks(ChildAssociationRef childAssociationRef)
 | 
			
		||||
    {
 | 
			
		||||
        final NodeRef childRef = childAssociationRef.getChildRef();
 | 
			
		||||
        final String id = childRef.getId();
 | 
			
		||||
        final String name = id.replace(CATEGORY_ID, CATEGORY_NAME);
 | 
			
		||||
        final NodeRef parentRef = childAssociationRef.getParentRef();
 | 
			
		||||
        given(nodesMock.getNode(id)).willReturn(prepareCategoryNode(name, id, parentRef));
 | 
			
		||||
        final ChildAssociationRef parentAssoc = new ChildAssociationRef(null, parentRef, null, childRef);
 | 
			
		||||
        given(nodeServiceMock.getPrimaryParent(childRef)).willReturn(parentAssoc);
 | 
			
		||||
        given(nodeServiceMock.getParentAssocs(parentRef)).willReturn(List.of(parentAssoc));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void doCategoryAssertions(final Category category, final int index, final String parentId)
 | 
			
		||||
    {
 | 
			
		||||
        final Category expectedCategory = Category.builder()
 | 
			
		||||
                .id(CATEGORY_ID + "-" + index)
 | 
			
		||||
                .name(CATEGORY_NAME + "-" + index)
 | 
			
		||||
                .parentId(parentId)
 | 
			
		||||
                .hasChildren(false)
 | 
			
		||||
                .create();
 | 
			
		||||
        assertEquals(expectedCategory, category);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
    <parent>
 | 
			
		||||
        <groupId>org.alfresco</groupId>
 | 
			
		||||
        <artifactId>alfresco-community-repo</artifactId>
 | 
			
		||||
        <version>20.42</version>
 | 
			
		||||
        <version>20.36-SNAPSHOT</version>
 | 
			
		||||
    </parent>
 | 
			
		||||
 | 
			
		||||
    <dependencies>
 | 
			
		||||
 
 | 
			
		||||
@@ -573,7 +573,6 @@
 | 
			
		||||
                org.alfresco.service.cmr.search.CategoryService.deleteClassification=ACL_ALLOW
 | 
			
		||||
                org.alfresco.service.cmr.search.CategoryService.deleteCategory=ACL_ALLOW
 | 
			
		||||
                org.alfresco.service.cmr.search.CategoryService.getTopCategories=ACL_ALLOW
 | 
			
		||||
                org.alfresco.service.cmr.search.CategoryService.getRootCategoryNodeRef=ACL_ALLOW
 | 
			
		||||
                org.alfresco.service.cmr.search.CategoryService.*=ACL_DENY
 | 
			
		||||
            </value>
 | 
			
		||||
        </property>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user