def test_it_serializes_the_annotation( self, fetch_annotation, links_service, groupfinder_service, annotation_resource, presenters, AnnotationUserInfoFormatter, ): message = {"action": "_", "annotation_id": "_", "src_client_id": "_"} socket = FakeSocket("giraffe") session = mock.sentinel.db_session settings = {"foo": "bar"} presenters.AnnotationJSONPresenter.return_value.asdict.return_value = ( self.serialized_annotation() ) messages.handle_annotation_event(message, [socket], settings, session) annotation_resource.assert_called_once_with( fetch_annotation.return_value, groupfinder_service.return_value, links_service.return_value, ) presenters.AnnotationJSONPresenter.assert_called_once_with( annotation_resource.return_value, formatters=[AnnotationUserInfoFormatter.return_value], ) assert presenters.AnnotationJSONPresenter.return_value.asdict.called
def test_it_initializes_groupfinder_service(self, groupfinder_service): message = {"action": "_", "annotation_id": "_", "src_client_id": "_"} session = mock.sentinel.db_session socket = FakeSocket("giraffe") settings = {"h.authority": "example.org"} messages.handle_annotation_event(message, [socket], settings, session) groupfinder_service.assert_called_once_with(session, "example.org")
def test_it_initializes_groupfinder_service(self, groupfinder_service): message = {'action': '_', 'annotation_id': '_', 'src_client_id': '_'} session = mock.sentinel.db_session socket = FakeSocket('giraffe') settings = {'h.authority': 'example.org'} messages.handle_annotation_event(message, [socket], settings, session) groupfinder_service.assert_called_once_with(session, 'example.org')
def test_no_send_if_action_is_read(self, presenter_asdict): """Should return None if the message action is 'read'.""" message = {'action': 'read', 'src_client_id': '_', 'annotation_id': '_'} socket = FakeSocket('giraffe') session = mock.sentinel.db_session presenter_asdict.return_value = self.serialized_annotation() messages.handle_annotation_event(message, [socket], session) assert socket.send_json_payloads == []
def test_no_send_for_sender_socket(self, presenter_asdict): """Should return None if the socket's client_id matches the message's.""" message = {'src_client_id': 'pigeon', 'annotation_id': '_', 'action': '_'} socket = FakeSocket('pigeon') session = mock.sentinel.db_session presenter_asdict.return_value = self.serialized_annotation() messages.handle_annotation_event(message, [socket], session) assert socket.send_json_payloads == []
def test_no_send_if_filter_does_not_match(self, presenter_asdict): """Should return None if the socket filter doesn't match the message.""" message = {'action': '_', 'src_client_id': '_', 'annotation_id': '_'} socket = FakeSocket('giraffe') socket.filter.match.return_value = False session = mock.sentinel.db_session presenter_asdict.return_value = self.serialized_annotation() messages.handle_annotation_event(message, [socket], session) assert socket.send_json_payloads == []
def test_no_send_if_annotation_nipsad(self, nipsa_service, presenter_asdict): """Should return None if the annotation is from a NIPSA'd user.""" message = {'action': '_', 'src_client_id': '_', 'annotation_id': '_'} socket = FakeSocket('giraffe') session = mock.sentinel.db_session presenter_asdict.return_value = self.serialized_annotation() nipsa_service.return_value.is_flagged.return_value = True messages.handle_annotation_event(message, [socket], session) assert socket.send_json_payloads == []
def test_no_send_if_action_is_read(self, presenter_asdict): """Should return None if the message action is 'read'.""" message = {"action": "read", "src_client_id": "_", "annotation_id": "_"} socket = FakeSocket("giraffe") session = mock.sentinel.db_session settings = {"foo": "bar"} presenter_asdict.return_value = self.serialized_annotation() messages.handle_annotation_event(message, [socket], settings, session) assert socket.send_json_payloads == []
def test_no_send_for_sender_socket(self, presenter_asdict): """Should return None if the socket's client_id matches the message's.""" message = {"src_client_id": "pigeon", "annotation_id": "_", "action": "_"} socket = FakeSocket("pigeon") session = mock.sentinel.db_session settings = {"foo": "bar"} presenter_asdict.return_value = self.serialized_annotation() messages.handle_annotation_event(message, [socket], settings, session) assert socket.send_json_payloads == []
def test_sends_nipsad_annotations_to_owners(self, presenter_asdict): """NIPSA'd users should see their own annotations.""" message = {'action': '_', 'src_client_id': '_', 'annotation_id': '_'} socket = FakeSocket('giraffe') socket.authenticated_userid = 'fred' session = mock.sentinel.db_session presenter_asdict.return_value = self.serialized_annotation({'nipsa': True}) messages.handle_annotation_event(message, [socket], session) assert len(socket.send_json_payloads) == 1
def test_no_send_if_not_in_group(self, presenter_asdict): """Users shouldn't see annotations in groups they aren't members of.""" message = {'action': '_', 'src_client_id': '_', 'annotation_id': '_'} socket = FakeSocket('giraffe') socket.authenticated_userid = 'fred' session = mock.sentinel.db_session presenter_asdict.return_value = self.serialized_annotation({ 'permissions': {'read': ['group:private-group']}}) messages.handle_annotation_event(message, [socket], session) assert socket.send_json_payloads == []
def test_it_fetches_the_annotation(self, fetch_annotation, presenter_asdict): message = { 'annotation_id': 'panda', 'action': 'update', 'src_client_id': 'pigeon' } socket = FakeSocket('giraffe') presenter_asdict.return_value = self.serialized_annotation() messages.handle_annotation_event(message, socket) fetch_annotation.assert_called_once_with(socket.request.db, 'panda')
def test_no_send_if_annotation_nipsad(self, nipsa_service, presenter_asdict): """Should return None if the annotation is from a NIPSA'd user.""" message = {"action": "_", "src_client_id": "_", "annotation_id": "_"} socket = FakeSocket("giraffe") session = mock.sentinel.db_session settings = {"foo": "bar"} presenter_asdict.return_value = self.serialized_annotation() nipsa_service.return_value.is_flagged.return_value = True messages.handle_annotation_event(message, [socket], settings, session) assert socket.send_json_payloads == []
def test_no_send_if_filter_does_not_match(self, presenter_asdict): """Should return None if the socket filter doesn't match the message.""" message = {"action": "_", "src_client_id": "_", "annotation_id": "_"} socket = FakeSocket("giraffe") socket.filter.match.return_value = False session = mock.sentinel.db_session settings = {"foo": "bar"} presenter_asdict.return_value = self.serialized_annotation() messages.handle_annotation_event(message, [socket], settings, session) assert socket.send_json_payloads == []
def test_no_send_if_no_socket_filter(self, presenter_asdict): """Should return None if the socket has no filter.""" message = {'src_client_id': '_', 'annotation_id': '_', 'action': '_'} socket = FakeSocket('giraffe') socket.filter = None session = mock.sentinel.db_session settings = {'foo': 'bar'} presenter_asdict.return_value = self.serialized_annotation() messages.handle_annotation_event(message, [socket], settings, session) assert socket.send_json_payloads == []
def test_it_serializes_the_annotation(self, fetch_annotation, presenters): message = {'action': '_', 'annotation_id': '_', 'src_client_id': '_'} socket = FakeSocket('giraffe') presenters.AnnotationJSONPresenter.return_value.asdict.return_value = ( self.serialized_annotation()) messages.handle_annotation_event(message, socket) presenters.AnnotationJSONPresenter.assert_called_once_with( socket.request, fetch_annotation.return_value) assert presenters.AnnotationJSONPresenter.return_value.asdict.called
def test_no_send_if_not_in_group(self, presenter_asdict): """Users shouldn't see annotations in groups they aren't members of.""" message = {"action": "_", "src_client_id": "_", "annotation_id": "_"} socket = FakeSocket("giraffe") socket.authenticated_userid = "fred" session = mock.sentinel.db_session settings = {"foo": "bar"} presenter_asdict.return_value = self.serialized_annotation( {"permissions": {"read": ["group:private-group"]}} ) messages.handle_annotation_event(message, [socket], settings, session) assert socket.send_json_payloads == []
def test_sends_if_in_group(self, presenter_asdict): """Users should see annotations in groups they are members of.""" message = {'action': '_', 'src_client_id': '_', 'annotation_id': '_'} socket = FakeSocket('giraffe') socket.authenticated_userid = 'fred' socket.effective_principals.append('group:private-group') session = mock.sentinel.db_session settings = {'foo': 'bar'} presenter_asdict.return_value = self.serialized_annotation({ 'permissions': {'read': ['group:private-group']}}) messages.handle_annotation_event(message, [socket], settings, session) assert len(socket.send_json_payloads) == 1
def test_it_fetches_the_annotation(self, fetch_annotation, presenter_asdict): message = { "annotation_id": "panda", "action": "update", "src_client_id": "pigeon", } socket = FakeSocket("giraffe") session = mock.sentinel.db_session settings = {"foo": "bar"} presenter_asdict.return_value = self.serialized_annotation() messages.handle_annotation_event(message, [socket], settings, session) fetch_annotation.assert_called_once_with(session, "panda")
def test_sends_nipsad_annotations_to_owners(self, fetch_annotation, nipsa_service, presenter_asdict): """NIPSA'd users should see their own annotations.""" message = {'action': '_', 'src_client_id': '_', 'annotation_id': '_'} fetch_annotation.return_value.userid = 'fred' socket = FakeSocket('giraffe') socket.authenticated_userid = 'fred' session = mock.sentinel.db_session settings = {'foo': 'bar'} presenter_asdict.return_value = self.serialized_annotation() nipsa_service.return_value.is_flagged.return_value = True messages.handle_annotation_event(message, [socket], settings, session) assert len(socket.send_json_payloads) == 1
def test_it_fetches_the_annotation(self, fetch_annotation, presenter_asdict): message = { 'annotation_id': 'panda', 'action': 'update', 'src_client_id': 'pigeon' } socket = FakeSocket('giraffe') session = mock.sentinel.db_session settings = {'foo': 'bar'} presenter_asdict.return_value = self.serialized_annotation() messages.handle_annotation_event(message, [socket], settings, session) fetch_annotation.assert_called_once_with(session, 'panda')
def test_sends_nipsad_annotations_to_owners( self, fetch_annotation, nipsa_service, presenter_asdict ): """NIPSA'd users should see their own annotations.""" message = {"action": "_", "src_client_id": "_", "annotation_id": "_"} fetch_annotation.return_value.userid = "fred" socket = FakeSocket("giraffe") socket.authenticated_userid = "fred" session = mock.sentinel.db_session settings = {"foo": "bar"} presenter_asdict.return_value = self.serialized_annotation() nipsa_service.return_value.is_flagged.return_value = True messages.handle_annotation_event(message, [socket], settings, session) assert len(socket.send_json_payloads) == 1
def test_notification_format_delete(self, fetch_annotation, presenter_asdict): """Check the format of the returned notification for deletes.""" message = {"annotation_id": "_", "action": "delete", "src_client_id": "pigeon"} annotation = fetch_annotation.return_value socket = FakeSocket("giraffe") session = mock.sentinel.db_session settings = {"foo": "bar"} presenter_asdict.return_value = self.serialized_annotation() messages.handle_annotation_event(message, [socket], settings, session) assert socket.send_json_payloads[0] == { "payload": [{"id": annotation.id}], "type": "annotation-notification", "options": {"action": "delete"}, }
def test_it_serializes_the_annotation(self, fetch_annotation, links_service, presenters): message = {'action': '_', 'annotation_id': '_', 'src_client_id': '_'} socket = FakeSocket('giraffe') session = mock.sentinel.db_session presenters.AnnotationJSONPresenter.return_value.asdict.return_value = ( self.serialized_annotation()) messages.handle_annotation_event(message, [socket], session) presenters.AnnotationJSONPresenter.assert_called_once_with( fetch_annotation.return_value, links_service.return_value) assert presenters.AnnotationJSONPresenter.return_value.asdict.called
def test_none_for_sender_socket(self, presenter_asdict): """Should return None if the socket's client_id matches the message's.""" message = {'src_client_id': 'pigeon', 'annotation_id': '_', 'action': '_'} socket = FakeSocket('pigeon') presenter_asdict.return_value = self.serialized_annotation() result = messages.handle_annotation_event(message, socket) assert result is None
def test_none_if_action_is_read(self, presenter_asdict): """Should return None if the message action is 'read'.""" message = {'action': 'read', 'src_client_id': '_', 'annotation_id': '_'} socket = FakeSocket('giraffe') presenter_asdict.return_value = self.serialized_annotation() result = messages.handle_annotation_event(message, socket) assert result is None
def test_sends_if_annotation_public(self, presenter_asdict): """ Everyone should see annotations which are public. When logged-out, effective principals contains only `pyramid.security.Everyone`. This test ensures that the system principal is correctly equated with the annotation principal 'group:__world__', ensuring that everyone (including logged-out users) receives all public annotations. """ message = {'action': '_', 'src_client_id': '_', 'annotation_id': '_'} socket = FakeSocket('giraffe') session = mock.sentinel.db_session presenter_asdict.return_value = self.serialized_annotation() messages.handle_annotation_event(message, [socket], session) assert len(socket.send_json_payloads) == 1
def test_none_if_filter_does_not_match(self, presenter_asdict): """Should return None if the socket filter doesn't match the message.""" message = {'action': '_', 'src_client_id': '_', 'annotation_id': '_'} socket = FakeSocket('giraffe') socket.filter.match.return_value = False presenter_asdict.return_value = self.serialized_annotation() result = messages.handle_annotation_event(message, socket) assert result is None
def test_none_if_annotation_nipsad(self, has_nipsa, presenter_asdict): """Should return None if the annotation is from a NIPSA'd user.""" message = {'action': '_', 'src_client_id': '_', 'annotation_id': '_'} socket = FakeSocket('giraffe') presenter_asdict.return_value = self.serialized_annotation() has_nipsa.return_value = True result = messages.handle_annotation_event(message, socket) assert result is None
def test_sends_nipsad_annotations_to_owners(self, presenter_asdict): """NIPSA'd users should see their own annotations.""" message = {'action': '_', 'src_client_id': '_', 'annotation_id': '_'} socket = FakeSocket('giraffe') socket.request.authenticated_userid = 'fred' presenter_asdict.return_value = self.serialized_annotation({'nipsa': True}) result = messages.handle_annotation_event(message, socket) assert result is not None
def handle_annotation_event(message=message, sockets=None, request=pyramid_request, session=session): if sockets is None: sockets = [socket] return messages.handle_annotation_event(message, sockets, request, session)
def test_none_if_no_socket_filter(self, presenter_asdict): """Should return None if the socket has no filter.""" message = {'src_client_id': '_', 'annotation_id': '_', 'action': '_'} socket = FakeSocket('giraffe') socket.filter = None presenter_asdict.return_value = self.serialized_annotation() result = messages.handle_annotation_event(message, socket) assert result is None
def test_speed(self, db_session, pyramid_request, socket, message, action, reps): sockets = list(socket for _ in range(reps)) message["action"] = action start = datetime.utcnow() handle_annotation_event( message=message, sockets=sockets, request=pyramid_request, session=db_session, ) diff = datetime.utcnow() - start assert socket.send_json.count == reps millis = diff.seconds * 1000 + diff.microseconds / 1000 print( f"{action} x {reps}: {millis} ms, {millis/reps} ms/item, {reps/millis*1000} items/sec" )
def test_none_if_action_is_read(self): """Should return None if the message action is 'read'.""" message = { 'annotation': {'permissions': {'read': ['group:__world__']}}, 'action': 'read', 'src_client_id': 'pigeon' } socket = FakeSocket('giraffe') assert messages.handle_annotation_event(message, socket) is None
def test_sends_nipsad_annotations_to_owners(self, presenter_asdict): """NIPSA'd users should see their own annotations.""" message = {'action': '_', 'src_client_id': '_', 'annotation_id': '_'} socket = FakeSocket('giraffe') socket.request.authenticated_userid = 'fred' presenter_asdict.return_value = self.serialized_annotation( {'nipsa': True}) result = messages.handle_annotation_event(message, socket) assert result is not None
def test_notification_format(self, presenter_asdict): """Check the format of the returned notification in the happy case.""" message = { "annotation_id": "panda", "action": "update", "src_client_id": "pigeon", } socket = FakeSocket("giraffe") session = mock.sentinel.db_session settings = {"foo": "bar"} presenter_asdict.return_value = self.serialized_annotation() messages.handle_annotation_event(message, [socket], settings, session) assert socket.send_json_payloads[0] == { "payload": [self.serialized_annotation()], "type": "annotation-notification", "options": {"action": "update"}, }
def test_none_for_sender_socket(self): """Should return None if the socket's client_id matches the message's.""" message = { 'annotation': {'permissions': {'read': ['group:__world__']}}, 'action': 'update', 'src_client_id': 'pigeon' } socket = FakeSocket('pigeon') assert messages.handle_annotation_event(message, socket) is None
def test_it_serializes_the_annotation(self, fetch_annotation, links_service, groupfinder_service, annotation_resource, presenters): message = {'action': '_', 'annotation_id': '_', 'src_client_id': '_'} socket = FakeSocket('giraffe') session = mock.sentinel.db_session settings = {'foo': 'bar'} presenters.AnnotationJSONPresenter.return_value.asdict.return_value = ( self.serialized_annotation()) messages.handle_annotation_event(message, [socket], settings, session) annotation_resource.assert_called_once_with( fetch_annotation.return_value, groupfinder_service.return_value, links_service.return_value) presenters.AnnotationJSONPresenter.assert_called_once_with( annotation_resource.return_value) assert presenters.AnnotationJSONPresenter.return_value.asdict.called
def test_none_if_filter_does_not_match(self): """Should return None if the socket filter doesn't match the message.""" message = { 'annotation': {'permissions': {'read': ['group:__world__']}}, 'action': 'update', 'src_client_id': 'pigeon' } socket = FakeSocket('giraffe') socket.filter.match.return_value = False assert messages.handle_annotation_event(message, socket) is None
def test_none_if_no_socket_filter(self): """Should return None if the socket has no filter.""" message = { 'annotation': {'permissions': {'read': ['group:__world__']}}, 'action': 'update', 'src_client_id': 'pigeon' } socket = FakeSocket('giraffe') socket.filter = None assert messages.handle_annotation_event(message, socket) is None
def test_notification_format(self, presenter_asdict): """Check the format of the returned notification in the happy case.""" message = { 'annotation_id': 'panda', 'action': 'update', 'src_client_id': 'pigeon' } socket = FakeSocket('giraffe') session = mock.sentinel.db_session presenter_asdict.return_value = self.serialized_annotation() messages.handle_annotation_event(message, [socket], session) assert socket.send_json_payloads[0] == { 'payload': [self.serialized_annotation()], 'type': 'annotation-notification', 'options': { 'action': 'update' }, }
def test_sends_if_in_group(self, presenter_asdict): """Users should see annotations in groups they are members of.""" message = {'action': '_', 'src_client_id': '_', 'annotation_id': '_'} socket = FakeSocket('giraffe') socket.request.effective_principals = ['fred', 'group:private-group'] presenter_asdict.return_value = self.serialized_annotation( {'permissions': { 'read': ['group:private-group'] }}) result = messages.handle_annotation_event(message, socket) assert result is not None
def test_none_if_action_is_read(self, presenter_asdict): """Should return None if the message action is 'read'.""" message = { 'action': 'read', 'src_client_id': '_', 'annotation_id': '_' } socket = FakeSocket('giraffe') presenter_asdict.return_value = self.serialized_annotation() result = messages.handle_annotation_event(message, socket) assert result is None
def test_none_for_sender_socket(self, presenter_asdict): """Should return None if the socket's client_id matches the message's.""" message = { 'src_client_id': 'pigeon', 'annotation_id': '_', 'action': '_' } socket = FakeSocket('pigeon') presenter_asdict.return_value = self.serialized_annotation() result = messages.handle_annotation_event(message, socket) assert result is None
def test_sends_nipsad_deletes_to_owners(self, fetch_annotation, nipsa_service): """NIPSA'd users should see their own deletions.""" message = { 'action': 'delete', 'src_client_id': '_', 'annotation_id': '_', 'annotation_dict': self.serialized_annotation({'user': '******'}), } fetch_annotation.return_value = None socket = FakeSocket('giraffe') socket.authenticated_userid = 'geraldine' session = mock.sentinel.db_session def is_flagged(userid): return userid == 'geraldine' nipsa_service.return_value.is_flagged.side_effect = is_flagged messages.handle_annotation_event(message, [socket], session) assert len(socket.send_json_payloads) == 1
def test_none_if_annotation_nipsad(self): """Should return None if the annotation is from a NIPSA'd user.""" message = { 'annotation': { 'user': '******', 'nipsa': True, 'permissions': {'read': ['group:__world__']} }, 'action': 'update', 'src_client_id': 'pigeon' } socket = FakeSocket('giraffe') assert messages.handle_annotation_event(message, socket) is None
def test_sends_if_in_group(self): """Users should see annotations in groups they are members of.""" message = { 'annotation': { 'user': '******', 'permissions': {'read': ['group:private-group']} }, 'action': 'update', 'src_client_id': 'pigeon' } socket = FakeSocket('giraffe') socket.request.effective_principals = ['fred', 'group:private-group'] assert messages.handle_annotation_event(message, socket) is not None
def test_notification_format(self): """Check the format of the returned notification in the happy case.""" message = { 'annotation': {'permissions': {'read': ['group:__world__']}}, 'action': 'update', 'src_client_id': 'pigeon' } socket = FakeSocket('giraffe') assert messages.handle_annotation_event(message, socket) == { 'payload': [message['annotation']], 'type': 'annotation-notification', 'options': {'action': 'update'}, }
def test_sends_nipsad_annotations_to_owners(self): """NIPSA'd users should see their own annotations.""" message = { 'annotation': { 'user': '******', 'nipsa': True, 'permissions': {'read': ['group:__world__']} }, 'action': 'update', 'src_client_id': 'pigeon' } socket = FakeSocket('giraffe') socket.request.authenticated_userid = 'fred' assert messages.handle_annotation_event(message, socket) is not None
def test_it_skips_notification_when_fetch_failed(self, fetch_annotation): """ When a create/update and a delete event happens in quick succession we could fail to load the annotation, even though the event action is update/create. This tests that in that case we silently abort and don't sent a notification to the client. """ message = { 'annotation_id': 'panda', 'action': 'update', 'src_client_id': 'pigeon' } socket = FakeSocket('giraffe') fetch_annotation.return_value = None assert messages.handle_annotation_event(message, socket) is None
def test_it_skips_notification_when_fetch_failed(self, fetch_annotation): """ When a create/update and a delete event happens in quick succession we could fail to load the annotation, even though the event action is update/create. This tests that in that case we silently abort and don't sent a notification to the client. """ message = { "annotation_id": "panda", "action": "update", "src_client_id": "pigeon", } socket = FakeSocket("giraffe") session = mock.sentinel.db_session settings = {"foo": "bar"} fetch_annotation.return_value = None result = messages.handle_annotation_event(message, [socket], settings, session) assert result is None
def test_sends_if_annotation_public(self): """ Everyone should see annotations which are public. When logged-out, effective principals contains only `pyramid.security.Everyone`. This test ensures that the system principal is correctly equated with the annotation principal 'group:__world__', ensuring that everyone (including logged-out users) receives all public annotations. """ message = { 'annotation': { 'user': '******', 'permissions': {'read': ['group:__world__']} }, 'action': 'update', 'src_client_id': 'pigeon' } socket = FakeSocket('giraffe') socket.request.effective_principals = [security.Everyone] assert messages.handle_annotation_event(message, socket) is not None