Skip to content

Commit 8b72f7e

Browse files
authored
feat: Update retention_policies and retention_policy_assignments (#803)
* feat: Update `retention_policies` and `retention_policy_assignments`
1 parent 526aa30 commit 8b72f7e

6 files changed

Lines changed: 96 additions & 10 deletions

File tree

‎boxsdk/client/client.py‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -862,7 +862,8 @@ def create_retention_policy(
862862
can_owner_extend_retention: Optional[bool] = None,
863863
are_owners_notified: Optional[bool] = None,
864864
custom_notification_recipients: Iterable['User'] = None,
865-
retention_type: Optional[str] = None
865+
retention_type: Optional[str] = None,
866+
description: Optional[str] = None,
866867
) -> 'RetentionPolicy':
867868
"""
868869
Create a retention policy for the given enterprise.
@@ -888,6 +889,8 @@ def create_retention_policy(
888889
- `non_modifiable`: You can modify the retention policy only in a limited way: add a folder,
889890
lengthen the duration, retire the policy, change the disposition action or notification settings.
890891
You cannot perform other actions, such as deleting the assignment or shortening the policy duration.
892+
:param description:
893+
The additional text description of the retention policy.
891894
:return:
892895
The newly created Retention Policy
893896
"""
@@ -910,6 +913,8 @@ def create_retention_policy(
910913
retention_attributes['custom_notification_recipients'] = user_list
911914
if retention_type is not None:
912915
retention_attributes['retention_type'] = retention_type
916+
if description is not None:
917+
retention_attributes['description'] = description
913918
box_response = self._session.post(url, data=json.dumps(retention_attributes))
914919
response = box_response.json()
915920
return self.translator.translate(

‎boxsdk/object/retention_policy.py‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,18 @@ def get_url(self, *args: Any) -> str:
2626
def assign(
2727
self,
2828
assignee: Union['Folder', 'Enterprise', 'MetadataTemplate'],
29-
fields: Iterable[str] = None
29+
fields: Iterable[str] = None,
30+
start_date_field: Optional[str] = None,
3031
) -> 'RetentionPolicyAssignment':
3132
"""Assign a retention policy to a Box item
3233
3334
:param assignee:
3435
The item to assign the retention policy on.
3536
:param fields:
3637
List of fields to request.
38+
:param start_date_field:
39+
The date the retention policy assignment begins.
40+
If the assigned_to type is metadata_template, this field can be a date field's metadata attribute key id.
3741
:returns:
3842
A :class:`RetentionPolicyAssignment` object.
3943
"""
@@ -48,6 +52,8 @@ def assign(
4852
params = {}
4953
if fields is not None:
5054
params['fields'] = ','.join(fields)
55+
if start_date_field is not None:
56+
body['start_date_field'] = start_date_field
5157
response = self._session.post(url, data=json.dumps(body), params=params).json()
5258
return self.translator.translate(
5359
session=self._session,

‎test/integration_new/object/retention_policy_assignement_itest.py‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from test.integration_new.context_managers.box_retention_policy import BoxRetentionPolicy
66
from test.integration_new.context_managers.box_test_file import BoxTestFile
77
from test.integration_new.context_managers.box_test_folder import BoxTestFolder
8+
from test.integration_new.context_managers.box_metadata_template import BoxTestMetadataTemplate
89

910

1011
RETENTION_POLICY_ASSIGNMENT_TESTS_DIRECTORY_NAME = 'retention-policy-assignment-integration-tests'
@@ -34,3 +35,18 @@ def test_delete_retention_policy_assignment(parent_folder, small_file_path):
3435

3536
with pytest.raises(BoxAPIException):
3637
retention_policy_assignment.get()
38+
39+
40+
def test_retention_policy_assignement_to_metadata_template():
41+
with BoxTestMetadataTemplate(display_name="test_template") as metadata_template:
42+
with BoxRetentionPolicy(disposition_action='permanently_delete', retention_length=1) as retention_policy:
43+
retention_policy_assignment = retention_policy.assign(metadata_template, start_date_field='upload_date')
44+
45+
assignment = retention_policy_assignment.get()
46+
assert assignment.id is not None
47+
assert assignment.start_date_field == 'upload_date'
48+
49+
retention_policy_assignment.delete()
50+
51+
with pytest.raises(BoxAPIException):
52+
retention_policy_assignment.get()
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
from test.integration_new import util
2+
from test.integration_new import CLIENT
3+
4+
5+
def test_create_metedata_template_with_fields():
6+
policy_name = 'Test Retention Policy ' + util.random_name()
7+
disposition_action = 'permanently_delete'
8+
retention_length = '1'
9+
retention_type = 'modifiable'
10+
policy_description = 'Test Retention Policy'
11+
12+
retention_policy = CLIENT.create_retention_policy(
13+
policy_name=policy_name,
14+
disposition_action=disposition_action,
15+
retention_length=retention_length,
16+
retention_type=retention_type,
17+
description=policy_description
18+
)
19+
20+
try:
21+
assert retention_policy.policy_name == policy_name
22+
assert retention_policy.disposition_action == disposition_action
23+
assert retention_policy.retention_length == retention_length
24+
assert retention_policy.retention_type == retention_type
25+
assert retention_policy.description == policy_description
26+
27+
new_policy_name = 'Test Retention Policy ' + util.random_name()
28+
new_policy_description = 'Test Retention Policy Updated'
29+
retention_policy.update_info(data={
30+
'policy_name': new_policy_name,
31+
'description': new_policy_description
32+
})
33+
34+
retention_policy = CLIENT.retention_policy(retention_id=retention_policy.object_id).get()
35+
assert retention_policy.policy_name == new_policy_name
36+
assert retention_policy.description == new_policy_description
37+
finally:
38+
retention_policy.update_info(data={
39+
'status': 'retired'
40+
})

‎test/unit/client/test_client.py‎

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -894,6 +894,7 @@ def test_create_retention_policy(mock_client, mock_box_session, mock_user_list):
894894
policy_name = 'Test Retention Policy'
895895
policy_type = 'finite'
896896
disposition_action = 'remove_retention'
897+
policy_description = 'Test Retention Policy'
897898
expected_url = f'{API.BASE_API_URL}/retention_policies'
898899
expected_data = {
899900
'policy_name': policy_name,
@@ -912,7 +913,8 @@ def test_create_retention_policy(mock_client, mock_box_session, mock_user_list):
912913
'id': mock_user_list[1].object_id,
913914
},
914915
],
915-
'retention_type': 'modifiable'
916+
'retention_type': 'modifiable',
917+
'description': policy_description,
916918
}
917919
mock_policy = {
918920
'type': 'retention_policy',
@@ -933,7 +935,8 @@ def test_create_retention_policy(mock_client, mock_box_session, mock_user_list):
933935
'id': mock_user_list[1].object_id,
934936
},
935937
],
936-
'retention_type': 'modifiable'
938+
'retention_type': 'modifiable',
939+
'description': policy_description,
937940
}
938941
mock_box_session.post.return_value.json.return_value = mock_policy
939942
policy = mock_client.create_retention_policy(
@@ -943,7 +946,8 @@ def test_create_retention_policy(mock_client, mock_box_session, mock_user_list):
943946
can_owner_extend_retention=True,
944947
are_owners_notified=False,
945948
custom_notification_recipients=mock_user_list,
946-
retention_type='modifiable'
949+
retention_type='modifiable',
950+
description=policy_description,
947951
)
948952
mock_box_session.post.assert_called_once_with(expected_url, data=json.dumps(expected_data))
949953
assert policy.object_id == mock_policy['id']
@@ -953,13 +957,15 @@ def test_create_retention_policy(mock_client, mock_box_session, mock_user_list):
953957
assert policy.can_owner_extend_retention == mock_policy['can_owner_extend_retention']
954958
assert policy.are_owners_notified == mock_policy['are_owners_notified']
955959
assert policy.retention_type == mock_policy['retention_type']
960+
assert policy.description == mock_policy['description']
956961
assert isinstance(policy, RetentionPolicy)
957962

958963

959964
def test_create_infinte_retention_policy(mock_client, mock_box_session):
960965
policy_name = 'Test Retention Policy'
961966
policy_type = 'indefinite'
962967
disposition_action = 'remove_retention'
968+
policy_description = 'Test Retention Policy'
963969
expected_url = f'{API.BASE_API_URL}/retention_policies'
964970
expected_data = {
965971
'policy_name': policy_name,
@@ -968,6 +974,7 @@ def test_create_infinte_retention_policy(mock_client, mock_box_session):
968974
'can_owner_extend_retention': False,
969975
'are_owners_notified': False,
970976
'retention_type': 'non_modifiable',
977+
'description': policy_description,
971978
}
972979
mock_policy = {
973980
'type': 'retention_policy',
@@ -978,6 +985,7 @@ def test_create_infinte_retention_policy(mock_client, mock_box_session):
978985
'can_owner_extend_retention': False,
979986
'are_owners_notified': False,
980987
'retention_type': 'non_modifiable',
988+
'description': policy_description,
981989
}
982990
mock_box_session.post.return_value.json.return_value = mock_policy
983991
policy = mock_client.create_retention_policy(
@@ -986,7 +994,8 @@ def test_create_infinte_retention_policy(mock_client, mock_box_session):
986994
retention_length=float('inf'),
987995
can_owner_extend_retention=False,
988996
are_owners_notified=False,
989-
retention_type='non_modifiable'
997+
retention_type='non_modifiable',
998+
description=policy_description,
990999
)
9911000
mock_box_session.post.assert_called_once_with(expected_url, data=json.dumps(expected_data))
9921001
assert policy.object_id == mock_policy['id']
@@ -996,6 +1005,7 @@ def test_create_infinte_retention_policy(mock_client, mock_box_session):
9961005
assert policy.can_owner_extend_retention == mock_policy['can_owner_extend_retention']
9971006
assert policy.are_owners_notified == mock_policy['are_owners_notified']
9981007
assert policy.retention_type == mock_policy['retention_type']
1008+
assert policy.description == mock_policy['description']
9991009
assert isinstance(policy, RetentionPolicy)
10001010

10011011

‎test/unit/object/test_retention_policy.py‎

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,22 @@ def test_get(test_retention_policy, mock_box_session):
1414
'policy_type': 'finite',
1515
'retention_length': '10',
1616
'disposition_action': 'permanently_delete',
17+
'description': 'Description',
1718
}
1819
retention_policy = test_retention_policy.get()
1920
mock_box_session.get.assert_called_once_with(expected_url, headers=None, params=None)
2021
assert isinstance(retention_policy, RetentionPolicy)
2122
assert retention_policy['type'] == test_retention_policy.object_type
2223
assert retention_policy['id'] == test_retention_policy.object_id
2324
assert retention_policy['policy_name'] == 'Policy Name'
25+
assert retention_policy['description'] == 'Description'
2426

