Skip to content

Commit

Permalink
Add Metadata-driven Retention Policies support (#444)
Browse files Browse the repository at this point in the history
  • Loading branch information
Matt Willer authored Apr 10, 2018
1 parent 354c01a commit 9b02386
Show file tree
Hide file tree
Showing 9 changed files with 247 additions and 3 deletions.
1 change: 1 addition & 0 deletions Box.V2.Test/Box.V2.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@
<Compile Include="BoxCollaborationsManagerTest.cs" />
<Compile Include="BoxLegalHoldPoliciesManagerTest.cs" />
<Compile Include="BoxWebLinksManagerTest.cs" />
<Compile Include="BoxRetentionPoliciesManagerTest.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="BoxRequestTest.cs" />
<Compile Include="BoxFoldersManagerTest.cs" />
Expand Down
161 changes: 161 additions & 0 deletions Box.V2.Test/BoxRetentionPoliciesManagerTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
using Box.V2.Managers;
using Box.V2.Models;
using Box.V2.Config;
using Box.V2.Auth;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using System.Threading.Tasks;
using System.Collections.Generic;
using Box.V2.Models.Request;

namespace Box.V2.Test
{
[TestClass]
public class BoxRetentionPoliciesManagerTest : BoxResourceManagerTest
{
protected BoxRetentionPoliciesManager _retentionPoliciesManager;

public BoxRetentionPoliciesManagerTest()
{
_retentionPoliciesManager = new BoxRetentionPoliciesManager(Config.Object, Service, Converter, AuthRepository);
}

[TestMethod]
public async Task CreateRetentionPolicy_OptionalParams_Success()
{
/*** Arrange ***/
string policyName = "Tax Documents";
int retentionLength = 365;
string policyType = "finite";
string policyAction = "permanently_delete";
string notifiedUserID = "12345";
string responseString = "{"
+ "\"type\": \"retention_policy\","
+ "\"id\": \"123456789\","
+ "\"policy_name\": \"" + policyName + "\","
+ "\"policy_type\": \"" + policyType + "\","
+ "\"retention_length\": " + retentionLength + ","
+ "\"disposition_action\": \"" + policyAction + "\","
+ "\"status\": \"active\","
+ "\"created_by\": {"
+ " \"type\": \"user\","
+ " \"id\": \"11993747\","
+ " \"name\": \"Sean\","
+ " \"login\": \"sean@box.com\""
+ "},"
+ "\"created_at\": \"2015-05-01T11:12:54-07:00\","
+ "\"modified_at\": null,"
+ "\"can_owner_extend_retention\": true,"
+ "\"are_owners_notified\": true,"
+ "\"custom_notification_recipients\": ["
+ " {"
+ " \"type\": \"user\","
+ " \"id\": \"" + notifiedUserID + "\""
+ " }"
+ "]"
+ "}";
Handler.Setup(h => h.ExecuteAsync<BoxRetentionPolicy>(It.IsAny<IBoxRequest>()))
.Returns(Task.FromResult<IBoxResponse<BoxRetentionPolicy>>(new BoxResponse<BoxRetentionPolicy>()
{
Status = ResponseStatus.Success,
ContentString = responseString
}));

/*** Act ***/
BoxRetentionPolicyRequest requestParams = new BoxRetentionPolicyRequest();
requestParams.AreOwnersNotified = true;
requestParams.CanOwnerExtendRetention = true;
BoxRequestEntity notifiedUser = new BoxRequestEntity();
notifiedUser.Type = BoxType.user;
notifiedUser.Id = notifiedUserID;
requestParams.CustomNotificationRecipients = new List<BoxRequestEntity>() { notifiedUser };
requestParams.PolicyName = policyName;
requestParams.PolicyType = policyType;
requestParams.RetentionLength = retentionLength;
requestParams.DispositionAction = policyAction;
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(true, results.CanOwnerExtendRetention);
Assert.AreEqual(true, results.AreOwnersNotified);
Assert.IsNotNull(results.CustomNotificationRecipients);
Assert.AreEqual(1, results.CustomNotificationRecipients.Count);
Assert.AreEqual(notifiedUserID, results.CustomNotificationRecipients[0].Id);
}

[TestMethod]
public async Task AssignPolicyToMetadataTemplate_OptionalParams_Success()
{
/*** Arrange ***/
string responseString = "{"
+ "\"type\": \"retention_policy_assignment\","
+ "\"id\": \"3233225\","
+ "\"retention_policy\": {"
+ " \"type\": \"retention_policy\","
+ " \"id\": \"32131\","
+ " \"policy_name\": \"TaxDocuments\""
+ "},"
+ "\"assigned_to\": {"
+ " \"type\": \"metadata_template\","
+ " \"id\": \"enterprise.my_template\""
+ "},"
+ "\"assigned_by\": {"
+ " \"type\": \"user\","
+ " \"id\": \"123456789\","
+ " \"name\": \"Sean\","
+ " \"login\": \"sean@box.com\""
+ "},"
+ "\"assigned_at\": \"2015-07-20T14:28:09-07:00\","
+ "\"filter_fields\": ["
+ " {"
+ " \"field\": \"foo\","
+ " \"value\": \"bar\""
+ " },"
+ " {"
+ " \"field\": \"baz\","
+ " \"value\": 42"
+ " }"
+ "]"
+ "}";

Handler.Setup(h => h.ExecuteAsync<BoxRetentionPolicyAssignment>(It.IsAny<IBoxRequest>()))
.Returns(Task.FromResult<IBoxResponse<BoxRetentionPolicyAssignment>>(new BoxResponse<BoxRetentionPolicyAssignment>()
{
Status = ResponseStatus.Success,
ContentString = responseString
}));

/*** Act ***/
BoxRetentionPolicyAssignmentRequest assignmentParams = new BoxRetentionPolicyAssignmentRequest();
assignmentParams.AssignTo = new BoxRequestEntity();
assignmentParams.AssignTo.Type = BoxType.metadata_template;
assignmentParams.AssignTo.Id = "enterprise.my_template";
assignmentParams.FilterFields = new List<object>
{
new
{
field = "foo",
value = "bar"
},
new
{
field = "baz",
value = 42
}
};
BoxRetentionPolicyAssignment result = await _retentionPoliciesManager.CreateRetentionPolicyAssignmentAsync(assignmentParams);

/*** Assert ***/
Assert.IsInstanceOfType(result.AssignedTo, typeof(BoxMetadataTemplate));
Assert.AreEqual("enterprise.my_template", result.AssignedTo.Id);
Assert.AreEqual("foo", result.FilterFields[0].Field);
Assert.AreEqual("bar", result.FilterFields[0].Value);
Assert.AreEqual("baz", result.FilterFields[1].Field);
Assert.AreEqual(42.ToString(), result.FilterFields[1].Value);
}
}
}
1 change: 1 addition & 0 deletions Box.V2/Box.V2.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
<Compile Include="Models\BoxGroupEventSource.cs" />
<Compile Include="Models\BoxGroupFileCollaborationEventSource.cs" />
<Compile Include="Models\BoxGroupFolderCollaborationEventSource.cs" />
<Compile Include="Models\BoxMetadataFieldFilter.cs" />
<Compile Include="Models\BoxRepresentation.cs" />
<Compile Include="Models\BoxRepresentationContent.cs" />
<Compile Include="Models\BoxRepresentationInfo.cs" />
Expand Down
25 changes: 25 additions & 0 deletions Box.V2/Models/BoxMetadataFieldFilter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Newtonsoft.Json;

namespace Box.V2.Models
{
/// <summary>
/// Box representation of a filter on a metadata field. Used for assigning a retention policy to a metadata template.
/// </summary>
public class BoxMetadataFieldFilter
{
public const string FieldField = "field";
public const string FieldValue = "value";

/// <summary>
/// The field key
/// </summary>
[JsonProperty(PropertyName = FieldField)]
public string Field { get; private set; }

/// <summary>
/// The value to filter against
/// </summary>
[JsonProperty(PropertyName = FieldValue)]
public string Value { get; private set; }
}
}
22 changes: 22 additions & 0 deletions Box.V2/Models/BoxRetentionPolicy.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;

namespace Box.V2.Models
{
Expand All @@ -16,6 +17,9 @@ public class BoxRetentionPolicy : BoxEntity
public const string FieldCreatedBy = "created_by";
public const string FieldCreatedAt = "created_at";
public const string FieldModifiedAt = "modified_at";
public const string FieldCanOwnerExtendRetention = "can_owner_extend_retention";
public const string FieldAreOwnersNotified = "are_owners_notified";
public const string FieldCustomNotificationRecipients = "custom_notification_recipients";

/// <summary>
/// The name given to the retention policy
Expand All @@ -33,6 +37,7 @@ public class BoxRetentionPolicy : BoxEntity
/// The length of the retention policy. This length specifies the duration in days that the retention policy will be active for after being assigned to content.
/// </summary>
[JsonProperty(PropertyName = FieldRetentionLength)]
// @TODO(mwiller) 2018-01-29: Change this to the correct type (int)
public string RetentionLength { get; set; }

/// <summary>
Expand Down Expand Up @@ -65,5 +70,22 @@ public class BoxRetentionPolicy : BoxEntity
[JsonProperty(PropertyName = FieldModifiedAt)]
public DateTime? ModifiedAt { get; set; }

/// <summary>
/// Whether owners of items under the policy can extend the retention period.
/// </summary>
[JsonProperty(PropertyName = FieldCanOwnerExtendRetention)]
public bool? CanOwnerExtendRetention { get; set; }

/// <summary>
/// Whether owners and co-owners of items under the policy are notified when the retention period is about to end.
/// </summary>
[JsonProperty(PropertyName = FieldAreOwnersNotified)]
public bool? AreOwnersNotified { get; set; }

/// <summary>
/// List of additional users who will be notified when the retention period is about to end.
/// </summary>
[JsonProperty(PropertyName = FieldCustomNotificationRecipients)]
public List<BoxUser> CustomNotificationRecipients { get; set; }
}
}
7 changes: 7 additions & 0 deletions Box.V2/Models/BoxRetentionPolicyAssignment.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;

