Skip to content

Commit

Permalink
feat: Add support for modifiable retention policies & enable deleting…
Browse files Browse the repository at this point in the history
… retention policy assignment (#856)
  • Loading branch information
congminh1254 committed Sep 13, 2022
1 parent 5ef2f18 commit 564904f
Show file tree
Hide file tree
Showing 8 changed files with 156 additions and 15 deletions.
@@ -0,0 +1,36 @@
using System;
using System.Threading.Tasks;
using Box.V2.Exceptions;
using Box.V2.Models;
using Box.V2.Models.Request;
using Box.V2.Test.Integration.Configuration;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Box.V2.Test.Integration
{
[TestClass]
public class BoxRetentionPolicyManagerIntegrationTest : TestInFolder
{
[TestMethod]
public async Task CreateRetentionPolicyAssignmentAsync_ForRetentionPolicyAssignmentRequest_ShouldSuccess()
{
var adminFolder = await CreateFolderAsAdmin("0");
var retentionPolicy = await CreateRetentionPolicy();
var policyAssignmentReq = new BoxRetentionPolicyAssignmentRequest()
{
PolicyId = retentionPolicy.Id,
AssignTo = new BoxRequestEntity()
{
Id = adminFolder.Id,
Type = BoxType.folder
}
};
var policyAssignment = await AdminClient.RetentionPoliciesManager.CreateRetentionPolicyAssignmentAsync(policyAssignmentReq);
Assert.AreEqual(retentionPolicy.Id, policyAssignment.RetentionPolicy.Id);
Assert.AreEqual(adminFolder.Id, policyAssignment.AssignedTo.Id);

var result = await AdminClient.RetentionPoliciesManager.DeleteRetentionPolicyAssignmentAsync(policyAssignment.Id);
Assert.IsTrue(result);
}
}
}
@@ -1,3 +1,4 @@
using System;
using System.Threading.Tasks;
using Box.V2.Models;
using Box.V2.Models.Request;
Expand Down Expand Up @@ -26,23 +27,49 @@ public async Task<string> Execute(IBoxClient client)
PolicyType = "finite",
RetentionLength = 1,
DispositionAction = DispositionAction.permanently_delete.ToString(),
RetentionType = BoxRetentionType.modifiable
};
try
{
var response = await client.RetentionPoliciesManager.CreateRetentionPolicyAsync(retentionPolicyRequest);
Policy = response;
}
catch (Exception ex)
{
// TODO: 12-09-2022, @mcong
// There is an error on backend side, which will return 409 status code "conflict"
// but retention policy still created.
// Delete this try-catch after the issue is fixed.
var policies = await client.RetentionPoliciesManager.GetRetentionPoliciesAsync(_policyName);
if (policies.Entries.Count == 1)
{
// Retention policy already created.
var policy = policies.Entries[0];
var response = await client.RetentionPoliciesManager.GetRetentionPolicyAsync(policy.Id);
Policy = response;
}
else
{
throw ex;
}

var response = await client.RetentionPoliciesManager.CreateRetentionPolicyAsync(retentionPolicyRequest);
Policy = response;
}
PolicyId = Policy.Id;

var assignmentRequest = new BoxRetentionPolicyAssignmentRequest()
if (_folderId != null)
{
PolicyId = PolicyId,
AssignTo = new BoxRequestEntity()
var assignmentRequest = new BoxRetentionPolicyAssignmentRequest()
{
Type = BoxType.folder,
Id = _folderId
}
};
PolicyId = PolicyId,
AssignTo = new BoxRequestEntity()
{
Type = BoxType.folder,
Id = _folderId
}
};

await client.RetentionPoliciesManager.CreateRetentionPolicyAssignmentAsync(assignmentRequest);
await client.RetentionPoliciesManager.CreateRetentionPolicyAssignmentAsync(assignmentRequest);
}

return PolicyId;
}
Expand All @@ -53,8 +80,17 @@ public async Task Dispose(IBoxClient client)
{
Status = "retired"
};