2527

2628
def test_update(test_retention_policy, mock_box_session):
2729
new_policy_name = 'New Name'
2830
new_retention_type = 'modifiable'
2931
new_retention_length = 60
32+
new_description = 'New Description'
3033
expected_url = f'{API.BASE_API_URL}/retention_policies/{test_retention_policy.object_id}'
3134
mock_box_session.put.return_value.json.return_value = {
3235
'type': test_retention_policy.object_type,
@@ -35,11 +38,13 @@ def test_update(test_retention_policy, mock_box_session):
3538
'policy_type': 'finite',
3639
'retention_length': new_retention_length,
3740
'retention_type': new_retention_type,
41+
'description': new_description,
3842
}
3943
data = {
4044
'policy_name': new_policy_name,
4145
'retention_type': new_retention_type,
42-
'retention_length': new_retention_length
46+
'retention_length': new_retention_length,
47+
'description': new_description,
4348
}
4449
retention_policy = test_retention_policy.update_info(data=data)
4550
mock_box_session.put.assert_called_once_with(expected_url, data=json.dumps(data), headers=None, params=None)
@@ -49,6 +54,7 @@ def test_update(test_retention_policy, mock_box_session):
4954
assert retention_policy['policy_name'] == new_policy_name
5055
assert retention_policy['retention_type'] == new_retention_type
5156
assert retention_policy['retention_length'] == new_retention_length
57+
assert retention_policy['description'] == new_description
5258

