diff --git a/cnxauthoring/tests/test_utils.py b/cnxauthoring/tests/test_utils.py index 36ab7ae..40ebf78 100644 --- a/cnxauthoring/tests/test_utils.py +++ b/cnxauthoring/tests/test_utils.py @@ -534,6 +534,78 @@ def test_declare_roles_w_invalid_role_type(self, mock_notify, mock_request): self.assertEqual(sorted(data, key=lambda v: (v['uid'], v['role'],)), expected) + @httpretty.activate + @mock.patch('cnxauthoring.utils.get_current_request') + @mock.patch('cnxauthoring.utils.notify_role_for_acceptance') + def test_declare_roles_on_revision(self, mock_notify, mock_request): + from ..models import create_content + + id = '916849b5-d71f-40e3-aaf8-7da2aa82508e' + document = create_content( + id=id, + title='My Document', + authors=[{'id': 'smoo'}, {'id': 'fred'}], + ) + publishing_url = 'http://publishing/' + settings = { + 'publishing.url': publishing_url, + 'publishing.api_key': 'trusted-publisher', + } + + url = urlparse.urljoin(publishing_url, + '/contents/{}/roles'.format(document.id)) + # get_responses = [ + # httpretty.Response( + # body=json.dumps([ + # {'uid': 'smoo', 'role': 'Author', 'has_accepted': True}, + # {'uid': 'fred', 'role': 'Author', 'has_accepted': True}, + # ], status=200), + get_response = [ + {'uid': 'smoo', 'role': 'Author', + 'has_accepted': True, 'uuid': id}, + {'uid': 'fred', 'role': 'Author', + 'has_accepted': True, 'uuid': id}, + ] + httpretty.register_uri(httpretty.GET, url, + body=json.dumps(get_response), status=200) + httpretty.register_uri(httpretty.POST, url, status=202) + + mock_request().authenticated_userid = 'smoo' + now = datetime.datetime.now() + formatted_now = now.isoformat() + with mock.patch('datetime.datetime') as mock_datetime: + mock_datetime.now.return_value = now + with testing.testConfig(settings=settings): + utils.declare_roles(document) + + # Check the roles for acceptance. + expected = [ + {'assignment_date': formatted_now, + 'has_accepted': True, + u'id': u'smoo', + 'requester': 'smoo'}, + {'assignment_date': formatted_now, + 'has_accepted': True, + u'id': u'fred', + 'requester': 'smoo'}] + self.assertTrue(document.metadata['authors'], expected) + + # Now change the has_accepted on one role to verify the syncing + # only happens during role addtion. + document.metadata['authors'][1]['has_accepted'] = False + document.metadata['authors'].append({'id': 'ren'}) + with mock.patch('datetime.datetime') as mock_datetime: + mock_datetime.now.return_value = now + with testing.testConfig(settings=settings): + utils.declare_roles(document) + expected[1]['has_accepted'] = False + expected.append( + {'assignment_date': formatted_now, + 'has_accepted': None, + 'id': 'ren', + 'requester': 'smoo'}) + self.assertEqual(document.metadata['authors'], expected) + @httpretty.activate def test_declare_licensors(self): from ..models import create_content, DEFAULT_LICENSE diff --git a/cnxauthoring/utils.py b/cnxauthoring/utils.py index 4c0adce..c29eba9 100644 --- a/cnxauthoring/utils.py +++ b/cnxauthoring/utils.py @@ -443,6 +443,23 @@ def declare_roles(model): url = urlparse.urljoin(publishing_url, '/contents/{}/roles'.format(model.id)) + # Sync with the current set of attributed roles. + response = requests.get(url, headers=headers) + upstream_role_entities = [] + if response.status_code == 200: + upstream_role_entities = response.json() + elif response.status_code >= 400 and response.status_code != 404: + raise PublishingError(response) + + for role_entity in upstream_role_entities: + user_id = role_entity['uid'] + has_accepted = role_entity['has_accepted'] + role_attr = PUBLISHING_ROLES_MAPPING[role_entity['role']] + for role in model.metadata.get(role_attr, []): + if role['id'] == user_id and 'has_accepted' not in role: + role['has_accepted'] = has_accepted + break + # Send roles to publishing. _roles_mapping = {v: k for k, v in PUBLISHING_ROLES_MAPPING.items()} role_submission_keys = ('uid', 'role', 'has_accepted',) @@ -455,6 +472,7 @@ def declare_roles(model): has_accepted = role.get('has_accepted', None) # Assume this is a new record when the requester is missing. if role.get('requester', None) is None: + role['has_accepted'] = has_accepted role['requester'] = authenticated_userid now = datetime.datetime.now(TZINFO).isoformat() role['assignment_date'] = now