Skip to content

Commit e2b7a17

Browse files
authored
feat: Added support for Modifiable Retention Policies (#872)
1 parent f94d988 commit e2b7a17

File tree

9 files changed

+115
-7
lines changed

9 files changed

+115
-7
lines changed

Sources/Modules/RetentionPolicyModule.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ public class RetentionPoliciesModule {
4848
/// - canOwnerExtendRetention: The Owner of a file will be allowed to extend the retention.
4949
/// - areOwnersNotified: The Owner or Co-owner will get notified when a file is nearing expiration.
5050
/// - customNotificationRecipients: Notified users.
51+
/// - retentionType: Specifies the retention type which can be `modifiable` or `non-modifiable`.
5152
/// - completion: Returns either standard RetentionPolicy object or an error.
5253
public func create(
5354
name: String,
@@ -57,12 +58,14 @@ public class RetentionPoliciesModule {
5758
canOwnerExtendRetention: Bool? = nil,
5859
areOwnersNotified: Bool? = nil,
5960
customNotificationRecipients: [User]? = nil,
61+
retentionType: RetentionType? = nil,
6062
completion: @escaping Callback<RetentionPolicy>
6163
) {
6264

6365
var body: [String: Any] = [:]
6466
body["policy_name"] = name
6567
body["policy_type"] = type.description
68+
body["retention_type"] = retentionType?.description
6669
body["retention_length"] = length
6770
body["disposition_action"] = dispositionAction.description
6871
body["can_owner_extend_retention"] = canOwnerExtendRetention
@@ -91,19 +94,24 @@ public class RetentionPoliciesModule {
9194
/// - dispositionAction: If updating a `finite` policy, the disposition action can be `permanently_delete` or `remove_retention`.
9295
/// For indefinite policies, disposition action must be remove_retention.
9396
/// - status: Used to `retire` a retention policy if status is set to `retired`. If not retiring a policy, do not include or set to null.
97+
/// - setRetentionTypeToNonModifiable: If value is `false` retention type is not changed. If value is true retention type is changed to `non_modifiable`.
9498
/// - completion: Returns either updated retention policy object or an error.
9599
public func update(
96100
policyId id: String,
97101
name: String? = nil,
98102
dispositionAction: DispositionAction? = nil,
99103
status: RetentionPolicyStatus? = nil,
104+
setRetentionTypeToNonModifiable: Bool = false,
100105
completion: @escaping Callback<RetentionPolicy>
101106
) {
102107

103108
var body: [String: Any] = [:]
104109
body["policy_name"] = name
105110
body["disposition_action"] = dispositionAction?.description
106111
body["status"] = status?.description
112+
if setRetentionTypeToNonModifiable {
113+
body["retention_type"] = RetentionType.nonModifiable.description
114+
}
107115

108116
boxClient.put(
109117
url: URL.boxAPIEndpoint("/2.0/retention_policies/\(id)", configuration: boxClient.configuration),

Sources/Responses/RetentionPolicy.swift

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ public enum RetentionPolicyType: BoxEnum {
1717
/// Custom value not yet implemented in this SDK version.
1818
case customValue(String)
1919

20+
/// Creates a new value
21+
///
22+
/// - Parameter value: String representation of a RetentionPolicyType rawValue
2023
public init(_ value: String) {
2124
switch value {
2225
case "finite":
@@ -28,6 +31,7 @@ public enum RetentionPolicyType: BoxEnum {
2831
}
2932
}
3033

34+
/// Returns string representation of RetentionPolicyType
3135
public var description: String {
3236
switch self {
3337
case .finite:
@@ -105,6 +109,45 @@ public enum RetentionPolicyStatus: BoxEnum {
105109
}
106110
}
107111

112+
/// Specifies the retention type
113+
public enum RetentionType: BoxEnum {
114+
/// You can modify the retention policy. For example, you can add or remove folders, shorten or lengthen the policy duration, or delete the assignment.
115+
/// Use this type if your retention policy is not related to any regulatory purposes.
116+
case modifiable
117+
/// You can modify the retention policy only in a limited way: add a folder, lengthen the duration, retire the policy, change the disposition action or notification settings.
118+
/// You cannot perform other actions, such as deleting the assignment or shortening the policy duration.
119+
/// Use this type to ensure compliance with regulatory retention policies.
120+
case nonModifiable
121+
/// Custom value that was not yet implemented in current SDK version.
122+
case customValue(String)
123+
124+
/// Creates a new value
125+
///
126+
/// - Parameter value: String representation of a RetentionType rawValue
127+
public init(_ value: String) {
128+
switch value {
129+
case "modifiable":
130+
self = .modifiable
131+
case "non_modifiable":
132+
self = .nonModifiable
133+
default:
134+
self = .customValue(value)
135+
}
136+
}
137+
138+
/// Returns string representation of RetentionType
139+
public var description: String {
140+
switch self {
141+
case .modifiable:
142+
return "modifiable"
143+
case .nonModifiable:
144+
return "non_modifiable"
145+
case let .customValue(value):
146+
return value
147+
}
148+
}
149+
}
150+
108151
/// A retention policy blocks permanent deletion of content for a specified amount of time.
109152
public class RetentionPolicy: BoxModel {
110153

@@ -139,6 +182,8 @@ public class RetentionPolicy: BoxModel {
139182
public let areOwnersNotified: Bool?
140183
/// Other users notified about retention policy changes.
141184
public let customNotificationRecipients: [User]?
185+
/// Specifies the retention type which can be `modifiable` or `non-modifiable`
186+
public let retentionType: RetentionType?
142187

143188
public required init(json: [String: Any]) throws {
144189
guard let itemType = json["type"] as? String else {
@@ -164,5 +209,6 @@ public class RetentionPolicy: BoxModel {
164209
canOwnerExtendRetention = try BoxJSONDecoder.optionalDecode(json: json, forKey: "can_owner_extend_retention")
165210
areOwnersNotified = try BoxJSONDecoder.optionalDecode(json: json, forKey: "are_owners_notified")
166211
customNotificationRecipients = try BoxJSONDecoder.optionalDecodeCollection(json: json, forKey: "custom_notification_recipients")
212+
retentionType = try BoxJSONDecoder.optionalDecodeEnum(json: json, forKey: "retention_type")
167213
}
168214
}

Sources/Responses/RetentionPolicyEntry.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,6 @@ public class RetentionPolicyEntry: BoxModel {
3333
type = itemType
3434

3535
id = try BoxJSONDecoder.decode(json: json, forKey: "id")
36-
name = try BoxJSONDecoder.optionalDecode(json: json, forKey: "name")
36+
name = try BoxJSONDecoder.optionalDecode(json: json, forKey: "policy_name")
3737
}
3838
}

Tests/Modules/RetentionPolicyModuleSpecs.swift

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class RetentionPolicyModuleSpecs: QuickSpec {
5353
expect(retentionPolicy.customNotificationRecipients?.count).to(equal(2))
5454
expect(retentionPolicy.customNotificationRecipients?.first?.id).to(equal("960"))
5555
expect(retentionPolicy.createdBy?.id).to(equal("958"))
56+
expect(retentionPolicy.retentionType).to(equal(.nonModifiable))
5657
case let .failure(error):
5758
fail("Expected call to getRetentionPolicy to succeed, but instead got \(error)")
5859
}
@@ -82,7 +83,8 @@ class RetentionPolicyModuleSpecs: QuickSpec {
8283
"disposition_action": "remove_retention",
8384
"can_owner_extend_retention": false,
8485
"are_owners_notified": true,
85-
"custom_notification_recipients": [user.rawData]
86+
"custom_notification_recipients": [user.rawData],
87+
"retention_type": "modifiable"
8688
])
8789
) { _ in
8890
OHHTTPStubsResponse(
@@ -98,7 +100,8 @@ class RetentionPolicyModuleSpecs: QuickSpec {
98100
dispositionAction: .removeRetention,
99101
canOwnerExtendRetention: false,
100102
areOwnersNotified: true,
101-
customNotificationRecipients: [user]
103+
customNotificationRecipients: [user],
104+
retentionType: .modifiable
102105
) { result in
103106
switch result {
104107
case let .success(retentionPolicy):
@@ -113,6 +116,7 @@ class RetentionPolicyModuleSpecs: QuickSpec {
113116
expect(retentionPolicy.customNotificationRecipients?.count).to(equal(1))
114117
expect(retentionPolicy.customNotificationRecipients?.first?.id).to(equal("22222"))
115118
expect(retentionPolicy.createdBy?.id).to(equal("33333"))
119+
expect(retentionPolicy.retentionType).to(equal(.modifiable))
116120
case let .failure(error):
117121
fail("Expected call to create to succeed, but instead got \(error)")
118122
}
@@ -156,6 +160,38 @@ class RetentionPolicyModuleSpecs: QuickSpec {
156160
expect(retentionPolicy.dispositionAction).to(equal(.removeRetention))
157161
expect(retentionPolicy.status).to(equal(.active))
158162
expect(retentionPolicy.createdBy?.id).to(equal("22222"))
163+
expect(retentionPolicy.retentionType).to(equal(.modifiable))
164+
case let .failure(error):
165+
fail("Expected call to updateto succeed, but instead got \(error)")
166+
}
167+
done()
168+
}
169+
}
170+
}
171+
172+
it("should update retention type to non_modifiable") {
173+
let id = "123456789"
174+
stub(
175+
condition: isHost("api.box.com") &&
176+
isPath("/2.0/retention_policies/\(id)") &&
177+
isMethodPUT() &&
178+
hasJsonBody([
179+
"retention_type": "non_modifiable"
180+
])
181+
) { _ in
182+
OHHTTPStubsResponse(
183+
fileAtPath: OHPathForFile("UpdateRetentionPolicy.json", type(of: self))!,
184+
statusCode: 200, headers: ["Content-Type": "application/json"]
185+
)
186+
}
187+
waitUntil(timeout: .seconds(10)) { done in
188+
self.sut.retentionPolicy.update(
189+
policyId: id,
190+
setRetentionTypeToNonModifiable: true
191+
) { result in
192+
switch result {
193+
case let .success(retentionPolicy):
194+
expect(retentionPolicy.id).to(equal(id))
159195
case let .failure(error):
160196
fail("Expected call to updateto succeed, but instead got \(error)")
161197
}
@@ -170,6 +206,7 @@ class RetentionPolicyModuleSpecs: QuickSpec {
170206
stub(
171207
condition: isHost("api.box.com") &&
172208
isPath("/2.0/retention_policies") &&
209+
containsQueryParams(["policy_name": "name", "policy_type": "finite", "created_by_user_id": "1234"]) &&
173210
isMethodGET()
174211
) { _ in
175212
OHHTTPStubsResponse(

Tests/Responses/RetentionPolicySpecs.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,5 +54,17 @@ class RetentionPolicySpecs: QuickSpec {
5454
}
5555
}
5656
}
57+
58+
describe("RetentionType") {
59+
60+
describe("init()") {
61+
62+
it("should correctly create an enum value from it's string representation") {
63+
expect(RetentionType.modifiable).to(equal(RetentionType(RetentionType.modifiable.description)))
64+
expect(RetentionType.nonModifiable).to(equal(RetentionType(RetentionType.nonModifiable.description)))
65+
expect(RetentionType.customValue("custom value")).to(equal(RetentionType("custom value")))
66+
}
67+
}
68+
}
5769
}
5870
}

Tests/Stubs/Resources/RetentionPolicy/CreateRetentionPolicy.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,6 @@
2323
"login": "[email protected]"
2424
},
2525
"created_at": "2015-05-01T11:12:54-07:00",
26-
"modified_at": "2015-06-08T11:11:50-07:00"
26+
"modified_at": "2015-06-08T11:11:50-07:00",
27+
"retention_type": "modifiable"
2728
}

Tests/Stubs/Resources/RetentionPolicy/GetRetentionPolicies.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
{
44
"type": "retention_policy",
55
"id": "123456789",
6-
"name": "Tax Documents"
6+
"policy_name": "Tax Documents",
7+
"disposition_action": "permanently_delete",
8+
"retention_length": "365"
79
}
810
],
911
"limit": 100,

Tests/Stubs/Resources/RetentionPolicy/GetRetentionPolicy.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,6 @@
2929
"id": "958",
3030
"name": "Unit Test User File Owner 1",
3131
"login": "[email protected]"
32-
}
32+
},
33+
"retention_type": "non_modifiable"
3334
}

Tests/Stubs/Resources/RetentionPolicy/UpdateRetentionPolicy.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@
1313
"login": "[email protected]"
1414
},
1515
"created_at": "2015-05-01T11:12:54-07:00",
16-
"modified_at": "2015-06-08T11:11:50-07:00"
16+
"modified_at": "2015-06-08T11:11:50-07:00",
17+
"retention_type": "modifiable"
1718
}

0 commit comments

Comments
 (0)