Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Sources/Modules/RetentionPolicyModule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public class RetentionPoliciesModule {
/// - canOwnerExtendRetention: The Owner of a file will be allowed to extend the retention.
/// - areOwnersNotified: The Owner or Co-owner will get notified when a file is nearing expiration.
/// - customNotificationRecipients: Notified users.
/// - retentionType: Specifies the retention type which can be `modifiable` or `non-modifiable`.
/// - completion: Returns either standard RetentionPolicy object or an error.
public func create(
name: String,
Expand All @@ -57,12 +58,14 @@ public class RetentionPoliciesModule {
canOwnerExtendRetention: Bool? = nil,
areOwnersNotified: Bool? = nil,
customNotificationRecipients: [User]? = nil,
retentionType: RetentionType? = nil,
completion: @escaping Callback<RetentionPolicy>
) {

var body: [String: Any] = [:]
body["policy_name"] = name
body["policy_type"] = type.description
body["retention_type"] = retentionType?.description
body["retention_length"] = length
body["disposition_action"] = dispositionAction.description
body["can_owner_extend_retention"] = canOwnerExtendRetention
Expand Down Expand Up @@ -91,19 +94,24 @@ public class RetentionPoliciesModule {
/// - dispositionAction: If updating a `finite` policy, the disposition action can be `permanently_delete` or `remove_retention`.
/// For indefinite policies, disposition action must be remove_retention.
/// - 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.
/// - setRetentionTypeToNonModifiable: If value is `false` retention type is not changed. If value is true retention type is changed to `non_modifiable`.
/// - completion: Returns either updated retention policy object or an error.
public func update(
policyId id: String,
name: String? = nil,
dispositionAction: DispositionAction? = nil,
status: RetentionPolicyStatus? = nil,
setRetentionTypeToNonModifiable: Bool = false,
completion: @escaping Callback<RetentionPolicy>
) {

var body: [String: Any] = [:]
body["policy_name"] = name
body["disposition_action"] = dispositionAction?.description
body["status"] = status?.description
if setRetentionTypeToNonModifiable {
body["retention_type"] = RetentionType.nonModifiable.description
}

boxClient.put(
url: URL.boxAPIEndpoint("/2.0/retention_policies/\(id)", configuration: boxClient.configuration),
Expand Down
46 changes: 46 additions & 0 deletions Sources/Responses/RetentionPolicy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ public enum RetentionPolicyType: BoxEnum {
/// Custom value not yet implemented in this SDK version.
case customValue(String)

/// Creates a new value
///
/// - Parameter value: String representation of a RetentionPolicyType rawValue
public init(_ value: String) {
switch value {
case "finite":
Expand All @@ -28,6 +31,7 @@ public enum RetentionPolicyType: BoxEnum {
}
}

/// Returns string representation of RetentionPolicyType
public var description: String {
switch self {
case .finite:
Expand Down Expand Up @@ -105,6 +109,45 @@ public enum RetentionPolicyStatus: BoxEnum {
}
}

/// Specifies the retention type
public enum RetentionType: BoxEnum {
/// You can modify the retention policy. For example, you can add or remove folders, shorten or lengthen the policy duration, or delete the assignment.
/// Use this type if your retention policy is not related to any regulatory purposes.
case modifiable
/// 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.
/// You cannot perform other actions, such as deleting the assignment or shortening the policy duration.
/// Use this type to ensure compliance with regulatory retention policies.
case nonModifiable
/// Custom value that was not yet implemented in current SDK version.
case customValue(String)

/// Creates a new value
///
/// - Parameter value: String representation of a RetentionType rawValue
public init(_ value: String) {
switch value {
case "modifiable":
self = .modifiable
case "non_modifiable":
self = .nonModifiable
default:
self = .customValue(value)
}
}

/// Returns string representation of RetentionType
public var description: String {
switch self {
case .modifiable:
return "modifiable"
case .nonModifiable:
return "non_modifiable"
case let .customValue(value):
return value
}
}
}

/// A retention policy blocks permanent deletion of content for a specified amount of time.
public class RetentionPolicy: BoxModel {

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

public required init(json: [String: Any]) throws {
guard let itemType = json["type"] as? String else {
Expand All @@ -164,5 +209,6 @@ public class RetentionPolicy: BoxModel {
canOwnerExtendRetention = try BoxJSONDecoder.optionalDecode(json: json, forKey: "can_owner_extend_retention")
areOwnersNotified = try BoxJSONDecoder.optionalDecode(json: json, forKey: "are_owners_notified")
customNotificationRecipients = try BoxJSONDecoder.optionalDecodeCollection(json: json, forKey: "custom_notification_recipients")
retentionType = try BoxJSONDecoder.optionalDecodeEnum(json: json, forKey: "retention_type")
}
}
2 changes: 1 addition & 1 deletion Sources/Responses/RetentionPolicyEntry.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,6 @@ public class RetentionPolicyEntry: BoxModel {
type = itemType

id = try BoxJSONDecoder.decode(json: json, forKey: "id")
name = try BoxJSONDecoder.optionalDecode(json: json, forKey: "name")
name = try BoxJSONDecoder.optionalDecode(json: json, forKey: "policy_name")
}
}
41 changes: 39 additions & 2 deletions Tests/Modules/RetentionPolicyModuleSpecs.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class RetentionPolicyModuleSpecs: QuickSpec {
expect(retentionPolicy.customNotificationRecipients?.count).to(equal(2))
expect(retentionPolicy.customNotificationRecipients?.first?.id).to(equal("960"))
expect(retentionPolicy.createdBy?.id).to(equal("958"))
expect(retentionPolicy.retentionType).to(equal(.nonModifiable))
case let .failure(error):
fail("Expected call to getRetentionPolicy to succeed, but instead got \(error)")
}
Expand Down Expand Up @@ -82,7 +83,8 @@ class RetentionPolicyModuleSpecs: QuickSpec {
"disposition_action": "remove_retention",
"can_owner_extend_retention": false,
"are_owners_notified": true,
"custom_notification_recipients": [user.rawData]
"custom_notification_recipients": [user.rawData],
"retention_type": "modifiable"
])
) { _ in
OHHTTPStubsResponse(
Expand All @@ -98,7 +100,8 @@ class RetentionPolicyModuleSpecs: QuickSpec {
dispositionAction: .removeRetention,
canOwnerExtendRetention: false,
areOwnersNotified: true,
customNotificationRecipients: [user]
customNotificationRecipients: [user],
retentionType: .modifiable
) { result in
switch result {
case let .success(retentionPolicy):
Expand All @@ -113,6 +116,7 @@ class RetentionPolicyModuleSpecs: QuickSpec {
expect(retentionPolicy.customNotificationRecipients?.count).to(equal(1))
expect(retentionPolicy.customNotificationRecipients?.first?.id).to(equal("22222"))
expect(retentionPolicy.createdBy?.id).to(equal("33333"))
expect(retentionPolicy.retentionType).to(equal(.modifiable))
case let .failure(error):
fail("Expected call to create to succeed, but instead got \(error)")
}
Expand Down Expand Up @@ -156,6 +160,38 @@ class RetentionPolicyModuleSpecs: QuickSpec {
expect(retentionPolicy.dispositionAction).to(equal(.removeRetention))
expect(retentionPolicy.status).to(equal(.active))
expect(retentionPolicy.createdBy?.id).to(equal("22222"))
expect(retentionPolicy.retentionType).to(equal(.modifiable))
case let .failure(error):
fail("Expected call to updateto succeed, but instead got \(error)")
}
done()
}
}
}

it("should update retention type to non_modifiable") {
let id = "123456789"
stub(
condition: isHost("api.box.com") &&
isPath("/2.0/retention_policies/\(id)") &&
isMethodPUT() &&
hasJsonBody([
"retention_type": "non_modifiable"
])
) { _ in
OHHTTPStubsResponse(
fileAtPath: OHPathForFile("UpdateRetentionPolicy.json", type(of: self))!,
statusCode: 200, headers: ["Content-Type": "application/json"]
)
}
waitUntil(timeout: .seconds(10)) { done in
self.sut.retentionPolicy.update(
policyId: id,
setRetentionTypeToNonModifiable: true
) { result in
switch result {
case let .success(retentionPolicy):
expect(retentionPolicy.id).to(equal(id))
case let .failure(error):
fail("Expected call to updateto succeed, but instead got \(error)")
}
Expand All @@ -170,6 +206,7 @@ class RetentionPolicyModuleSpecs: QuickSpec {
stub(
condition: isHost("api.box.com") &&
isPath("/2.0/retention_policies") &&
containsQueryParams(["policy_name": "name", "policy_type": "finite", "created_by_user_id": "1234"]) &&
isMethodGET()
) { _ in
OHHTTPStubsResponse(
Expand Down
12 changes: 12 additions & 0 deletions Tests/Responses/RetentionPolicySpecs.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,17 @@ class RetentionPolicySpecs: QuickSpec {
}
}
}

describe("RetentionType") {

describe("init()") {

it("should correctly create an enum value from it's string representation") {
expect(RetentionType.modifiable).to(equal(RetentionType(RetentionType.modifiable.description)))
expect(RetentionType.nonModifiable).to(equal(RetentionType(RetentionType.nonModifiable.description)))
expect(RetentionType.customValue("custom value")).to(equal(RetentionType("custom value")))
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@
"login": "[email protected]"
},
"created_at": "2015-05-01T11:12:54-07:00",
"modified_at": "2015-06-08T11:11:50-07:00"
"modified_at": "2015-06-08T11:11:50-07:00",
"retention_type": "modifiable"
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
{
"type": "retention_policy",
"id": "123456789",
"name": "Tax Documents"
"policy_name": "Tax Documents",
"disposition_action": "permanently_delete",
"retention_length": "365"
}
],
"limit": 100,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,6 @@
"id": "958",
"name": "Unit Test User File Owner 1",
"login": "[email protected]"
}
},
"retention_type": "non_modifiable"
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@
"login": "[email protected]"
},
"created_at": "2015-05-01T11:12:54-07:00",
"modified_at": "2015-06-08T11:11:50-07:00"
"modified_at": "2015-06-08T11:11:50-07:00",
"retention_type": "modifiable"
}