namespace Box.V2.Models
{
Expand All @@ -12,6 +13,7 @@ public class BoxRetentionPolicyAssignment : BoxEntity
public const string FieldAssignedTo = "assigned_to";
public const string FieldAssignedBy = "assigned_by";
public const string FieldAssignedAt = "assigned_at";
public const string FieldFilterFields = "filter_fields";

/// <summary>
/// A mini retention policy object representing the retention policy that has been assigned to this content.
Expand All @@ -37,5 +39,10 @@ public class BoxRetentionPolicyAssignment : BoxEntity
[JsonProperty(PropertyName = FieldAssignedAt)]
public DateTime? AssignedAt { get; set; }

/// <summary>
/// Optional field filters for an assignment to a metadata template
/// </summary>
[JsonProperty(PropertyName = FieldFilterFields)]
public List<BoxMetadataFieldFilter> FilterFields { get; set; }
}
}
3 changes: 2 additions & 1 deletion Box.V2/Models/Request/BoxRequestEntity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,6 @@ public enum BoxType
user,
group,
web_link,
file_version
file_version,
metadata_template
}
9 changes: 8 additions & 1 deletion Box.V2/Models/Request/BoxRetentionPolicyAssignmentRequest.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Newtonsoft.Json;
using System.Collections.Generic;
using Newtonsoft.Json;