await client.RetentionPoliciesManager.UpdateRetentionPolicyAsync(PolicyId, retentionPolicyRequest);
try
{
await client.RetentionPoliciesManager.UpdateRetentionPolicyAsync(PolicyId, retentionPolicyRequest);
}
catch
{
// TODO: 12-09-2022, @mcong
// There is an error on backend side, which will return 500 status code "Internal Server Error"
// but retention policy still updated.
// Delete this try-catch after the issue is fixed.
}
}
}
}
Expand Up @@ -263,7 +263,7 @@ public static MemoryStream CreateBigFileInMemoryStream()
return CreateFileInMemoryStream(50000000);
}

public static async Task<BoxRetentionPolicy> CreateRetentionPolicy(string folderId = "0", CommandScope commandScope = CommandScope.Test)
public static async Task<BoxRetentionPolicy> CreateRetentionPolicy(string folderId = null, CommandScope commandScope = CommandScope.Test)
{
var createRetentionPolicyCommand = new CreateRetentionPolicyCommand(folderId, GetUniqueName("policy"), commandScope);
await ExecuteCommand(createRetentionPolicyCommand);
Expand Down
25 changes: 23 additions & 2 deletions Box.V2.Test/BoxRetentionPoliciesManagerTest.cs
Expand Up @@ -28,6 +28,7 @@ public async Task CreateRetentionPolicy_OptionalParams_Success()
var policyType = "finite";
var policyAction = "permanently_delete";
var notifiedUserID = "12345";
var retentionType = BoxRetentionType.non_modifiable;
var responseString = "{"
+ "\"type\": \"retention_policy\","
+ "\"id\": \"123456789\","
Expand All @@ -51,7 +52,8 @@ public async Task CreateRetentionPolicy_OptionalParams_Success()
+ " \"type\": \"user\","
+ " \"id\": \"" + notifiedUserID + "\""
+ " }"
+ "]"
+ "],"
+ "\"retention_type\": \"non-modifiable\""
+ "}";
Handler.Setup(h => h.ExecuteAsync<BoxRetentionPolicy>(It.IsAny<IBoxRequest>()))
.Returns(Task.FromResult<IBoxResponse<BoxRetentionPolicy>>(new BoxResponse<BoxRetentionPolicy>()
Expand All @@ -64,7 +66,7 @@ public async Task CreateRetentionPolicy_OptionalParams_Success()
var requestParams = new BoxRetentionPolicyRequest
{
AreOwnersNotified = true,
CanOwnerExtendRetention = true
CanOwnerExtendRetention = true,
};
var notifiedUser = new BoxRequestEntity
{
Expand All @@ -76,13 +78,15 @@ public async Task CreateRetentionPolicy_OptionalParams_Success()
requestParams.PolicyType = policyType;
requestParams.RetentionLength = retentionLength;
requestParams.DispositionAction = policyAction;
requestParams.RetentionType = retentionType;
BoxRetentionPolicy results = await _retentionPoliciesManager.CreateRetentionPolicyAsync(requestParams);

/*** Assert ***/
Assert.AreEqual(policyAction, results.DispositionAction);
Assert.AreEqual(policyName, results.PolicyName);
Assert.AreEqual(policyType, results.PolicyType);
Assert.AreEqual(retentionLength.ToString(), results.RetentionLength);
Assert.AreEqual(retentionType, results.RetentionType);
Assert.AreEqual(true, results.CanOwnerExtendRetention);
Assert.AreEqual(true, results.AreOwnersNotified);
Assert.IsNotNull(results.CustomNotificationRecipients);
Expand Down Expand Up @@ -165,6 +169,23 @@ public async Task AssignPolicyToMetadataTemplate_OptionalParams_Success()
Assert.AreEqual(42.ToString(), result.FilterFields[1].Value);
}

[TestMethod]
public async Task DeleteRetentionPolicyAssignment_ValidRequest_Success()
{
/*** Arrange ***/
var responseString = "";
Handler.Setup(h => h.ExecuteAsync<BoxRetentionPolicyAssignment>(It.IsAny<IBoxRequest>()))
.Returns(Task.FromResult<IBoxResponse<BoxRetentionPolicyAssignment>>(new BoxResponse<BoxRetentionPolicyAssignment>()
{
Status = ResponseStatus.Success,
ContentString = responseString
}));
bool result = await _retentionPoliciesManager.DeleteRetentionPolicyAssignmentAsync("12345");

/*** Assert ***/
Assert.IsTrue(result);
}

[TestMethod]
public async Task GetFileVersionRetentions_OptionalParams_Success()
{
Expand Down
15 changes: 15 additions & 0 deletions Box.V2/Managers/BoxRetentionPoliciesManager.cs
Expand Up @@ -172,6 +172,21 @@ public async Task<BoxRetentionPolicyAssignment> GetRetentionPolicyAssignmentAsyn
return response.ResponseObject;
}

/// <summary>
/// Used to delete a retention policy assignment.
/// </summary>
/// <param name="retentionPolicyAssignmentId">ID of the retention policy assignment.</param>
/// <returns>True if the retention policy assignment was successfully deleted.</returns>
public async Task<bool> DeleteRetentionPolicyAssignmentAsync(string retentionPolicyAssignmentId)
{
BoxRequest request = new BoxRequest(_config.RetentionPolicyAssignmentsUri, retentionPolicyAssignmentId)
.Method(RequestMethod.Delete);

IBoxResponse<BoxRetentionPolicyAssignment> response = await ToResponseAsync<BoxRetentionPolicyAssignment>(request).ConfigureAwait(false);

return response.Status == ResponseStatus.Success;
}

/// <summary>
/// Retrieves all file version retentions for the given enterprise.
/// </summary>
Expand Down
7 changes: 7 additions & 0 deletions Box.V2/Managers/IBoxRetentionPoliciesManager.cs
Expand Up @@ -78,6 +78,13 @@ public interface IBoxRetentionPoliciesManager
/// <returns>The specified retention policy assignment will be returned upon success.</returns>
Task<BoxRetentionPolicyAssignment> GetRetentionPolicyAssignmentAsync(string retentionPolicyAssignmentId, IEnumerable<string> fields = null);

/// <summary>
/// Used to delete a retention policy assignment.
/// </summary>
/// <param name="retentionPolicyAssignmentId">ID of the retention policy assignment.</param>
/// <returns>True if the retention policy assignment was successfully deleted.</returns>
Task<bool> DeleteRetentionPolicyAssignmentAsync(string retentionPolicyAssignmentId);

/// <summary>
/// Retrieves all file version retentions for the given enterprise.
/// </summary>
Expand Down
17 changes: 17 additions & 0 deletions Box.V2/Models/BoxRetentionPolicy.cs
@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace Box.V2.Models
{
Expand All @@ -20,6 +22,7 @@ public class BoxRetentionPolicy : BoxEntity
public const string FieldCanOwnerExtendRetention = "can_owner_extend_retention";
public const string FieldAreOwnersNotified = "are_owners_notified";
public const string FieldCustomNotificationRecipients = "custom_notification_recipients";
public const string FieldRetentionType = "retention_type";

/// <summary>
/// The name given to the retention policy
Expand Down Expand Up @@ -87,5 +90,19 @@ public class BoxRetentionPolicy : BoxEntity
/// </summary>
[JsonProperty(PropertyName = FieldCustomNotificationRecipients)]
public virtual List<BoxUser> CustomNotificationRecipients { get; set; }

/// <summary>
/// The type of retention policy. Value is one of modifiable or non-modifiable.
/// </summary>
[JsonProperty(PropertyName = FieldRetentionType)]
[JsonConverter(typeof(StringEnumConverter))]
public virtual BoxRetentionType RetentionType { get; set; }
}

public enum BoxRetentionType
{
modifiable,
[EnumMember(Value = "non-modifiable")]
non_modifiable
}
}
9 changes: 9 additions & 0 deletions Box.V2/Models/Request/BoxRetentionPolicyRequest.cs
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace Box.V2.Models.Request
{
Expand Down Expand Up @@ -55,5 +56,13 @@ public class BoxRetentionPolicyRequest
/// </summary>
[JsonProperty(PropertyName = "custom_notification_recipients")]
public List<BoxRequestEntity> CustomNotificationRecipients { get; set; }

/// <summary>
/// Used to determine the type of retention policy, value can be modifiable or non-modifiable
/// When updating a retention policy, you can use non-modifiable type only. You can convert a modifiable policy to non-modifiable, but not the other way around.
/// </summary>
[JsonProperty(PropertyName = "retention_type")]
[JsonConverter(typeof(StringEnumConverter))]
public BoxRetentionType RetentionType { get; set; }
}
}

0 comments on commit 564904f

Please sign in to comment.