def test_it_finds_the_group(self, pyramid_request, pyramid_config, group_service): data = self.annotation_data() data['groupid'] = 'foo-group' storage.create_annotation(pyramid_request, data, group_service) group_service.find.assert_called_once_with('foo-group')
def test_it_sets_group_for_replies( self, fetch_annotation, models, pyramid_config, pyramid_request, groupfinder_service, ): # Make the annotation's parent belong to 'test-group'. fetch_annotation.return_value.groupid = "test-group" # The request will need permission to write to 'test-group'. pyramid_config.testing_securitypolicy( "acct:[email protected]", groupids=["group:test-group"] ) data = self.annotation_data() assert data["groupid"] != "test-group" # The annotation is a reply. data["references"] = ["parent_annotation_id"] storage.create_annotation(pyramid_request, data, groupfinder_service) assert models.Annotation.call_args[1]["groupid"] == "test-group"
def test_it_validates_the_group_scope(self, pyramid_request, annotation_data, group, _validate_group_scope): storage.create_annotation(pyramid_request, annotation_data) _validate_group_scope.assert_called_once_with( group, annotation_data["target_uri"])
def test_it_does_not_crash_if_no_text_or_tags(self, pyramid_request, group_service): # Highlights have no text or tags. data = self.annotation_data() data["text"] = data["tags"] = "" storage.create_annotation(pyramid_request, data, group_service)
def test_it_adds_the_annotation_to_the_database(self, models, pyramid_request, group_service): storage.create_annotation(pyramid_request, self.annotation_data(), group_service) assert models.Annotation.return_value in pyramid_request.db.added
def test_it_inits_an_Annotation_model(self, models, pyramid_request, group_service): data = self.annotation_data() storage.create_annotation(pyramid_request, copy.deepcopy(data), group_service) del data['document'] models.Annotation.assert_called_once_with(**data)
def test_it_does_not_crash_if_target_selectors_is_empty( self, pyramid_request, group_service): # Page notes have [] for target_selectors. data = self.annotation_data() data["target_selectors"] = [] storage.create_annotation(pyramid_request, data, group_service)
def test_it_updates_the_document_metadata_from_the_annotation( self, models, pyramid_request, datetime, groupfinder_service, update_document_metadata, ): annotation_data = self.annotation_data() annotation_data["document"][ "document_meta_dicts" ] = mock.sentinel.document_meta_dicts annotation_data["document"][ "document_uri_dicts" ] = mock.sentinel.document_uri_dicts storage.create_annotation(pyramid_request, annotation_data, groupfinder_service) update_document_metadata.assert_called_once_with( pyramid_request.db, models.Annotation.return_value.target_uri, mock.sentinel.document_meta_dicts, mock.sentinel.document_uri_dicts, created=datetime.utcnow(), updated=datetime.utcnow(), )
def test_it_does_not_crash_if_no_text_or_tags(self, pyramid_request, annotation_data): # Highlights have no text or tags. annotation_data["text"] = annotation_data["tags"] = "" # ValueError: Attribute 'tags' does not accept objects of type <class 'str'> # So what should this be? None? storage.create_annotation(pyramid_request, annotation_data)
def test_it_does_not_crash_if_target_selectors_is_empty( self, pyramid_request, group_service ): # Page notes have [] for target_selectors. data = self.annotation_data() data["target_selectors"] = [] storage.create_annotation(pyramid_request, data, group_service)
def test_it_adds_the_annotation_to_the_database( self, models, pyramid_request, group_service, fake_db_session ): pyramid_request.db = fake_db_session storage.create_annotation( pyramid_request, self.annotation_data(), group_service ) assert models.Annotation.return_value in pyramid_request.db.added
def test_it_finds_the_group( self, pyramid_request, pyramid_config, groupfinder_service ): data = self.annotation_data() data["groupid"] = "foo-group" storage.create_annotation(pyramid_request, data, groupfinder_service) groupfinder_service.find.assert_called_once_with("foo-group")
def test_it_raises_when_group_scope_mismatch(self, pyramid_request, pyramid_config, group_service, scoped_open_group): group_service.find.return_value = scoped_open_group data = self.annotation_data() data['target_uri'] = 'http://www.bar.com/bing.html' with pytest.raises(ValidationError) as exc: storage.create_annotation(pyramid_request, data, group_service) assert str(exc.value).startswith('group scope: ')
def test_it_raises_if_write_permission_is_missing(self, pyramid_request, annotation_data, has_permission): has_permission.return_value = False with pytest.raises(ValidationError): storage.create_annotation(pyramid_request, annotation_data) has_permission.assert_called_once_with( Permission.Group.WRITE, context=Any.instance_of(GroupContext))
def test_it_raises_when_group_could_not_be_found(self, pyramid_request, pyramid_config, group_service): pyramid_config.testing_securitypolicy('userid', permissive=True) group_service.find.return_value = None data = self.annotation_data() data['groupid'] = 'missing-group' with pytest.raises(ValidationError) as exc: storage.create_annotation(pyramid_request, data, group_service) assert str(exc.value).startswith('group: ')
def test_it_raises_when_user_is_missing_write_permission(self, pyramid_request, pyramid_config, group_service): pyramid_config.testing_securitypolicy('userid', permissive=False) group_service.find.return_value = FakeGroup() data = self.annotation_data() data['groupid'] = 'foo-group' with pytest.raises(ValidationError) as exc: storage.create_annotation(pyramid_request, data, group_service) assert str(exc.value).startswith('group: ')
def test_it_raises_if_parent_annotation_does_not_exist( self, fetch_annotation, pyramid_request, group_service): fetch_annotation.return_value = None data = self.annotation_data() # The annotation is a reply. data["references"] = ["parent_annotation_id"] with pytest.raises(ValidationError) as exc: storage.create_annotation(pyramid_request, data, group_service) assert str(exc.value).startswith("references.0: ")
def test_it_raises_if_parent_annotation_does_not_exist( self, fetch_annotation, pyramid_request, group_service ): fetch_annotation.return_value = None data = self.annotation_data() # The annotation is a reply. data["references"] = ["parent_annotation_id"] with pytest.raises(ValidationError) as exc: storage.create_annotation(pyramid_request, data, group_service) assert str(exc.value).startswith("references.0: ")
def test_it_returns_the_annotation(self, models, pyramid_request, group_service): annotation = storage.create_annotation(pyramid_request, self.annotation_data(), group_service) assert annotation == models.Annotation.return_value
def test_it_queues_the_search_index(self, pyramid_request, annotation_data, search_index): annotation = storage.create_annotation(pyramid_request, annotation_data) search_index._queue.add_by_id.assert_called_once_with( # pylint:disable=protected-access annotation.id, tag="storage.create_annotation", schedule_in=60)
def test_it_sets_the_group_to_match_the_parent_for_replies( self, pyramid_request, annotation_data, factories, other_group): parent_annotation = factories.Annotation(group=other_group) annotation_data["references"] = [parent_annotation.id] annotation = storage.create_annotation(pyramid_request, annotation_data) assert annotation.groupid assert annotation.group == parent_annotation.group
def test_it_allows_when_unscoped_group(self, pyramid_request, pyramid_config, group_service, factories, models): group_service.find.return_value = factories.OpenGroup() data = self.annotation_data() data['target_uri'] = 'http://www.foo.com/boo/bah.html' # this should not raise result = storage.create_annotation(pyramid_request, data, group_service) assert result == models.Annotation.return_value
def test_it_queues_the_annotation_for_syncing_to_Elasticsearch( self, groupfinder_service, pyramid_request, search_index ): annotation = storage.create_annotation( pyramid_request, self.annotation_data(), groupfinder_service ) search_index._queue.add_by_id.assert_called_once_with( annotation.id, tag="storage.create_annotation", schedule_in=60 )
def test_it(self, pyramid_request, annotation_data, datetime): annotation = storage.create_annotation(pyramid_request, annotation_data) for param, value in annotation_data.items(): assert getattr(annotation, param) == value assert annotation.created == datetime.utcnow.return_value assert annotation.updated == datetime.utcnow.return_value assert sa.inspect(annotation).persistent # We saved it to the DB
def test_it_allows_when_user_has_write_permission(self, pyramid_request, pyramid_config, models, group_service): pyramid_config.testing_securitypolicy('userid', permissive=True) group_service.find.return_value = FakeGroup() data = self.annotation_data() data['groupid'] = 'foo-group' # this should not raise result = storage.create_annotation(pyramid_request, data, group_service) assert result == models.Annotation.return_value
def test_it_sets_group_for_replies( self, fetch_annotation, models, pyramid_config, pyramid_request, group_service ): # Make the annotation's parent belong to 'test-group'. fetch_annotation.return_value.groupid = "test-group" # The request will need permission to write to 'test-group'. pyramid_config.testing_securitypolicy( "acct:[email protected]", groupids=["group:test-group"] ) data = self.annotation_data() assert data["groupid"] != "test-group" # The annotation is a reply. data["references"] = ["parent_annotation_id"] storage.create_annotation(pyramid_request, data, group_service) assert models.Annotation.call_args[1]["groupid"] == "test-group"
def test_it_sets_the_annotations_document_id( self, models, pyramid_request, group_service, update_document_metadata ): annotation_data = self.annotation_data() document = mock.Mock() update_document_metadata.return_value = document ann = storage.create_annotation(pyramid_request, annotation_data, group_service) assert ann.document == document
def test_it_allows_when_target_uri_matches_single_group_scope( self, pyramid_request, pyramid_config, group_service, scoped_open_group, models ): group_service.find.return_value = scoped_open_group data = self.annotation_data() data["target_uri"] = "http://www.foo.com/boo/bah.html" # this should not raise result = storage.create_annotation(pyramid_request, data, group_service) assert result == models.Annotation.return_value
def test_it_sets_the_annotations_document_id(self, models, pyramid_request, group_service): annotation_data = self.annotation_data() document = mock.Mock() models.update_document_metadata.return_value = document ann = storage.create_annotation(pyramid_request, annotation_data, group_service) assert ann.document == document
def test_it_fetches_parent_annotation_for_replies(self, fetch_annotation, pyramid_config, pyramid_request, group_service): # Make the annotation's parent belong to 'test-group'. fetch_annotation.return_value.groupid = "test-group" # The request will need permission to write to 'test-group'. pyramid_config.testing_securitypolicy("acct:[email protected]", groupids=["group:test-group"]) data = self.annotation_data() # The annotation is a reply. data["references"] = ["parent_annotation_id"] storage.create_annotation(pyramid_request, data, group_service) fetch_annotation.assert_called_once_with(pyramid_request.db, "parent_annotation_id")
def test_it_updates_the_document_metadata_from_the_annotation( self, models, pyramid_request, datetime, group_service, update_document_metadata ): annotation_data = self.annotation_data() annotation_data["document"][ "document_meta_dicts" ] = mock.sentinel.document_meta_dicts annotation_data["document"][ "document_uri_dicts" ] = mock.sentinel.document_uri_dicts storage.create_annotation(pyramid_request, annotation_data, group_service) update_document_metadata.assert_called_once_with( pyramid_request.db, models.Annotation.return_value.target_uri, mock.sentinel.document_meta_dicts, mock.sentinel.document_uri_dicts, created=datetime.utcnow(), updated=datetime.utcnow(), )
def create(request): """Create an annotation from the POST payload.""" schema = CreateAnnotationSchema(request) appstruct = schema.validate(_json_payload(request)) group_service = request.find_service(IGroupService) annotation = storage.create_annotation(request, appstruct, group_service) _publish_annotation_event(request, annotation, "create") svc = request.find_service(name="annotation_json_presentation") annotation_resource = _annotation_resource(request, annotation) return svc.present(annotation_resource)
def create(request): """Create an annotation from the POST payload.""" schema = CreateAnnotationSchema(request) appstruct = schema.validate(_json_payload(request)) annotation = storage.create_annotation(request, appstruct) _publish_annotation_event(request, annotation, "create") return request.find_service(name="annotation_json").present_for_user( annotation=annotation, user=request.user )
def test_it_allows_when_target_uri_matches_multiple_group_scope( self, pyramid_request, pyramid_config, group_service, factories, models ): scope = factories.GroupScope(scope="http://www.foo.com") scope2 = factories.GroupScope(scope="http://www.bar.com") group_service.find.return_value = factories.OpenGroup(scopes=[scope, scope2]) data = self.annotation_data() data["target_uri"] = "http://www.bar.com/boo/bah.html" # this should not raise result = storage.create_annotation(pyramid_request, data, group_service) assert result == models.Annotation.return_value
def test_it_allows_mismatched_scope_when_feature_flag_off( self, pyramid_request, pyramid_config, group_service, scoped_open_group, models): group_service.find.return_value = scoped_open_group data = self.annotation_data() data['target_uri'] = 'http://www.baz.com/boo/bah.html' # this should not raise result = storage.create_annotation(pyramid_request, data, group_service) assert result == models.Annotation.return_value
def test_it_fetches_parent_annotation_for_replies(self, fetch_annotation, pyramid_config, pyramid_request, group_service): # Make the annotation's parent belong to 'test-group'. fetch_annotation.return_value.groupid = 'test-group' # The request will need permission to write to 'test-group'. pyramid_config.testing_securitypolicy('acct:[email protected]', groupids=['group:test-group']) data = self.annotation_data() # The annotation is a reply. data['references'] = ['parent_annotation_id'] storage.create_annotation(pyramid_request, data, group_service) fetch_annotation.assert_called_once_with(pyramid_request.db, 'parent_annotation_id')
def test_it_allows_scope_mismatch_when_enforce_scope_is_False( self, pyramid_request, pyramid_config, group_service, scoped_open_group, models ): scoped_open_group.enforce_scope = False group_service.find.return_value = scoped_open_group data = self.annotation_data() # This target URI is not within any of the group's defined scopes data["target_uri"] = "http://www.foo.com/boo/bah.html" # This will not raise because ``enforce_scope`` is set to False for the # annotation's group result = storage.create_annotation(pyramid_request, data, group_service) assert result == models.Annotation.return_value
def create(request): """Create an annotation from the POST payload.""" schema = CreateAnnotationSchema(request) appstruct = schema.validate(_json_payload(request)) group_service = request.find_service(IGroupService) annotation = storage.create_annotation(request, appstruct, group_service) _publish_annotation_event(request, annotation, 'create') links_service = request.find_service(name='links') group_service = request.find_service(IGroupService) resource = AnnotationResource(annotation, group_service, links_service) presenter = AnnotationJSONPresenter(resource) return presenter.asdict()
def test_it_does_not_crash_if_no_text_or_tags(self, pyramid_request, group_service): # Highlights have no text or tags. data = self.annotation_data() data['text'] = data['tags'] = '' storage.create_annotation(pyramid_request, data, group_service)