mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
Added parentId parameter for tests that use declareRecord v1 api
This commit is contained in:
@@ -41,7 +41,7 @@ import lombok.Setter;
|
|||||||
* @author Tuna Aksoy
|
* @author Tuna Aksoy
|
||||||
* @since 2.6
|
* @since 2.6
|
||||||
*/
|
*/
|
||||||
public abstract class RMModelRequest extends ModelRequest<RMModelRequest>
|
public abstract class RMModelRequest<Request> extends ModelRequest<Request>
|
||||||
{
|
{
|
||||||
@Getter (value = PROTECTED)
|
@Getter (value = PROTECTED)
|
||||||
@Setter (value = PRIVATE)
|
@Setter (value = PRIVATE)
|
||||||
|
@@ -41,8 +41,10 @@ import org.alfresco.rest.rm.community.requests.RMModelRequest;
|
|||||||
* @author Kristijan Conkas
|
* @author Kristijan Conkas
|
||||||
* @since 2.6
|
* @since 2.6
|
||||||
*/
|
*/
|
||||||
public class FilesAPI extends RMModelRequest
|
public class FilesAPI extends RMModelRequest<FilesAPI>
|
||||||
{
|
{
|
||||||
|
public static final String PARENT_ID_PARAM = "parentId";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param rmRestWrapper RM REST Wrapper
|
* @param rmRestWrapper RM REST Wrapper
|
||||||
*/
|
*/
|
||||||
@@ -55,26 +57,6 @@ public class FilesAPI extends RMModelRequest
|
|||||||
* Declare file as record
|
* Declare file as record
|
||||||
*
|
*
|
||||||
* @param fileId The Id of a file to declare as record
|
* @param fileId The Id of a file to declare as record
|
||||||
* @param parameters Request parameters, refer to API documentation for more details
|
|
||||||
* @return The {@link Record} for created record
|
|
||||||
* @throws Exception for malformed JSON responses
|
|
||||||
*/
|
|
||||||
public Record declareAsRecord(String fileId, String parameters) throws Exception
|
|
||||||
{
|
|
||||||
mandatoryString("fileId", fileId);
|
|
||||||
|
|
||||||
return getRmRestWrapper().processModel(Record.class, simpleRequest(
|
|
||||||
POST,
|
|
||||||
"/files/{fileId}/declare?{parameters}",
|
|
||||||
fileId,
|
|
||||||
parameters
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A no-parameter version of {@link FilesAPI#declareAsRecord}
|
|
||||||
*
|
|
||||||
* @param fileId The Id of a file to declare as record
|
|
||||||
* @return The {@link Record} for created record
|
* @return The {@link Record} for created record
|
||||||
* @throws Exception for malformed JSON responses
|
* @throws Exception for malformed JSON responses
|
||||||
*/
|
*/
|
||||||
@@ -82,7 +64,12 @@ public class FilesAPI extends RMModelRequest
|
|||||||
{
|
{
|
||||||
mandatoryString("fileId", fileId);
|
mandatoryString("fileId", fileId);
|
||||||
|
|
||||||
return declareAsRecord(fileId, EMPTY);
|
return getRmRestWrapper().processModel(Record.class, simpleRequest(
|
||||||
|
POST,
|
||||||
|
"/files/{fileId}/declare?{parameters}",
|
||||||
|
fileId,
|
||||||
|
getRmRestWrapper().getParameters()
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -26,16 +26,19 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.rest.rm.community.files;
|
package org.alfresco.rest.rm.community.files;
|
||||||
|
|
||||||
|
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.FILE_PLAN_ALIAS;
|
||||||
|
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.TRANSFERS_ALIAS;
|
||||||
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.UNFILED_RECORDS_CONTAINER_ALIAS;
|
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentAlias.UNFILED_RECORDS_CONTAINER_ALIAS;
|
||||||
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.UNFILED_RECORD_FOLDER_TYPE;
|
import static org.alfresco.rest.rm.community.model.fileplancomponents.FilePlanComponentType.UNFILED_RECORD_FOLDER_TYPE;
|
||||||
import static org.alfresco.rest.rm.community.model.user.UserPermissions.PERMISSION_FILING;
|
import static org.alfresco.rest.rm.community.model.user.UserPermissions.PERMISSION_FILING;
|
||||||
import static org.alfresco.rest.rm.community.model.user.UserPermissions.PERMISSION_READ_RECORDS;
|
import static org.alfresco.rest.rm.community.model.user.UserPermissions.PERMISSION_READ_RECORDS;
|
||||||
import static org.alfresco.rest.rm.community.model.user.UserRoles.ROLE_RM_POWER_USER;
|
import static org.alfresco.rest.rm.community.model.user.UserRoles.ROLE_RM_POWER_USER;
|
||||||
import static org.alfresco.rest.rm.community.model.user.UserRoles.ROLE_RM_USER;
|
import static org.alfresco.rest.rm.community.requests.gscore.api.FilesAPI.PARENT_ID_PARAM;
|
||||||
import static org.alfresco.utility.data.RandomData.getRandomAlphanumeric;
|
import static org.alfresco.utility.data.RandomData.getRandomAlphanumeric;
|
||||||
import static org.alfresco.utility.data.RandomData.getRandomName;
|
import static org.alfresco.utility.data.RandomData.getRandomName;
|
||||||
import static org.alfresco.utility.report.log.Step.STEP;
|
import static org.alfresco.utility.report.log.Step.STEP;
|
||||||
import static org.springframework.http.HttpStatus.ACCEPTED;
|
import static org.springframework.http.HttpStatus.ACCEPTED;
|
||||||
|
import static org.springframework.http.HttpStatus.BAD_REQUEST;
|
||||||
import static org.springframework.http.HttpStatus.CREATED;
|
import static org.springframework.http.HttpStatus.CREATED;
|
||||||
import static org.springframework.http.HttpStatus.FORBIDDEN;
|
import static org.springframework.http.HttpStatus.FORBIDDEN;
|
||||||
import static org.springframework.http.HttpStatus.UNPROCESSABLE_ENTITY;
|
import static org.springframework.http.HttpStatus.UNPROCESSABLE_ENTITY;
|
||||||
@@ -57,6 +60,7 @@ import org.alfresco.test.AlfrescoTest;
|
|||||||
import org.alfresco.utility.Utility;
|
import org.alfresco.utility.Utility;
|
||||||
import org.alfresco.utility.constants.UserRole;
|
import org.alfresco.utility.constants.UserRole;
|
||||||
import org.alfresco.utility.model.FileModel;
|
import org.alfresco.utility.model.FileModel;
|
||||||
|
import org.alfresco.utility.model.FolderModel;
|
||||||
import org.alfresco.utility.model.SiteModel;
|
import org.alfresco.utility.model.SiteModel;
|
||||||
import org.alfresco.utility.model.UserModel;
|
import org.alfresco.utility.model.UserModel;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -77,10 +81,11 @@ public class DeclareAndFileDocumentAsRecordTests extends BaseRMRestTest
|
|||||||
private final static String DESTINATION_PATH_NOT_RESOLVED_EXC = "Unable to execute create-record action, because the destination path could not be resolved.";
|
private final static String DESTINATION_PATH_NOT_RESOLVED_EXC = "Unable to execute create-record action, because the destination path could not be resolved.";
|
||||||
private final static String INVALID_DESTINATION_PATH_EXC = "Unable to execute create-record action, because the destination path is invalid.";
|
private final static String INVALID_DESTINATION_PATH_EXC = "Unable to execute create-record action, because the destination path is invalid.";
|
||||||
private final static String DESTINATION_PATH_NOT_RECORD_FOLDER_EXC = "Unable to execute create-record action, because the destination path is not a record folder.";
|
private final static String DESTINATION_PATH_NOT_RECORD_FOLDER_EXC = "Unable to execute create-record action, because the destination path is not a record folder.";
|
||||||
private final static String CLOSED_RECORD_FOLDER_EXC = "You can't add new items to a closed record folder";
|
private final static String CLOSED_RECORD_FOLDER_EXC = "Unable to create record, because container is closed";
|
||||||
|
|
||||||
private UserModel userFillingPermission, userReadOnlyPermission;
|
private UserModel userFillingPermission, userReadOnlyPermission;
|
||||||
private SiteModel publicSite;
|
private SiteModel publicSite;
|
||||||
|
private FolderModel testFolder;
|
||||||
private RecordCategory recordCategory;
|
private RecordCategory recordCategory;
|
||||||
private RecordCategoryChild recordFolder, subcategoryRecordFolder, subCategory;
|
private RecordCategoryChild recordFolder, subcategoryRecordFolder, subCategory;
|
||||||
private UnfiledContainerChild unfiledContainerFolder;
|
private UnfiledContainerChild unfiledContainerFolder;
|
||||||
@@ -92,16 +97,14 @@ public class DeclareAndFileDocumentAsRecordTests extends BaseRMRestTest
|
|||||||
private RoleService roleService;
|
private RoleService roleService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invalid containers where in-place records can't be filed
|
* Invalid destination paths where in-place records can't be filed
|
||||||
*/
|
*/
|
||||||
@DataProvider (name = "invalidFileLocations")
|
@DataProvider (name = "invalidDestinationPaths")
|
||||||
public Object[][] getInvalidFileLocations() throws Exception
|
public Object[][] getInvalidDestinationPaths() throws Exception
|
||||||
{
|
{
|
||||||
RecordCategoryChild closedFolder = createFolder(recordCategory.getId(), getRandomName("closedFolder"));
|
RecordCategoryChild closedFolder = createFolder(recordCategory.getId(), getRandomName("closedFolder"));
|
||||||
closeFolder(closedFolder.getId());
|
closeFolder(closedFolder.getId());
|
||||||
|
|
||||||
unfiledContainerFolder = createUnfiledContainerChild(UNFILED_RECORDS_CONTAINER_ALIAS,
|
|
||||||
"Unfiled Folder " + getRandomAlphanumeric(), UNFILED_RECORD_FOLDER_TYPE);
|
|
||||||
return new String[][]
|
return new String[][]
|
||||||
{
|
{
|
||||||
{ "/", DESTINATION_PATH_NOT_RESOLVED_EXC},
|
{ "/", DESTINATION_PATH_NOT_RESOLVED_EXC},
|
||||||
@@ -115,7 +118,25 @@ public class DeclareAndFileDocumentAsRecordTests extends BaseRMRestTest
|
|||||||
// an arbitrary unfiled records folder
|
// an arbitrary unfiled records folder
|
||||||
{ "Unfiled Records/" + unfiledContainerFolder.getName(), INVALID_DESTINATION_PATH_EXC },
|
{ "Unfiled Records/" + unfiledContainerFolder.getName(), INVALID_DESTINATION_PATH_EXC },
|
||||||
// a collaboration site folder
|
// a collaboration site folder
|
||||||
{ dataContent.usingAdmin().usingSite(publicSite).createFolder().getCmisLocation(), DESTINATION_PATH_NOT_RESOLVED_EXC }
|
{ testFolder.getCmisLocation(), DESTINATION_PATH_NOT_RESOLVED_EXC }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalid destination ids where in-place records can't be filed
|
||||||
|
*/
|
||||||
|
@DataProvider (name = "invalidDestinationIds")
|
||||||
|
public Object[][] getInvalidDestinationIds()
|
||||||
|
{
|
||||||
|
return new String[][]
|
||||||
|
{
|
||||||
|
{ getRestAPIFactory().getFilePlansAPI().getFilePlan(FILE_PLAN_ALIAS).getId() },
|
||||||
|
{ getRestAPIFactory().getUnfiledContainersAPI().getUnfiledContainer(UNFILED_RECORDS_CONTAINER_ALIAS).getId() },
|
||||||
|
{ getRestAPIFactory().getTransferContainerAPI().getTransferContainer(TRANSFERS_ALIAS).getId() },
|
||||||
|
{ getContentService().getNodeRefByPath(getAdminUser().getUsername(), getAdminUser().getPassword(), "/Sites/rm/documentLibrary/Holds") },
|
||||||
|
{ recordCategory.getId() },
|
||||||
|
{ unfiledContainerFolder.getId() },
|
||||||
|
{ testFolder.getNodeRef() }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,15 +146,21 @@ public class DeclareAndFileDocumentAsRecordTests extends BaseRMRestTest
|
|||||||
STEP("Create test collaboration site to store documents in.");
|
STEP("Create test collaboration site to store documents in.");
|
||||||
publicSite = dataSite.usingAdmin().createPublicRandomSite();
|
publicSite = dataSite.usingAdmin().createPublicRandomSite();
|
||||||
|
|
||||||
|
STEP("Create a test foloder within the collaboration site");
|
||||||
|
testFolder = dataContent.usingAdmin().usingSite(publicSite).createFolder();
|
||||||
|
|
||||||
STEP("Create record categories and record folders");
|
STEP("Create record categories and record folders");
|
||||||
recordCategory = createRootCategory(getRandomName("recordCategory"));
|
recordCategory = createRootCategory(getRandomName("recordCategory"));
|
||||||
subCategory = createRecordCategory(recordCategory.getId(), getRandomName("subCategory"));
|
subCategory = createRecordCategory(recordCategory.getId(), getRandomName("subCategory"));
|
||||||
recordFolder = createFolder(recordCategory.getId(), getRandomName("recordFolder"));
|
recordFolder = createFolder(recordCategory.getId(), getRandomName("recordFolder"));
|
||||||
subcategoryRecordFolder = createFolder(subCategory.getId(), getRandomName("recordFolder"));
|
subcategoryRecordFolder = createFolder(subCategory.getId(), getRandomName("recordFolder"));
|
||||||
|
unfiledContainerFolder = createUnfiledContainerChild(UNFILED_RECORDS_CONTAINER_ALIAS,
|
||||||
|
"Unfiled Folder " + getRandomAlphanumeric(), UNFILED_RECORD_FOLDER_TYPE);
|
||||||
|
|
||||||
STEP("Create rm users with different permissions on the record category");
|
STEP("Create rm users with different permissions on the record category");
|
||||||
userFillingPermission = roleService.createCollaboratorWithRMRoleAndPermission(publicSite, recordCategory, ROLE_RM_POWER_USER, PERMISSION_FILING);
|
userFillingPermission = roleService.createCollaboratorWithRMRoleAndPermission(publicSite, recordCategory, ROLE_RM_POWER_USER, PERMISSION_FILING);
|
||||||
userReadOnlyPermission = roleService.createCollaboratorWithRMRoleAndPermission(publicSite, recordCategory,ROLE_RM_USER, PERMISSION_READ_RECORDS);
|
userReadOnlyPermission = roleService.createCollaboratorWithRMRoleAndPermission(publicSite, recordCategory,
|
||||||
|
ROLE_RM_POWER_USER, PERMISSION_READ_RECORDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -194,7 +221,7 @@ public class DeclareAndFileDocumentAsRecordTests extends BaseRMRestTest
|
|||||||
* Then I receive an error indicating that I have attempted to declare and file a document into an invalid record folder
|
* Then I receive an error indicating that I have attempted to declare and file a document into an invalid record folder
|
||||||
* And the document is not declared as a record
|
* And the document is not declared as a record
|
||||||
*/
|
*/
|
||||||
@Test (dataProvider = "invalidFileLocations")
|
@Test (dataProvider = "invalidDestinationPaths")
|
||||||
public void declareAndFileToInvalidLocationUsingActionsAPI(String containerPath, String expectedException) throws Exception
|
public void declareAndFileToInvalidLocationUsingActionsAPI(String containerPath, String expectedException) throws Exception
|
||||||
{
|
{
|
||||||
STEP("Create a document in the collaboration site");
|
STEP("Create a document in the collaboration site");
|
||||||
@@ -232,8 +259,8 @@ public class DeclareAndFileDocumentAsRecordTests extends BaseRMRestTest
|
|||||||
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
|
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
|
||||||
|
|
||||||
STEP("Declare document as record with a location parameter value");
|
STEP("Declare document as record with a location parameter value");
|
||||||
//TODO add recordFolder location parameter value
|
|
||||||
Record record = getRestAPIFactory().getFilesAPI(userFillingPermission)
|
Record record = getRestAPIFactory().getFilesAPI(userFillingPermission)
|
||||||
|
.usingParams(String.format("%s=%s", PARENT_ID_PARAM, recordFolder.getId()))
|
||||||
.declareAsRecord(testFile.getNodeRefWithoutVersion());
|
.declareAsRecord(testFile.getNodeRefWithoutVersion());
|
||||||
assertStatusCode(CREATED);
|
assertStatusCode(CREATED);
|
||||||
|
|
||||||
@@ -244,6 +271,30 @@ public class DeclareAndFileDocumentAsRecordTests extends BaseRMRestTest
|
|||||||
assertTrue(hasRecordAspect(testFile), "File should have record aspect");
|
assertTrue(hasRecordAspect(testFile), "File should have record aspect");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given I declare a record using the v1 API
|
||||||
|
* When I provide an invalid record folder in the location parameter
|
||||||
|
* Then I receive an error indicating that I have attempted to declare and file a document into an invalid record folder
|
||||||
|
* And the document is not declared as a record
|
||||||
|
*/
|
||||||
|
@Test (dataProvider = "invalidDestinationIds")
|
||||||
|
public void declareAndFileToInvalidLocationUsingFilesAPI(String containerID) throws Exception
|
||||||
|
{
|
||||||
|
STEP("Create a document in the collaboration site");
|
||||||
|
FileModel testFile = dataContent.usingSite(publicSite)
|
||||||
|
.usingAdmin()
|
||||||
|
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
|
||||||
|
|
||||||
|
STEP("Declare document as record with an invalid location parameter value");
|
||||||
|
getRestAPIFactory().getFilesAPI()
|
||||||
|
.usingParams(String.format("%s=%s", PARENT_ID_PARAM, containerID))
|
||||||
|
.declareAsRecord(testFile.getNodeRefWithoutVersion());
|
||||||
|
assertStatusCode(BAD_REQUEST);
|
||||||
|
|
||||||
|
STEP("Check that the file is not a record");
|
||||||
|
assertFalse(hasRecordAspect(testFile), "File should not have record aspect");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given I am an user with read only permissions on a record folder
|
* Given I am an user with read only permissions on a record folder
|
||||||
* When I declare and file a record to the record folder
|
* When I declare and file a record to the record folder
|
||||||
@@ -258,9 +309,9 @@ public class DeclareAndFileDocumentAsRecordTests extends BaseRMRestTest
|
|||||||
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
|
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
|
||||||
|
|
||||||
STEP("Declare document as record with a record folder as location parameter");
|
STEP("Declare document as record with a record folder as location parameter");
|
||||||
//TODO add recordFolder location parameter value
|
getRestAPIFactory().getFilesAPI(userReadOnlyPermission)
|
||||||
getRestAPIFactory().getFilesAPI(userReadOnlyPermission).declareAsRecord(testFile.getNodeRefWithoutVersion());
|
.usingParams(String.format("%s=%s", PARENT_ID_PARAM, recordFolder.getId()))
|
||||||
//TODO check what status code should be returned
|
.declareAsRecord(testFile.getNodeRefWithoutVersion());
|
||||||
assertStatusCode(FORBIDDEN);
|
assertStatusCode(FORBIDDEN);
|
||||||
|
|
||||||
STEP("Check that the file is not a record");
|
STEP("Check that the file is not a record");
|
||||||
@@ -285,8 +336,9 @@ public class DeclareAndFileDocumentAsRecordTests extends BaseRMRestTest
|
|||||||
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
|
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
|
||||||
|
|
||||||
STEP("Declare document as record with a record folder as location parameter");
|
STEP("Declare document as record with a record folder as location parameter");
|
||||||
//TODO add recordFolder location parameter value
|
getRestAPIFactory().getFilesAPI(nonRMUser)
|
||||||
getRestAPIFactory().getFilesAPI(nonRMUser).declareAsRecord(testFile.getNodeRefWithoutVersion());
|
.usingParams(String.format("%s=%s", PARENT_ID_PARAM, recordFolder.getId()))
|
||||||
|
.declareAsRecord(testFile.getNodeRefWithoutVersion());
|
||||||
assertStatusCode(FORBIDDEN);
|
assertStatusCode(FORBIDDEN);
|
||||||
|
|
||||||
STEP("Check that the file is not a record");
|
STEP("Check that the file is not a record");
|
||||||
@@ -308,13 +360,15 @@ public class DeclareAndFileDocumentAsRecordTests extends BaseRMRestTest
|
|||||||
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
|
.createContent(CMISUtil.DocumentType.TEXT_PLAIN);
|
||||||
|
|
||||||
STEP("Declare document as record with a record folder as location parameter");
|
STEP("Declare document as record with a record folder as location parameter");
|
||||||
//TODO add subcategoryRecordFolder as location parameter value
|
getRestAPIFactory().getFilesAPI(userFillingPermission)
|
||||||
getRestAPIFactory().getFilesAPI(userFillingPermission).declareAsRecord(testFile.getNodeRefWithoutVersion());
|
.usingParams(String.format("%s=%s", PARENT_ID_PARAM, subcategoryRecordFolder.getId()))
|
||||||
|
.declareAsRecord(testFile.getNodeRefWithoutVersion());
|
||||||
assertStatusCode(CREATED);
|
assertStatusCode(CREATED);
|
||||||
|
|
||||||
STEP("Declare it again using a different record folder as location parameter");
|
STEP("Declare it again using a different record folder as location parameter");
|
||||||
//TODO add recordFolder as location parameter value
|
getRestAPIFactory().getFilesAPI(userFillingPermission)
|
||||||
getRestAPIFactory().getFilesAPI(userFillingPermission).declareAsRecord(testFile.getNodeRefWithoutVersion());
|
.usingParams(String.format("%s=%s", PARENT_ID_PARAM, recordFolder.getId()))
|
||||||
|
.declareAsRecord(testFile.getNodeRefWithoutVersion());
|
||||||
assertStatusCode(UNPROCESSABLE_ENTITY);
|
assertStatusCode(UNPROCESSABLE_ENTITY);
|
||||||
|
|
||||||
STEP("Verify the declared record is placed in the first record folder");
|
STEP("Verify the declared record is placed in the first record folder");
|
||||||
@@ -324,8 +378,6 @@ public class DeclareAndFileDocumentAsRecordTests extends BaseRMRestTest
|
|||||||
"Record should not be filed to subcategoryRecordFolder");
|
"Record should not be filed to subcategoryRecordFolder");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@AfterClass(alwaysRun = true)
|
@AfterClass(alwaysRun = true)
|
||||||
public void declareAndFileDocumentAsRecordCleanup()
|
public void declareAndFileDocumentAsRecordCleanup()
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user