5359

5460
def test_assign(test_retention_policy, test_folder, mock_box_session):
@@ -59,21 +65,24 @@ def test_assign(test_retention_policy, test_folder, mock_box_session):
5965
'assign_to': {
6066
'type': test_folder.object_type,
6167
'id': test_folder.object_id,
62-
}
68+
},
69+
"start_date_field": "upload_date"
6370
}
6471
mock_assignment = {
6572
'type': 'retention_policy_assignment',
6673
'id': '1234',
6774
'retention_policy': {
6875
'type': 'retention_policy',
6976
'id': policy_id,
70-
}
77+
},
78+
"start_date_field": "upload_date"
7179
}
7280
mock_box_session.post.return_value.json.return_value = mock_assignment
73-
assignment = test_retention_policy.assign(test_folder)
81+
assignment = test_retention_policy.assign(test_folder, start_date_field='upload_date')
7482
mock_box_session.post.assert_called_once_with(expected_url, data=json.dumps(expected_data), params={})
7583
assert assignment.id == mock_assignment['id']
7684
assert assignment.retention_policy['id'] == mock_assignment['retention_policy']['id']
85+
assert assignment.start_date_field == mock_assignment['start_date_field']
7786
assert isinstance(assignment, RetentionPolicyAssignment)
7887

7988

0 commit comments

Comments
 (0)