-
Notifications
You must be signed in to change notification settings - Fork 45
Add data classification endpoint support #137
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: mainline
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| # pylint: disable=C0111,R0902,R0904,R0912,R0913,R0915,E1101 | ||
| # Smartsheet Python SDK. | ||
| # | ||
| # Copyright 2018 Smartsheet.com, Inc. | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"): you may | ||
| # not use this file except in compliance with the License. You may obtain | ||
| # a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
| # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
| # License for the specific language governing permissions and limitations | ||
| # under the License. | ||
|
|
||
| from __future__ import absolute_import | ||
|
|
||
| from ..types import EnumeratedValue, json | ||
| from ..util import deserialize, serialize | ||
| from .enums import DataClassificationType | ||
|
|
||
|
|
||
| class DataClassification: | ||
|
|
||
| """Smartsheet DataClassification data model.""" | ||
|
|
||
| def __init__(self, props=None, base_obj=None): | ||
| """Initialize the DataClassification model.""" | ||
| self._base = None | ||
| if base_obj is not None: | ||
| self._base = base_obj | ||
|
|
||
| self._data_classification = EnumeratedValue(DataClassificationType) | ||
|
|
||
| if props: | ||
| deserialize(self, props) | ||
|
|
||
| self.request_response = None | ||
|
|
||
| @property | ||
| def data_classification(self): | ||
| return self._data_classification | ||
|
|
||
| @data_classification.setter | ||
| def data_classification(self, value): | ||
| self._data_classification.set(value) | ||
|
|
||
| def to_dict(self): | ||
| return serialize(self) | ||
|
|
||
| def to_json(self): | ||
| return json.dumps(self.to_dict()) | ||
|
|
||
| def __str__(self): | ||
| return self.to_json() | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| # pylint: disable=C0111,R0902,R0904,R0912,R0913,R0915,E1101 | ||
| # Smartsheet Python SDK. | ||
| # | ||
| # Copyright 2018 Smartsheet.com, Inc. | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"): you may | ||
| # not use this file except in compliance with the License. You may obtain | ||
| # a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
| # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
| # License for the specific language governing permissions and limitations | ||
| # under the License. | ||
| from enum import Enum | ||
|
|
||
|
|
||
| class DataClassificationType(Enum): | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This enum should inherit from str as well. Look at SeatType for example. |
||
| PUBLIC = 'PUBLIC' | ||
| INTERNAL = 'INTERNAL' | ||
| CONFIDENTIAL = 'CONFIDENTIAL' | ||
| SECRET = 'SECRET' | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -282,7 +282,7 @@ def delete_column(self, sheet_id, column_id) -> Union[Result[None], Error]: | |
| return response | ||
|
|
||
| def delete_rows(self, sheet_id, ids, ignore_rows_not_found=False) -> Union[Result[List[NumberObjectValue]], Error]: | ||
| """Deletes one or more Row(s) from the specified Sheeet. | ||
| """Deletes one or more Row(s) from the specified Sheet. | ||
|
|
||
| Args: | ||
| sheet_id (int): Sheet ID | ||
|
|
@@ -334,6 +334,47 @@ def delete_share(self, sheet_id, share_id) -> Union[Result[None], Error]: | |
|
|
||
| return response | ||
|
|
||
| def set_data_classification(self, sheet_id, data_classification_obj) -> Union[Result[None], Error]: | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function (and the one below) needs type definitions for |
||
| """Sets the data classification on a Sheet. | ||
|
|
||
| Args: | ||
| sheet_id (int): Sheet ID | ||
| data_classification_obj | ||
| (DataClassification): DataClassification object. | ||
|
|
||
| Returns: | ||
| Union[Result[None], Error]: The result of the operation, or an Error object if the request fails. | ||
| """ | ||
| _op = fresh_operation("set_data_classification") | ||
| _op["method"] = "PUT" | ||
| _op["path"] = "/sheets/" + str(sheet_id) + "/dataclassification" | ||
| _op["json"] = data_classification_obj | ||
|
|
||
| expected = ["Result", None] | ||
| prepped_request = self._base.prepare_request(_op) | ||
| response = self._base.request(prepped_request, expected, _op) | ||
|
|
||
| return response | ||
|
|
||
| def delete_data_classification(self, sheet_id) -> Union[Result[None], Error]: | ||
| """Removes the data classification from a Sheet. Requires ADMIN or OWNER access. | ||
|
|
||
| Args: | ||
| sheet_id (int): Sheet ID | ||
|
|
||
| Returns: | ||
| Union[Result[None], Error]: The result of the operation, or an Error object if the request fails. | ||
| """ | ||
| _op = fresh_operation("delete_data_classification") | ||
| _op["method"] = "DELETE" | ||
| _op["path"] = "/sheets/" + str(sheet_id) + "/dataclassification" | ||
|
|
||
| expected = ["Result", None] | ||
| prepped_request = self._base.prepare_request(_op) | ||
| response = self._base.request(prepped_request, expected, _op) | ||
|
|
||
| return response | ||
|
|
||
| def delete_sheet(self, sheet_id) -> Union[Result[None], Error]: | ||
| """Delete the specified Sheet. | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| TEST_SHEET_ID = 1234567890123456 | ||
| TEST_SUCCESS_MESSAGE = "SUCCESS" | ||
| TEST_RESULT_CODE = 0 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,64 @@ | ||
| import uuid | ||
| from urllib.parse import urlparse | ||
|
|
||
| from smartsheet.models import Error | ||
| from tests.mock_api.sheets.common_test_constants import TEST_SHEET_ID, TEST_SUCCESS_MESSAGE, TEST_RESULT_CODE | ||
| from tests.mock_api.mock_api_test_helper import ( | ||
| get_mock_api_client, | ||
| get_wiremock_request, | ||
| ) | ||
|
|
||
|
|
||
| def test_delete_data_classification_generated_url_is_correct(): | ||
| request_id = uuid.uuid4().hex | ||
| client = get_mock_api_client( | ||
| "/sheets/delete-data-classification/all-response-body-properties", request_id | ||
| ) | ||
|
|
||
| client.Sheets.delete_data_classification( | ||
| sheet_id=TEST_SHEET_ID, | ||
| ) | ||
|
|
||
| wiremock_request = get_wiremock_request(request_id) | ||
| url = urlparse(wiremock_request["absoluteUrl"]) | ||
| assert url.path == f'/2.0/sheets/{TEST_SHEET_ID}/dataclassification' | ||
|
|
||
|
|
||
| def test_delete_data_classification_all_response_properties(): | ||
| request_id = uuid.uuid4().hex | ||
| client = get_mock_api_client( | ||
| "/sheets/delete-data-classification/all-response-body-properties", request_id | ||
| ) | ||
|
|
||
| response = client.Sheets.delete_data_classification( | ||
| sheet_id=TEST_SHEET_ID, | ||
| ) | ||
|
|
||
| assert response.message == TEST_SUCCESS_MESSAGE | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should assert the response as a whole dict instead of prop by prop. This should be adjusted in all tests. |
||
| assert response.result_code == TEST_RESULT_CODE | ||
|
|
||
|
|
||
| def test_delete_data_classification_error_4xx(): | ||
| request_id = uuid.uuid4().hex | ||
| client = get_mock_api_client( | ||
| "/errors/400-response", request_id | ||
| ) | ||
|
|
||
| response = client.Sheets.delete_data_classification( | ||
| sheet_id=TEST_SHEET_ID, | ||
| ) | ||
|
|
||
| assert isinstance(response, Error) | ||
|
|
||
|
|
||
| def test_delete_data_classification_error_5xx(): | ||
| request_id = uuid.uuid4().hex | ||
| client = get_mock_api_client( | ||
| "/errors/500-response", request_id | ||
| ) | ||
|
|
||
| response = client.Sheets.delete_data_classification( | ||
| sheet_id=TEST_SHEET_ID, | ||
| ) | ||
|
|
||
| assert isinstance(response, Error) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| import json | ||
| import uuid | ||
| from urllib.parse import urlparse | ||
|
|
||
| from smartsheet.models import Error | ||
| from smartsheet.models.data_classification import DataClassification | ||
| from tests.mock_api.sheets.common_test_constants import TEST_SHEET_ID, TEST_SUCCESS_MESSAGE, TEST_RESULT_CODE | ||
| from tests.mock_api.mock_api_test_helper import ( | ||
| get_mock_api_client, | ||
| get_wiremock_request, | ||
| ) | ||
|
|
||
|
|
||
| def test_set_data_classification_generated_url_is_correct(): | ||
| request_id = uuid.uuid4().hex | ||
| client = get_mock_api_client( | ||
| "/sheets/set-data-classification/all-response-body-properties", request_id | ||
| ) | ||
|
|
||
| data_classification_obj = DataClassification({"dataClassification": "CONFIDENTIAL"}) | ||
|
|
||
| client.Sheets.set_data_classification( | ||
| sheet_id=TEST_SHEET_ID, | ||
| data_classification_obj=data_classification_obj, | ||
| ) | ||
|
|
||
| wiremock_request = get_wiremock_request(request_id) | ||
| url = urlparse(wiremock_request["absoluteUrl"]) | ||
| assert url.path == f'/2.0/sheets/{TEST_SHEET_ID}/dataclassification' | ||
|
|
||
|
|
||
| def test_set_data_classification_all_response_properties(): | ||
| request_id = uuid.uuid4().hex | ||
| client = get_mock_api_client( | ||
| "/sheets/set-data-classification/all-response-body-properties", request_id | ||
| ) | ||
|
|
||
| data_classification_obj = DataClassification({"dataClassification": "CONFIDENTIAL"}) | ||
|
|
||
| response = client.Sheets.set_data_classification( | ||
| sheet_id=TEST_SHEET_ID, | ||
| data_classification_obj=data_classification_obj, | ||
| ) | ||
|
|
||
| assert response.message == TEST_SUCCESS_MESSAGE | ||
| assert response.result_code == TEST_RESULT_CODE | ||
|
|
||
| wiremock_request = get_wiremock_request(request_id) | ||
| body = json.loads(wiremock_request["body"]) | ||
| assert body == {"dataClassification": "CONFIDENTIAL"} | ||
|
|
||
|
|
||
| def test_set_data_classification_error_4xx(): | ||
| request_id = uuid.uuid4().hex | ||
| client = get_mock_api_client( | ||
| "/errors/400-response", request_id | ||
| ) | ||
|
|
||
| data_classification_obj = DataClassification({"dataClassification": "CONFIDENTIAL"}) | ||
|
|
||
| response = client.Sheets.set_data_classification( | ||
| sheet_id=TEST_SHEET_ID, | ||
| data_classification_obj=data_classification_obj, | ||
| ) | ||
|
|
||
| assert isinstance(response, Error) | ||
|
|
||
|
|
||
| def test_set_data_classification_error_5xx(): | ||
| request_id = uuid.uuid4().hex | ||
| client = get_mock_api_client( | ||
| "/errors/500-response", request_id | ||
| ) | ||
|
|
||
| data_classification_obj = DataClassification({"dataClassification": "CONFIDENTIAL"}) | ||
|
|
||
| response = client.Sheets.set_data_classification( | ||
| sheet_id=TEST_SHEET_ID, | ||
| data_classification_obj=data_classification_obj, | ||
| ) | ||
|
|
||
| assert isinstance(response, Error) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a result of the comment above this should return .value (the same change should be applied below in the sheet model.