namespace Box.V2.Models.Request
{
Expand All @@ -15,5 +16,11 @@ public class BoxRetentionPolicyAssignmentRequest
/// </summary>
[JsonProperty(PropertyName = "assign_to")]
public BoxRequestEntity AssignTo { get; set; }

/// <summary>
/// An optional list of metadata field filters to use when applying the retention policy to a metadata template, e.g. {"field": "foo", "value": "bar"}
/// </summary>
[JsonProperty(PropertyName = "filter_fields")]
public List<object> FilterFields { get; set; }
}
}
21 changes: 20 additions & 1 deletion Box.V2/Models/Request/BoxRetentionPolicyRequest.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Newtonsoft.Json;
using System.Collections.Generic;
using Newtonsoft.Json;

namespace Box.V2.Models.Request
{
Expand Down Expand Up @@ -36,5 +37,23 @@ public class BoxRetentionPolicyRequest
/// </summary>
[JsonProperty(PropertyName = "status")]
public string Status { get; set; }

/// <summary>
/// Used to determine if the owner of items under the policy can extend the retention when the original period is ending.
/// </summary>
[JsonProperty(PropertyName = "can_owner_extend_retention")]
public bool CanOwnerExtendRetention { get; set; }

/// <summary>
/// Used to determine if owners and co-owners of items under the policy are notified when the retention period is ending.
/// </summary>
[JsonProperty(PropertyName = "are_owners_notified")]
public bool AreOwnersNotified { get; set; }

/// <summary>
/// List of additional users to notify when the retention period is ending.
/// </summary>
[JsonProperty(PropertyName = "custom_notification_recipients")]
public List<BoxRequestEntity> CustomNotificationRecipients { get; set; }
}
}

0 comments on commit 9b02386

Please sign in to comment.